diff --git a/.env.example b/.env.example index b9bb631..b4755fd 100644 --- a/.env.example +++ b/.env.example @@ -98,7 +98,8 @@ MICROSITE_API_BASE_URL=http://localhost:3001/api # Infra: wildcard DNS *.eventbuzz.live → CloudFront; map Host header to # s3://{AWS_BUCKET}/{MICROSITE_V2_S3_PREFIX}/sites/{subdomain}/index.html # Dev fallback: open published HTML via CloudFront URL of index.html key directly. -# Seed first template: npm run seed:microsite-v2-template +# Seed bundled microsite templates: npm run seed:global-microsite-v2-templates +# Or one template: npm run seed:eventify-template / npm run seed:eventre-template # # Published-site target: s3 (default) | ec2. When ec2, rendered index.html + # config.json are uploaded via SFTP to {REMOTE_ROOT}/{subdomain}/ on the EC2 box. diff --git a/microsite-v2-templates/crest-novel/assets/css/main.css b/microsite-v2-templates/crest-novel/assets/css/main.css index 7905fe7..425e004 100644 --- a/microsite-v2-templates/crest-novel/assets/css/main.css +++ b/microsite-v2-templates/crest-novel/assets/css/main.css @@ -1609,6 +1609,98 @@ h1 { font-size: 13px; } +.schedule .schedule-theme-card { + border: none; + margin-bottom: 0; + display: block; +} + +.schedule .schedule-theme-card .d-flex, +.schedule .schedule-theme-card .schedule-theme-row { + display: flex; + flex-wrap: nowrap; + align-items: stretch; +} + +.schedule .schedule-theme-name { + margin-bottom: 0; + word-break: break-word; +} + +.schedule .schedule-session-topics { + padding: 16px 32px 20px 300px; +} + +.schedule .schedule-topic { + display: grid; + grid-template-columns: 150px 96px minmax(0, 1fr) 220px; + column-gap: 16px; + align-items: start; + padding: 10px 0; + border-bottom: 1px dashed #eee; +} + +.schedule .schedule-topic:last-child { + border-bottom: none; +} + +.schedule .schedule-topic-head { + padding-top: 0; + padding-bottom: 8px; + border-bottom: 2px solid #e5e5e5; + margin-bottom: 2px; +} + +.schedule .schedule-topic-head .schedule-topic-type, +.schedule .schedule-topic-head .schedule-topic-duration, +.schedule .schedule-topic-head .schedule-topic-title, +.schedule .schedule-topic-head .schedule-topic-role { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.04em; + color: #888; + font-style: normal; +} + +.schedule .schedule-topic-type, +.schedule .schedule-topic-duration, +.schedule .schedule-topic-title, +.schedule .schedule-topic-role { + min-width: 0; +} + +.schedule .schedule-topic-type { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + color: var(--eventup-accent-start, #015AAA); + line-height: 1.4; +} + +.schedule .schedule-topic-duration { + font-size: 13px; + font-weight: 600; + color: #555; + line-height: 1.4; + white-space: nowrap; +} + +.schedule .schedule-topic-title { + font-size: 15px; + font-weight: 500; + color: #212121; + line-height: 1.45; +} + +.schedule .schedule-topic-role { + font-size: 13px; + color: #777; + font-style: italic; + line-height: 1.4; + text-align: right; +} + .schedule .show .card-body { background: #f3f4f3; } @@ -1616,14 +1708,17 @@ h1 { .schedule .card .schedule-slot-time { background-image: linear-gradient(65deg, var(--eventup-accent-start) 0, var(--eventup-accent-end) 100%); color: #fff; - padding: 38px 28px; + padding: 32px 16px; float: none; - font-size: 18px; + font-size: 15px; font-weight: 700; + line-height: 1.35; + white-space: nowrap; -webkit-box-flex: 0; - -ms-flex: 0 0 18%; - flex: 0 0 18%; - max-width: 18%; + -ms-flex: 0 0 26%; + flex: 0 0 26%; + min-width: 230px; + max-width: 26%; display: flex; align-items: center; justify-content: center; diff --git a/microsite-v2-templates/crest-novel/assets/css/responsive.css b/microsite-v2-templates/crest-novel/assets/css/responsive.css index 092947a..f40b3ae 100644 --- a/microsite-v2-templates/crest-novel/assets/css/responsive.css +++ b/microsite-v2-templates/crest-novel/assets/css/responsive.css @@ -15,6 +15,10 @@ .schedule .card .schedule-slot-time { padding: 38px 22px; } + .schedule .schedule-topic { + grid-template-columns: 132px 88px minmax(0, 1fr) 190px; + column-gap: 12px; + } #pricing .price-block-wrapper .pricing-list { padding: 10px 35px 10px 45px; } @@ -139,8 +143,10 @@ } .schedule .card .schedule-slot-time { font-size: 14px; - padding: 29px; - max-width: 22%; + padding: 24px 12px; + min-width: 210px; + flex: 0 0 26%; + max-width: 26%; } .schedule .schedule-tab-title .nav-tabs .nav-link { width: 150px; @@ -245,6 +251,42 @@ margin-left: 0; margin-top: 4px; } + .schedule .schedule-session-topics { + padding: 16px 20px; + } + .schedule .schedule-topic { + grid-template-columns: 108px 72px minmax(0, 1fr); + column-gap: 10px; + row-gap: 4px; + } + .schedule .schedule-topic-role { + grid-column: 1 / -1; + text-align: left; + padding-top: 2px; + } + .schedule .schedule-theme-card .schedule-theme-row { + flex-wrap: nowrap; + } + .schedule .card .schedule-slot-time { + flex: 0 0 48%; + min-width: 200px; + max-width: 48%; + padding: 14px 10px; + font-size: 12px; + white-space: nowrap; + } + .schedule .card-header.schedule-card-header-static { + flex: 1 1 auto; + width: auto; + min-width: 0; + padding: 16px 14px; + } + .schedule .card-header.schedule-card-header-static h4, + .schedule .card-header.schedule-card-header-static .schedule-theme-name { + font-size: 13px; + line-height: 1.35; + word-break: break-word; + } #information-bar .info-bar-item { margin-bottom: 24px; } @@ -298,10 +340,12 @@ } .schedule .card .schedule-slot-time { display: flex; - flex: 0 0 22%; - max-width: 22%; - font-size: 12px; - padding: 20px 12px; + flex: 0 0 48%; + min-width: 190px; + max-width: 48%; + font-size: 11px; + padding: 16px 10px; + white-space: nowrap; } .schedule .card-header { padding: 30px; diff --git a/microsite-v2-templates/crest-novel/assets/js/site-config.js b/microsite-v2-templates/crest-novel/assets/js/site-config.js index dc7678c..a442be4 100644 --- a/microsite-v2-templates/crest-novel/assets/js/site-config.js +++ b/microsite-v2-templates/crest-novel/assets/js/site-config.js @@ -1244,17 +1244,120 @@ initCounterUp(section); } - function renderScheduleSession(session) { + function inferScheduleAmPm(hour, dayIndex) { + if (dayIndex === 0 && hour >= 1 && hour <= 6) return 'PM'; + if (dayIndex >= 1) { + if (hour >= 9 && hour <= 11) return 'AM'; + if (hour === 12) return 'PM'; + } + if (hour >= 1 && hour <= 6) return 'PM'; + if (hour >= 7 && hour <= 11) return 'AM'; + if (hour === 12) return 'PM'; + return 'AM'; + } + + function formatClockPart(part, dayIndex) { + var trimmed = String(part || '').trim(); + var match = trimmed.match(/^(\d{1,2})\s*:\s*(\d{2})\s*(am|pm|a\.m|p\.m)?\.?$/i); + if (!match) return trimmed; + + var hour = parseInt(match[1], 10); + var minute = parseInt(match[2], 10); + var explicit = match[3] ? match[3].replace(/\./g, '').toLowerCase() : ''; + var suffix = explicit === 'am' || explicit === 'pm' + ? explicit.toUpperCase() + : inferScheduleAmPm(hour, dayIndex); + var hour12 = suffix === 'AM' + ? (hour === 12 ? 12 : hour) + : (hour >= 1 && hour <= 6 ? hour : (hour === 12 ? 12 : (hour > 12 ? hour - 12 : hour))); + + return hour12 + ':' + String(minute).padStart(2, '0') + ' ' + suffix; + } + + function formatScheduleTimeDisplay(timeStr, dayIndex) { + var raw = String(timeStr || '').trim(); + if (!raw) return ''; + if (/\b(am|pm|a\.m|p\.m)\b/i.test(raw)) return raw; + + var separator = /\s+to\s+/i.test(raw) ? ' to ' : ' - '; + var parts = raw.split(/\s+to\s+|\s*-\s*/i).map(function (part) { + return String(part || '').trim(); + }).filter(Boolean); + if (parts.length < 2) return raw; + + return formatClockPart(parts[0], dayIndex) + separator + formatClockPart(parts[1], dayIndex); + } + + function escapeHtml(str) { + return String(str == null ? '' : str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + } + + function renderScheduleTopic(topic) { + var durationLabel = topic.duration + ? (/^\d+(\s*\+\s*\d+)?$/.test(String(topic.duration).trim()) + ? escapeHtml(topic.duration) + ' min' + : escapeHtml(topic.duration)) + : ''; + + return '
' + + '' + escapeHtml(topic.type || '') + '' + + '' + durationLabel + '' + + '' + escapeHtml(topic.title || '') + '' + + '' + escapeHtml(topic.role || '') + '' + + '
'; + } + + function scheduleSessionUsesBlock(session) { + if (!session) return false; + if (Array.isArray(session.topics)) return true; + return Boolean(session.name); + } + + function renderScheduleSessionBlock(session, dayIndex) { + var topics = Array.isArray(session.topics) ? session.topics : []; + var topicsHtml = topics.length + ? '' + + topics.map(renderScheduleTopic).join('') + : ''; + var sessionName = session.name || session.title || ''; + var sessionTime = formatScheduleTimeDisplay(session.time || '', dayIndex); + var bodyHtml = topicsHtml + ? '
' + topicsHtml + '
' + : ''; + + return '
' + + '
' + + '
' + escapeHtml(sessionTime) + '
' + + '
' + + '

' + escapeHtml(sessionName) + '

' + + '
' + + '
' + + bodyHtml + + '
'; + } + + function renderScheduleSession(session, dayIndex) { + var sessionName = session.name || session.title || ''; + var sessionTime = formatScheduleTimeDisplay(session.time || '', dayIndex); var typeHtml = session.type - ? '' + session.type + '' + ? '' + escapeHtml(session.type) + '' : ''; return '
' + '
' - + '' + (session.time || '') + '' + + '' + escapeHtml(sessionTime) + '' + '' + '
' - + '

' + (session.title || '') + '

' + + '

' + escapeHtml(sessionName) + '

' + typeHtml + '
' + '
' @@ -1305,10 +1408,15 @@ return day && day.show !== false; }); - var sessionsHtml = function (day) { + var sessionsHtml = function (day, dayIndex) { return (day.sessions || []).filter(function (session) { return session && session.show !== false; - }).map(renderScheduleSession).join(''); + }).map(function (session) { + if (scheduleSessionUsesBlock(session)) { + return renderScheduleSessionBlock(session, dayIndex); + } + return renderScheduleSession(session, dayIndex); + }).join(''); }; if (days.length === 1) { @@ -1323,7 +1431,7 @@ } contentEl.innerHTML = '
' - + '
' + sessionsHtml(days[0]) + '
' + + '
' + sessionsHtml(days[0], 0) + '
' + '
'; } else if (days.length > 1) { if (singleDateWrap) { @@ -1358,7 +1466,7 @@ pane.className = 'tab-pane fade' + (isActive ? ' show active' : ''); pane.id = tabId; pane.setAttribute('role', 'tabpanel'); - pane.innerHTML = '
' + sessionsHtml(day) + '
'; + pane.innerHTML = '
' + sessionsHtml(day, index) + '
'; contentEl.appendChild(pane); }); } else { diff --git a/microsite-v2-templates/crest-novel/template.html b/microsite-v2-templates/crest-novel/template.html index e9f2139..4ddcce5 100644 --- a/microsite-v2-templates/crest-novel/template.html +++ b/microsite-v2-templates/crest-novel/template.html @@ -16,9 +16,9 @@ - + - + + + + + + {{#if_show sections.logo}} + + + {{/if_show}} + +
+ {{#if_show sections.hero}} +
+
+
+
+
+ {{#if sections.logo.hero.url}} +
+ +
+ {{/if}} +
+
+
+

{{sections.hero.event_name}}

+ + {{#if sections.hero.cta.text}} + + {{/if}} +
+
+
+
+
+ {{/if_show}} +
+ + {{#if sections.hero.countdown.show}} +
+
+
+
+
+
+
+
+
+
+
+
+
+ {{/if}} + + {{#if_show sections.about}} +
+
+
+
+
+
+

{{sections.about.heading}}

+
{{{sections.about.content}}}
+
+ {{#if (eq sections.about.media.type "image")}}{{#if sections.about.media.image}} +
{{sections.about.heading}}
+ {{/if}}{{/if}} + {{#if (eq sections.about.media.type "video")}}{{#if sections.about.media.video}} +
+ {{/if}}{{/if}} + {{#if (eq sections.about.media.type "youtube")}}{{#if sections.about.media.youtube}} +
+ {{/if}}{{/if}} +
+
+
+
+
+ {{/if_show}} + + {{#if_show sections.video}} +
+
+
+

{{sections.video.heading}}

+
+
+
+ {{#if (eq sections.video.media.type "image")}}{{#if sections.video.media.image}} +
{{sections.video.heading}}
+ {{/if}}{{/if}} + {{#if (eq sections.video.media.type "video")}}{{#if sections.video.media.video}} +
+ {{/if}}{{/if}} + {{#if (eq sections.video.media.type "youtube")}}{{#if sections.video.media.youtube}} +
+ {{/if}}{{/if}} +
+
+
+
+ {{/if_show}} + + {{#if_show sections.informationBar}} +
+
+
+ {{#each sections.informationBar.items}} +
+
+ +
+ {{this.label}} + {{this.value}} +
+
+
+ {{/each}} +
+
+
+ {{/if_show}} + + {{#if_show sections.event_highlights}} +
+
+
+
+
+

{{sections.event_highlights.heading}}

+ {{#if sections.event_highlights.subtitle}}

{{sections.event_highlights.subtitle}}

{{/if}} +
+
+
+
+ {{#each sections.event_highlights.items}} +
+
+ +

{{this.title}}

+

{{this.description}}

+ 0{{@index}} +
+
+ {{/each}} +
+
+
+ {{/if_show}} + + {{#if_show sections.event_stats}} +
+
+
+ {{#each sections.event_stats.items}} +
+
+
+
+
{{this.value}}
+

{{this.label}}

+
+
+
+ {{/each}} +
+
+
+ {{/if_show}} + + {{#if_show sections.speakers}} +
+
+
+
+
+

{{sections.speakers.heading}}

+ {{#if sections.speakers.subtitle}}

{{sections.speakers.subtitle}}

{{/if}} +
+
+
+
+ {{#each sections.speakers.items}} +
+
+ {{#if this.image}}{{this.name}}{{/if}} +

{{this.name}}

+

{{this.role}}

+
+
+ {{/each}} +
+
+
+ {{/if_show}} + + {{#if_show sections.event_schedule}} +
+
+
+
+
+

{{sections.event_schedule.heading}}

+ {{#if sections.event_schedule.subtitle}}

{{sections.event_schedule.subtitle}}

{{/if}} +
+
+
+ {{#each sections.event_schedule.days}} +
+

{{this.label}}{{#if this.date}} — {{this.date}}{{/if}}

+
+ + + {{#each this.sessions}} + + + + + + {{/each}} + +
{{this.time}}{{this.type}}{{this.title}}
+
+
+ {{/each}} +
+
+ {{/if_show}} + + {{#if_show sections.about_crest}} +
+
+
+
+

{{sections.about_crest.heading}}

+
{{{sections.about_crest.content}}}
+ {{#if sections.about_crest.cta.text}} +

{{sections.about_crest.cta.text}}

+ {{/if}} +
+
+
+
+ {{/if_show}} + + {{#if_show sections.sponsors}} +
+
+ {{#unless sections.sponsors.hideHeading}} +
+

{{sections.sponsors.heading}}

+ {{#if sections.sponsors.subtitle}}

{{sections.sponsors.subtitle}}

{{/if}} +
+ {{/unless}} +
+ {{#each sections.sponsors.groups}} +
+ {{#unless ../sections.sponsors.hideGroupTitles}}
{{this.title}}
{{/unless}} +
+ {{#each this.items}} +
+ {{this.alt}} +
+ {{/each}} +
+
+ {{/each}} +
+
+
+ {{/if_show}} + + {{#if_show sections.contact}} +
+
+
+

{{sections.contact.heading}}

+ {{#if sections.contact.subtitle}}

{{sections.contact.subtitle}}

{{/if}} +
+
+
+ {{#if sections.contact.phones}} +
    + {{#each sections.contact.phones}} +
  • {{this.label}}: {{this.number}}
  • + {{/each}} +
+ {{/if}} + {{#if sections.contact.address}}

{{sections.contact.address}}

{{/if}} +
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+ Loading… + + +
+
+ +
+ + +
+
+
+
+
+
+
+
+ {{/if_show}} + + {{#if_show sections.map}} +
+
+ +
+
+ {{/if_show}} + + {{#if_show sections.footer}} + + {{/if_show}} + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/microsite-v2-templates/event-up_ol/template.json b/microsite-v2-templates/event-up_ol/template.json new file mode 100644 index 0000000..0d24a4a --- /dev/null +++ b/microsite-v2-templates/event-up_ol/template.json @@ -0,0 +1,420 @@ +{ + "version": 1, + "meta": { + "title": "EventUp Conference", + "eventId": "" + }, + "theme": { + "fields": [ + { "key": "accent", "type": "color", "label": "Accent color", "default": "#189A95" }, + { "key": "headingColor", "type": "color", "label": "Heading color", "default": "#015AAA" } + ] + }, + "sections": [ + { + "id": "marketing_popup", + "label": "Marketing popup", + "show": false, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Introducing" }, + { "key": "logo", "type": "image", "label": "Popup logo" }, + { + "key": "media.type", + "type": "select", + "label": "Media", + "default": "none", + "options": [ + { "value": "none", "label": "None" }, + { "value": "image", "label": "Image" }, + { "value": "video", "label": "Video (upload)" }, + { "value": "youtube", "label": "YouTube video" } + ] + }, + { + "key": "media.image", + "type": "image", + "label": "Popup image", + "showIf": { "field": "media.type", "equals": "image" } + }, + { + "key": "media.video", + "type": "video", + "label": "Popup video", + "showIf": { "field": "media.type", "equals": "video" } + }, + { + "key": "media.youtube", + "type": "url", + "label": "YouTube URL", + "placeholder": "https://www.youtube.com/watch?v=...", + "showIf": { "field": "media.type", "equals": "youtube" } + }, + { + "key": "autoCloseDuration", + "type": "text", + "label": "Auto-close after (ms)", + "default": "3000" + } + ] + }, + { + "id": "logo", + "label": "Logos", + "show": true, + "fields": [ + { "key": "header.url", "type": "image", "label": "Header logo" }, + { "key": "header.alt", "type": "text", "label": "Header logo alt", "default": "Event logo" }, + { "key": "header.maxHeight", "type": "text", "label": "Header logo max height (px)", "default": "56" }, + { "key": "hero.url", "type": "image", "label": "Hero logo" }, + { "key": "hero.alt", "type": "text", "label": "Hero logo alt", "default": "" }, + { "key": "footer.url", "type": "image", "label": "Footer logo" }, + { "key": "footer.alt", "type": "text", "label": "Footer logo alt", "default": "" } + ] + }, + { + "id": "hero", + "label": "Hero", + "show": true, + "fields": [ + { "key": "event_name", "type": "text", "label": "Event name", "default": "Your Event Name" }, + { "key": "date_venue", "type": "text", "label": "Date & venue", "default": "Date and location" }, + { "key": "image.url", "type": "image", "label": "Hero background image" }, + { "key": "cta.text", "type": "text", "label": "CTA label", "default": "Register Now" }, + { "key": "cta.url", "type": "url", "label": "CTA URL", "default": "#" }, + { + "key": "cta.target", + "type": "select", + "label": "CTA target", + "default": "_blank", + "options": [ + { "value": "_blank", "label": "New tab" }, + { "value": "modal", "label": "Modal (iframe)" }, + { "value": "_self", "label": "Same tab" } + ] + }, + { "key": "countdown.show", "type": "boolean", "label": "Show countdown", "default": true }, + { "key": "countdown.date", "type": "date", "label": "Countdown date", "default": "" }, + { "key": "countdown.time", "type": "time", "label": "Countdown time", "default": "12:00" } + ] + }, + { + "id": "about", + "label": "About the event", + "show": true, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "About the Event" }, + { "key": "content", "type": "richtext", "label": "Content", "default": "

Describe your event here.

" }, + { + "key": "media.type", + "type": "select", + "label": "Media", + "default": "none", + "options": [ + { "value": "none", "label": "None" }, + { "value": "image", "label": "Image" }, + { "value": "video", "label": "Video (upload)" }, + { "value": "youtube", "label": "YouTube video" } + ] + }, + { + "key": "media.image", + "type": "image", + "label": "About image", + "showIf": { "field": "media.type", "equals": "image" } + }, + { + "key": "media.video", + "type": "video", + "label": "About video", + "showIf": { "field": "media.type", "equals": "video" } + }, + { + "key": "media.youtube", + "type": "url", + "label": "YouTube URL", + "placeholder": "https://www.youtube.com/watch?v=...", + "showIf": { "field": "media.type", "equals": "youtube" } + } + ] + }, + { + "id": "video", + "label": "Expert videos", + "show": false, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Hear it from experts" }, + { + "key": "media.type", + "type": "select", + "label": "Media", + "default": "none", + "options": [ + { "value": "none", "label": "None" }, + { "value": "image", "label": "Image" }, + { "value": "video", "label": "Video (upload)" }, + { "value": "youtube", "label": "YouTube video" } + ] + }, + { + "key": "media.image", + "type": "image", + "label": "Image", + "showIf": { "field": "media.type", "equals": "image" } + }, + { + "key": "media.video", + "type": "video", + "label": "Video", + "showIf": { "field": "media.type", "equals": "video" } + }, + { + "key": "media.youtube", + "type": "url", + "label": "YouTube URL", + "placeholder": "https://www.youtube.com/watch?v=...", + "showIf": { "field": "media.type", "equals": "youtube" } + } + ] + }, + { + "id": "informationBar", + "label": "Information bar", + "show": true, + "fields": [ + { + "key": "items", + "type": "array", + "label": "Info items", + "itemFields": [ + { "key": "icon", "type": "text", "label": "Icon class (LineIcons)", "default": "lni-map-marker" }, + { "key": "label", "type": "text", "label": "Label" }, + { "key": "value", "type": "text", "label": "Value" } + ] + } + ] + }, + { + "id": "event_highlights", + "label": "Why join (highlights)", + "show": true, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Why You Should Join?" }, + { "key": "subtitle", "type": "textarea", "label": "Subtitle", "default": "" }, + { + "key": "items", + "type": "array", + "label": "Highlight cards", + "itemFields": [ + { "key": "icon", "type": "text", "label": "Icon class", "default": "lni-microphone" }, + { "key": "title", "type": "text", "label": "Title" }, + { "key": "description", "type": "textarea", "label": "Description" } + ] + } + ] + }, + { + "id": "event_stats", + "label": "Stats counters", + "show": false, + "fields": [ + { + "key": "items", + "type": "array", + "label": "Stats", + "itemFields": [ + { "key": "icon", "type": "text", "label": "Icon class", "default": "lni-mic" }, + { "key": "value", "type": "text", "label": "Value" }, + { "key": "label", "type": "text", "label": "Label" } + ] + } + ] + }, + { + "id": "speakers", + "label": "Speakers", + "show": true, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Our Speakers" }, + { "key": "subtitle", "type": "textarea", "label": "Subtitle", "default": "" }, + { + "key": "items", + "type": "array", + "label": "Speakers", + "itemFields": [ + { "key": "name", "type": "text", "label": "Name" }, + { "key": "role", "type": "text", "label": "Role" }, + { "key": "image", "type": "image", "label": "Photo" }, + { "key": "url", "type": "url", "label": "Profile URL", "default": "#" } + ] + } + ] + }, + { + "id": "event_schedule", + "label": "Schedule", + "show": true, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Event Schedule" }, + { "key": "subtitle", "type": "textarea", "label": "Subtitle", "default": "" }, + { + "key": "days", + "type": "array", + "label": "Days", + "itemFields": [ + { "key": "label", "type": "text", "label": "Day label", "default": "Day 01" }, + { "key": "date", "type": "text", "label": "Date line", "default": "" }, + { + "key": "sessions", + "type": "array", + "label": "Sessions", + "itemFields": [ + { "key": "time", "type": "text", "label": "Time" }, + { "key": "type", "type": "text", "label": "Type", "default": "Main programme" }, + { "key": "title", "type": "text", "label": "Title" } + ] + } + ] + } + ] + }, + { + "id": "about_crest", + "label": "About CREST / secondary about", + "show": false, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "About" }, + { "key": "content", "type": "richtext", "label": "Content", "default": "" }, + { "key": "cta.text", "type": "text", "label": "CTA text", "default": "" }, + { "key": "cta.url", "type": "url", "label": "CTA URL", "default": "#" } + ] + }, + { + "id": "latest_news", + "label": "Latest news", + "show": false, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Latest News" }, + { "key": "subtitle", "type": "textarea", "label": "Subtitle", "default": "" } + ] + }, + { + "id": "sponsors", + "label": "Sponsors", + "show": true, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading (optional)", "default": "Sponsors" }, + { "key": "subtitle", "type": "textarea", "label": "Subtitle", "default": "" }, + { "key": "hideHeading", "type": "boolean", "label": "Hide section heading", "default": false }, + { "key": "hideGroupTitles", "type": "boolean", "label": "Hide sponsor tier titles", "default": false }, + { + "key": "groups", + "type": "array", + "label": "Sponsor groups", + "itemFields": [ + { "key": "title", "type": "text", "label": "Tier title" }, + { "key": "tier", "type": "text", "label": "Tier id", "default": "other" }, + { + "key": "items", + "type": "array", + "label": "Logos", + "itemFields": [ + { "key": "image", "type": "image", "label": "Logo image" }, + { "key": "alt", "type": "text", "label": "Alt text" } + ] + } + ] + } + ] + }, + { + "id": "map", + "label": "Map", + "show": false, + "fields": [ + { "key": "embedUrl", "type": "url", "label": "Google Maps embed URL" }, + { "key": "height", "type": "text", "label": "Iframe height (px)", "default": "450" } + ] + }, + { + "id": "contact", + "label": "Contact", + "show": true, + "fields": [ + { "key": "heading", "type": "text", "label": "Heading", "default": "Contact Us" }, + { "key": "subtitle", "type": "textarea", "label": "Subtitle", "default": "" }, + { "key": "formId", "type": "text", "label": "EventBuzz form ID" }, + { "key": "apiBaseUrl", "type": "url", "label": "API base URL", "default": "https://api.eventbuzz.live/api" }, + { "key": "address", "type": "textarea", "label": "Address", "default": "" }, + { + "key": "phones", + "type": "array", + "label": "Phone numbers", + "itemFields": [ + { "key": "label", "type": "text", "label": "Label" }, + { "key": "number", "type": "text", "label": "Display number" }, + { "key": "tel", "type": "text", "label": "tel: href value" } + ] + } + ] + }, + { + "id": "feedback", + "label": "Feedback FAB", + "show": false, + "fields": [ + { "key": "label", "type": "text", "label": "Button label", "default": "Feedback" }, + { "key": "url", "type": "url", "label": "Feedback form URL" }, + { + "key": "target", + "type": "select", + "label": "Open in", + "default": "_blank", + "options": [ + { "value": "_blank", "label": "New tab" }, + { "value": "modal", "label": "Modal" } + ] + } + ] + }, + { + "id": "footer", + "label": "Footer", + "show": true, + "fields": [ + { "key": "tagline", "type": "text", "label": "Tagline", "default": "" }, + { "key": "linksHeading", "type": "text", "label": "Links heading", "default": "Quick Links" }, + { "key": "social.heading", "type": "text", "label": "Social heading", "default": "Follow us" }, + { + "key": "links", + "type": "array", + "label": "Footer links", + "itemFields": [ + { "key": "text", "type": "text", "label": "Text" }, + { "key": "url", "type": "url", "label": "URL" }, + { + "key": "target", + "type": "select", + "label": "Target", + "default": "_self", + "options": [ + { "value": "modal", "label": "Modal" }, + { "value": "_blank", "label": "New tab" }, + { "value": "_self", "label": "Same tab" } + ] + } + ] + }, + { + "key": "social.links", + "type": "array", + "label": "Social links", + "itemFields": [ + { "key": "url", "type": "url", "label": "URL" }, + { "key": "icon", "type": "text", "label": "Icon class", "default": "lni-facebook-filled" }, + { "key": "label", "type": "text", "label": "Aria label" } + ] + } + ] + } + ] +} diff --git a/microsite-v2-templates/eventify/assets/css/LineIcons.css b/microsite-v2-templates/eventify/assets/css/LineIcons.css new file mode 100644 index 0000000..ad5fcb2 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/LineIcons.css @@ -0,0 +1,1907 @@ +@font-face { + font-family: 'LineIcons'; + src: url('../fonts/LineIcons.eot%3Fy2l643'); + src: url('../fonts/LineIcons.eot%3Fy2l643') format('embedded-opentype'), + url('../fonts/LineIcons.ttf%3Fy2l643') format('truetype'), + url('../fonts/LineIcons.woff%3Fy2l643') format('woff'), + url('../fonts/LineIcons.svg%3Fy2l643') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="lni-"], [class*=" lni-"] { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'LineIcons' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.lni-add-file:before { + content: "\e900"; +} +.lni-empty-file:before { + content: "\e916"; +} +.lni-remove-file:before { + content: "\e917"; +} +.lni-files:before { + content: "\ea6f"; +} +.lni-display-alt:before { + content: "\e901"; +} +.lni-laptop-phone:before { + content: "\e902"; +} +.lni-laptop:before { + content: "\e936"; +} +.lni-mobile:before { + content: "\e907"; +} +.lni-tab:before { + content: "\e922"; +} +.lni-timer:before { + content: "\e903"; +} +.lni-headphone:before { + content: "\e904"; +} +.lni-rocket:before { + content: "\e905"; +} +.lni-package:before { + content: "\e906"; +} +.lni-popup:before { + content: "\e909"; +} +.lni-scroll-down:before { + content: "\e90a"; +} +.lni-pagination:before { + content: "\e90b"; +} +.lni-unlock:before { + content: "\e90c"; +} +.lni-lock:before { + content: "\e946"; +} +.lni-reload:before { + content: "\e90d"; +} +.lni-map-marker:before { + content: "\e91e"; +} +.lni-map:before { + content: "\e90e"; +} +.lni-game:before { + content: "\e90f"; +} +.lni-search:before { + content: "\e910"; +} +.lni-alarm:before { + content: "\e911"; +} +.lni-code:before { + content: "\e91c"; +} +.lni-website:before { + content: "\e908"; +} +.lni-code-alt:before { + content: "\e912"; +} +.lni-display:before { + content: "\e913"; +} +.lni-shortcode:before { + content: "\e919"; +} +.lni-headphone-alt:before { + content: "\e915"; +} +.lni-alarm-clock:before { + content: "\e918"; +} +.lni-bookmark-alt:before { + content: "\e91a"; +} +.lni-bookmark:before { + content: "\e91b"; +} +.lni-layout:before { + content: "\e937"; +} +.lni-keyboard:before { + content: "\e91d"; +} +.lni-grid-alt:before { + content: "\e91f"; +} +.lni-grid:before { + content: "\e920"; +} +.lni-mic:before { + content: "\e921"; +} +.lni-signal:before { + content: "\e923"; +} +.lni-download:before { + content: "\e925"; +} +.lni-upload:before { + content: "\e926"; +} +.lni-zip:before { + content: "\e927"; +} +.lni-rss-feed:before { + content: "\e928"; +} +.lni-warning:before { + content: "\e929"; +} +.lni-cloud-sync:before { + content: "\e92a"; +} +.lni-cloud-upload:before { + content: "\e92b"; +} +.lni-cloud-check:before { + content: "\e92c"; +} +.lni-cloud-download:before { + content: "\e914"; +} +.lni-cog:before { + content: "\e92d"; +} +.lni-dashboard:before { + content: "\e92e"; +} +.lni-folder:before { + content: "\eaa0"; +} +.lni-database:before { + content: "\e92f"; +} +.lni-harddrive:before { + content: "\eaab"; +} +.lni-control-panel:before { + content: "\e930"; +} +.lni-plug:before { + content: "\e931"; +} +.lni-menu:before { + content: "\eab8"; +} +.lni-power-switch:before { + content: "\e932"; +} +.lni-printer:before { + content: "\e933"; +} +.lni-save:before { + content: "\eab9"; +} +.lni-layers:before { + content: "\e934"; +} +.lni-link:before { + content: "\e935"; +} +.lni-share:before { + content: "\eaba"; +} +.lni-inbox:before { + content: "\eabb"; +} +.lni-unlink:before { + content: "\e924"; +} +.lni-microphone:before { + content: "\e938"; +} +.lni-magnet:before { + content: "\e939"; +} +.lni-mouse:before { + content: "\e93a"; +} +.lni-share-alt:before { + content: "\e93b"; +} +.lni-bluetooth:before { + content: "\e93c"; +} +.lni-crop:before { + content: "\e93d"; +} +.lni-cut:before { + content: "\e93f"; +} +.lni-protection:before { + content: "\e940"; +} +.lni-shield:before { + content: "\eabc"; +} +.lni-bolt-alt:before { + content: "\e941"; +} +.lni-bolt:before { + content: "\e942"; +} +.lni-infinite:before { + content: "\e943"; +} +.lni-hand:before { + content: "\e944"; +} +.lni-flag:before { + content: "\e945"; +} +.lni-zoom-out:before { + content: "\e947"; +} +.lni-zoom-in:before { + content: "\e948"; +} +.lni-pin-alt:before { + content: "\e949"; +} +.lni-pin:before { + content: "\e9ba"; +} +.lni-more-alt:before { + content: "\e94a"; +} +.lni-more:before { + content: "\e958"; +} +.lni-check-box:before { + content: "\e94b"; +} +.lni-check-mark-circle:before { + content: "\e94c"; +} +.lni-cross-circle:before { + content: "\e94d"; +} +.lni-circle-minus:before { + content: "\e94e"; +} +.lni-close:before { + content: "\e951"; +} +.lni-star-filled:before { + content: "\e94f"; +} +.lni-star:before { + content: "\e950"; +} +.lni-star-empty:before { + content: "\e952"; +} +.lni-star-half:before { + content: "\e953"; +} +.lni-question-circle:before { + content: "\e954"; +} +.lni-thumbs-down:before { + content: "\e955"; +} +.lni-thumbs-up:before { + content: "\e956"; +} +.lni-minus:before { + content: "\e957"; +} +.lni-plus:before { + content: "\e959"; +} +.lni-ban:before { + content: "\e95a"; +} +.lni-hourglass:before { + content: "\eabd"; +} +.lni-trash:before { + content: "\e95b"; +} +.lni-key:before { + content: "\e95c"; +} +.lni-pulse:before { + content: "\e95d"; +} +.lni-heart:before { + content: "\e95e"; +} +.lni-heart-filled:before { + content: "\e93e"; +} +.lni-help:before { + content: "\e95f"; +} +.lni-paint-roller:before { + content: "\e960"; +} +.lni-ux:before { + content: "\e961"; +} +.lni-radio-button:before { + content: "\e962"; +} +.lni-brush-alt:before { + content: "\e963"; +} +.lni-select:before { + content: "\eabe"; +} +.lni-slice:before { + content: "\e964"; +} +.lni-move:before { + content: "\e965"; +} +.lni-wheelchair:before { + content: "\e966"; +} +.lni-vector:before { + content: "\e967"; +} +.lni-ruler-pencil:before { + content: "\e968"; +} +.lni-ruler:before { + content: "\e969"; +} +.lni-brush:before { + content: "\e96a"; +} +.lni-eraser:before { + content: "\e96b"; +} +.lni-ruler-alt:before { + content: "\e96c"; +} +.lni-color-pallet:before { + content: "\e96d"; +} +.lni-paint-bucket:before { + content: "\e96e"; +} +.lni-bulb:before { + content: "\e96f"; +} +.lni-highlight-alt:before { + content: "\e970"; +} +.lni-highlight:before { + content: "\e971"; +} +.lni-handshake:before { + content: "\e972"; +} +.lni-briefcase:before { + content: "\eabf"; +} +.lni-funnel:before { + content: "\eac0"; +} +.lni-world:before { + content: "\e973"; +} +.lni-calculator:before { + content: "\e974"; +} +.lni-target-revenue:before { + content: "\e975"; +} +.lni-revenue:before { + content: "\e976"; +} +.lni-invention:before { + content: "\e977"; +} +.lni-network:before { + content: "\e978"; +} +.lni-credit-cards:before { + content: "\e979"; +} +.lni-pie-chart:before { + content: "\e97a"; +} +.lni-archive:before { + content: "\e97b"; +} +.lni-magnifier:before { + content: "\e97c"; +} +.lni-agenda:before { + content: "\e97d"; +} +.lni-tag:before { + content: "\e97f"; +} +.lni-target:before { + content: "\e980"; +} +.lni-stamp:before { + content: "\e981"; +} +.lni-clipboard:before { + content: "\e982"; +} +.lni-licencse:before { + content: "\e983"; +} +.lni-paperclip:before { + content: "\e984"; +} +.lni-stats-up:before { + content: "\e97e"; +} +.lni-stats-down:before { + content: "\e985"; +} +.lni-bar-chart:before { + content: "\e986"; +} +.lni-bullhorn:before { + content: "\e987"; +} +.lni-calendar:before { + content: "\e988"; +} +.lni-quotation:before { + content: "\e989"; +} +.lni-bus:before { + content: "\e98a"; +} +.lni-car-alt:before { + content: "\e98b"; +} +.lni-car:before { + content: "\e98c"; +} +.lni-train:before { + content: "\e9a0"; +} +.lni-train-alt:before { + content: "\e991"; +} +.lni-helicopter:before { + content: "\e990"; +} +.lni-ship:before { + content: "\e992"; +} +.lni-bridge:before { + content: "\e993"; +} +.lni-scooter:before { + content: "\e98f"; +} +.lni-plane:before { + content: "\e994"; +} +.lni-bi-cycle:before { + content: "\e996"; +} +.lni-postcard:before { + content: "\e98d"; +} +.lni-road:before { + content: "\e98e"; +} +.lni-envelope:before { + content: "\e997"; +} +.lni-reply:before { + content: "\e998"; +} +.lni-bubble:before { + content: "\e995"; +} +.lni-support:before { + content: "\e999"; +} +.lni-comment-reply:before { + content: "\e99a"; +} +.lni-pointer:before { + content: "\e99b"; +} +.lni-phone:before { + content: "\e99c"; +} +.lni-phone-handset:before { + content: "\eac1"; +} +.lni-comment-alt:before { + content: "\e99e"; +} +.lni-comment:before { + content: "\e99f"; +} +.lni-coffee-cup:before { + content: "\e9a1"; +} +.lni-home:before { + content: "\e9a2"; +} +.lni-gift:before { + content: "\eac2"; +} +.lni-thought:before { + content: "\e9a3"; +} +.lni-eye:before { + content: "\eac3"; +} +.lni-user:before { + content: "\e9a4"; +} +.lni-users:before { + content: "\e9a5"; +} +.lni-wallet:before { + content: "\e9a6"; +} +.lni-tshirt:before { + content: "\e9a7"; +} +.lni-medall-alt:before { + content: "\e9a8"; +} +.lni-medall:before { + content: "\e9a9"; +} +.lni-notepad:before { + content: "\e9aa"; +} +.lni-crown:before { + content: "\e9ab"; +} +.lni-ticket:before { + content: "\e9ac"; +} +.lni-ticket-alt:before { + content: "\e9ad"; +} +.lni-certificate:before { + content: "\e9ae"; +} +.lni-cup:before { + content: "\e9af"; +} +.lni-library:before { + content: "\e9b0"; +} +.lni-school-bench-alt:before { + content: "\e9b1"; +} +.lni-school-bench:before { + content: "\e9b4"; +} +.lni-microscope:before { + content: "\e9b2"; +} +.lni-school-compass:before { + content: "\e9b3"; +} +.lni-information:before { + content: "\e9b5"; +} +.lni-graduation:before { + content: "\e9b6"; +} +.lni-write:before { + content: "\e9b7"; +} +.lni-pencil-alt:before { + content: "\e9b8"; +} +.lni-pencil:before { + content: "\e9b9"; +} +.lni-blackboard:before { + content: "\e9bb"; +} +.lni-book:before { + content: "\e9bc"; +} +.lni-shuffle:before { + content: "\e9bd"; +} +.lni-gallery:before { + content: "\eac4"; +} +.lni-image:before { + content: "\eac5"; +} +.lni-volume-mute:before { + content: "\e9be"; +} +.lni-backward:before { + content: "\e9bf"; +} +.lni-forward:before { + content: "\e9c0"; +} +.lni-stop:before { + content: "\e9c1"; +} +.lni-play:before { + content: "\e9c2"; +} +.lni-pause:before { + content: "\e9c3"; +} +.lni-music:before { + content: "\e9c4"; +} +.lni-frame-expand:before { + content: "\e9c5"; +} +.lni-full-screen:before { + content: "\eac6"; +} +.lni-video:before { + content: "\e9c6"; +} +.lni-volume-high:before { + content: "\e9c7"; +} +.lni-volume-low:before { + content: "\e9c8"; +} +.lni-volume-medium:before { + content: "\e9c9"; +} +.lni-volume:before { + content: "\e9ca"; +} +.lni-camera:before { + content: "\e9cb"; +} +.lni-invest-monitor:before { + content: "\e9cc"; +} +.lni-grow:before { + content: "\e9cd"; +} +.lni-money-location:before { + content: "\e9ce"; +} +.lni-cloudnetwork:before { + content: "\e9cf"; +} +.lni-diamond:before { + content: "\e9d0"; +} +.lni-customer:before { + content: "\e9d1"; +} +.lni-domain:before { + content: "\e9d2"; +} +.lni-target-audience:before { + content: "\e9d3"; +} +.lni-seo:before { + content: "\e9d4"; +} +.lni-keyword-research:before { + content: "\e9d5"; +} +.lni-seo-monitoring:before { + content: "\e9d6"; +} +.lni-seo-consulting:before { + content: "\e9d7"; +} +.lni-money-protection:before { + content: "\e9d8"; +} +.lni-offer:before { + content: "\e9d9"; +} +.lni-delivery:before { + content: "\e9da"; +} +.lni-investment:before { + content: "\e9db"; +} +.lni-shopping-basket:before { + content: "\e9dc"; +} +.lni-coin:before { + content: "\e9dd"; +} +.lni-cart-full:before { + content: "\e9de"; +} +.lni-cart:before { + content: "\e9df"; +} +.lni-burger:before { + content: "\e9e0"; +} +.lni-restaurant:before { + content: "\e9e1"; +} +.lni-service:before { + content: "\e9e2"; +} +.lni-chef-hat:before { + content: "\e9e3"; +} +.lni-cake:before { + content: "\e9e4"; +} +.lni-pizza:before { + content: "\e9e5"; +} +.lni-teabag:before { + content: "\e9e6"; +} +.lni-dinner:before { + content: "\e9e7"; +} +.lni-taxi:before { + content: "\e9e8"; +} +.lni-caravan:before { + content: "\e9e9"; +} +.lni-pyramids:before { + content: "\e9ea"; +} +.lni-surfboard:before { + content: "\e9eb"; +} +.lni-travel:before { + content: "\e9ec"; +} +.lni-island:before { + content: "\e9ed"; +} +.lni-mashroom:before { + content: "\e9ee"; +} +.lni-sprout:before { + content: "\e9ef"; +} +.lni-tree:before { + content: "\e9f0"; +} +.lni-trees:before { + content: "\e9f1"; +} +.lni-flower:before { + content: "\e9f2"; +} +.lni-bug:before { + content: "\e9f3"; +} +.lni-leaf:before { + content: "\e9f4"; +} +.lni-fresh-juice:before { + content: "\e9f5"; +} +.lni-heart-monitor:before { + content: "\e9f6"; +} +.lni-dumbbell:before { + content: "\e9f7"; +} +.lni-skipping-rope:before { + content: "\e9f8"; +} +.lni-slim:before { + content: "\e9f9"; +} +.lni-weight:before { + content: "\e9fa"; +} +.lni-basketball:before { + content: "\e9fb"; +} +.lni-first-aid:before { + content: "\e9fc"; +} +.lni-ambulance:before { + content: "\e9fd"; +} +.lni-hospital:before { + content: "\e9fe"; +} +.lni-syringe:before { + content: "\e9ff"; +} +.lni-capsule:before { + content: "\ea00"; +} +.lni-stethoscope:before { + content: "\ea01"; +} +.lni-wheelbarrow:before { + content: "\ea02"; +} +.lni-shovel:before { + content: "\ea03"; +} +.lni-construction-hammer:before { + content: "\ea04"; +} +.lni-brick:before { + content: "\ea05"; +} +.lni-hammer:before { + content: "\eac7"; +} +.lni-helmet:before { + content: "\ea06"; +} +.lni-trowel:before { + content: "\ea07"; +} +.lni-construction:before { + content: "\ea08"; +} +.lni-apartment:before { + content: "\ea09"; +} +.lni-juice:before { + content: "\ea0a"; +} +.lni-spray:before { + content: "\ea0b"; +} +.lni-candy-cane:before { + content: "\ea0c"; +} +.lni-candy:before { + content: "\ea0d"; +} +.lni-fireworks:before { + content: "\ea0e"; +} +.lni-flags:before { + content: "\ea0f"; +} +.lni-baloon:before { + content: "\ea10"; +} +.lni-cloud:before { + content: "\ea11"; +} +.lni-night:before { + content: "\ea12"; +} +.lni-cloudy-sun:before { + content: "\ea13"; +} +.lni-rain:before { + content: "\ea14"; +} +.lni-thunder:before { + content: "\ea15"; +} +.lni-drop:before { + content: "\ea16"; +} +.lni-thunder-alt:before { + content: "\ea18"; +} +.lni-sun:before { + content: "\ea17"; +} +.lni-spell-check:before { + content: "\ea1a"; +} +.lni-text-format:before { + content: "\ea1b"; +} +.lni-text-format-remove:before { + content: "\ea1c"; +} +.lni-italic:before { + content: "\ea1d"; +} +.lni-line-dotted:before { + content: "\ea1e"; +} +.lni-text-align-center:before { + content: "\ea19"; +} +.lni-text-align-left:before { + content: "\ea20"; +} +.lni-text-align-right:before { + content: "\ea21"; +} +.lni-text-align-justify:before { + content: "\ea22"; +} +.lni-bold:before { + content: "\ea23"; +} +.lni-page-break:before { + content: "\ea24"; +} +.lni-strikethrough:before { + content: "\ea25"; +} +.lni-text-size:before { + content: "\ea26"; +} +.lni-line-dashed:before { + content: "\ea27"; +} +.lni-line-double:before { + content: "\ea28"; +} +.lni-direction-ltr:before { + content: "\ea29"; +} +.lni-direction-rtl:before { + content: "\ea2a"; +} +.lni-list:before { + content: "\ea2b"; +} +.lni-line-spacing:before { + content: "\ea2f"; +} +.lni-sort-alpha-asc:before { + content: "\ea1f"; +} +.lni-sort-amount-asc:before { + content: "\ea2c"; +} +.lni-indent-decrease:before { + content: "\ea2d"; +} +.lni-indent-increase:before { + content: "\ea2e"; +} +.lni-pilcrow:before { + content: "\ea30"; +} +.lni-underline:before { + content: "\ea31"; +} +.lni-dollar:before { + content: "\ea32"; +} +.lni-rupee:before { + content: "\ea33"; +} +.lni-pound:before { + content: "\ea34"; +} +.lni-yen:before { + content: "\ea35"; +} +.lni-euro:before { + content: "\ea36"; +} +.lni-emoji-happy:before { + content: "\ea37"; +} +.lni-emoji-tounge:before { + content: "\ea38"; +} +.lni-emoji-cool:before { + content: "\ea39"; +} +.lni-emoji-friendly:before { + content: "\ea3a"; +} +.lni-emoji-neutral:before { + content: "\ea3b"; +} +.lni-emoji-sad:before { + content: "\ea3c"; +} +.lni-emoji-smile:before { + content: "\ea3d"; +} +.lni-emoji-suspect:before { + content: "\ea3e"; +} +.lni-direction-alt:before { + content: "\ea3f"; +} +.lni-enter:before { + content: "\ea40"; +} +.lni-exit-down:before { + content: "\ea41"; +} +.lni-exit-up:before { + content: "\ea5f"; +} +.lni-exit:before { + content: "\ea42"; +} +.lni-chevron-up:before { + content: "\ea43"; +} +.lni-chevron-left:before { + content: "\ea44"; +} +.lni-chevron-down:before { + content: "\ea45"; +} +.lni-chevron-right:before { + content: "\ea46"; +} +.lni-arrow-down:before { + content: "\ea47"; +} +.lni-arrows-horizontal:before { + content: "\ea48"; +} +.lni-arrows-vertical:before { + content: "\ea49"; +} +.lni-direction:before { + content: "\ea4a"; +} +.lni-arrow-left:before { + content: "\ea4b"; +} +.lni-arrow-right:before { + content: "\ea4c"; +} +.lni-arrow-up:before { + content: "\ea4d"; +} +.lni-arrow-down-circle:before { + content: "\ea4e"; +} +.lni-anchor:before { + content: "\ea4f"; +} +.lni-arrow-left-circle:before { + content: "\ea50"; +} +.lni-arrow-right-circle:before { + content: "\ea51"; +} +.lni-arrow-up-circle:before { + content: "\ea52"; +} +.lni-angle-double-down:before { + content: "\ea53"; +} +.lni-angle-double-left:before { + content: "\ea54"; +} +.lni-angle-double-right:before { + content: "\ea55"; +} +.lni-angle-double-up:before { + content: "\ea56"; +} +.lni-arrow-top-left:before { + content: "\ea57"; +} +.lni-arrow-top-right:before { + content: "\ea58"; +} +.lni-chevron-down-circle:before { + content: "\ea59"; +} +.lni-chevron-left-circle:before { + content: "\ea5a"; +} +.lni-chevron-right-circle:before { + content: "\ea5b"; +} +.lni-chevron-up-circle:before { + content: "\ea5c"; +} +.lni-shift-left:before { + content: "\ea5d"; +} +.lni-shift-right:before { + content: "\ea5e"; +} +.lni-pointer-down:before { + content: "\ea60"; +} +.lni-pointer-right:before { + content: "\ea62"; +} +.lni-pointer-left:before { + content: "\ea61"; +} +.lni-pointer-up:before { + content: "\ea63"; +} +.lni-spinner-arrow:before { + content: "\ea64"; +} +.lni-spinner-solid:before { + content: "\ea65"; +} +.lni-spinner:before { + content: "\ea66"; +} +.lni-google:before { + content: "\e99d"; +} +.lni-producthunt:before { + content: "\ea68"; +} +.lni-paypal:before { + content: "\eab3"; +} +.lni-paypal-original:before { + content: "\ea6c"; +} +.lni-java:before { + content: "\ea6d"; +} +.lni-microsoft:before { + content: "\ea6b"; +} +.lni-windows:before { + content: "\ea6e"; +} +.lni-flickr:before { + content: "\ea70"; +} +.lni-drupal:before { + content: "\ea9f"; +} +.lni-drupal-original:before { + content: "\ea71"; +} +.lni-android:before { + content: "\eab7"; +} +.lni-android-original:before { + content: "\ea72"; +} +.lni-playstore:before { + content: "\eab4"; +} +.lni-git:before { + content: "\ea9b"; +} +.lni-github-original:before { + content: "\ea73"; +} +.lni-github:before { + content: "\ea9c"; +} +.lni-steam:before { + content: "\ea75"; +} +.lni-shopify:before { + content: "\ea76"; +} +.lni-snapchat:before { + content: "\ea77"; +} +.lni-soundcloud:before { + content: "\eab5"; +} +.lni-souncloud-original:before { + content: "\ea78"; +} +.lni-telegram:before { + content: "\ea79"; +} +.lni-twitch:before { + content: "\ea7a"; +} +.lni-vimeo:before { + content: "\ea7c"; +} +.lni-vk:before { + content: "\ea7d"; +} +.lni-wechat:before { + content: "\ea7e"; +} +.lni-whatsapp:before { + content: "\ea7f"; +} +.lni-yahoo:before { + content: "\ea80"; +} +.lni-youtube:before { + content: "\ea81"; +} +.lni-stackoverflow:before { + content: "\ea82"; +} +.lni-slideshare:before { + content: "\ea84"; +} +.lni-slack:before { + content: "\ea85"; +} +.lni-lineicons-alt:before { + content: "\ea69"; +} +.lni-lineicons:before { + content: "\ea6a"; +} +.lni-skype:before { + content: "\ea86"; +} +.lni-pinterest:before { + content: "\ea87"; +} +.lni-reddit:before { + content: "\ea88"; +} +.lni-line:before { + content: "\ea89"; +} +.lni-megento:before { + content: "\ea8b"; +} +.lni-blogger:before { + content: "\ea8e"; +} +.lni-bootstrap:before { + content: "\ea8f"; +} +.lni-dribbble:before { + content: "\ea90"; +} +.lni-dropbox:before { + content: "\ea98"; +} +.lni-dropbox-original:before { + content: "\ea91"; +} +.lni-envato:before { + content: "\ea92"; +} +.lni-500px:before { + content: "\ea95"; +} +.lni-twitter-original:before { + content: "\ea7b"; +} +.lni-twitter:before { + content: "\ea97"; +} +.lni-twitter-filled:before { + content: "\eac8"; +} +.lni-facebook-messenger:before { + content: "\ea93"; +} +.lni-facebook-original:before { + content: "\ea94"; +} +.lni-facebook-filled:before { + content: "\ea99"; +} +.lni-facebook:before { + content: "\ea9a"; +} +.lni-joomla:before { + content: "\eac9"; +} +.lni-firefox:before { + content: "\ea9d"; +} +.lni-amazon-original:before { + content: "\ea74"; +} +.lni-amazon:before { + content: "\ea9e"; +} +.lni-linkedin-original:before { + content: "\ea8a"; +} +.lni-linkedin:before { + content: "\eaa1"; +} +.lni-linkedin-filled:before { + content: "\eaca"; +} +.lni-bitbucket:before { + content: "\eaa2"; +} +.lni-quora:before { + content: "\eaa3"; +} +.lni-medium:before { + content: "\eaa4"; +} +.lni-instagram-original:before { + content: "\ea8c"; +} +.lni-instagram-filled:before { + content: "\eaa6"; +} +.lni-instagram:before { + content: "\eaa7"; +} +.lni-bitcoin:before { + content: "\eaa8"; +} +.lni-stripe:before { + content: "\eaa9"; +} +.lni-wordpress-filled:before { + content: "\eaaa"; +} +.lni-wordpress:before { + content: "\ea96"; +} +.lni-google-plus:before { + content: "\eaac"; +} +.lni-mastercard:before { + content: "\eaae"; +} +.lni-visa:before { + content: "\eaaf"; +} +.lni-amex:before { + content: "\eacb"; +} +.lni-apple:before { + content: "\eab0"; +} +.lni-behance:before { + content: "\eab1"; +} +.lni-behance-original:before { + content: "\ea8d"; +} +.lni-chrome:before { + content: "\eab2"; +} +.lni-spotify-original:before { + content: "\ea83"; +} +.lni-spotify:before { + content: "\eab6"; +} +.lni-html:before { + content: "\eaad"; +} +.lni-css:before { + content: "\eaa5"; +} +.lni-ycombinator:before { + content: "\ea67"; +} + +/* Extra */ +span{ + display: inline-block; +} +.lni-spin-effect { + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; +} + +.lni-spin-effect-hover:hover { + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; +} + +.lni-tada-effect { + -webkit-animation: tada 1.5s ease infinite; + animation: tada 1.5s ease infinite; +} + +.lni-tada-effect-hover:hover { + -webkit-animation: tada 1.5s ease infinite; + animation: tada 1.5s ease infinite; +} + +.lni-flashing-effect { + -webkit-animation: flashing 1.5s infinite linear; + animation: flashing 1.5s infinite linear; +} + +.lni-flashing-effect-hover:hover { + -webkit-animation: flashing 1.5s infinite linear; + animation: flashing 1.5s infinite linear; +} + +.lni-burst-effect { + -webkit-animation: burst 1.5s infinite linear; + animation: burst 1.5s infinite linear; +} + +.lni-burst-effect-hover:hover { + -webkit-animation: burst 1.5s infinite linear; + animation: burst 1.5s infinite linear; +} + +.lni-fade-up-effect { + -webkit-animation: fade-up 1.5s infinite linear; + animation: fade-up 1.5s infinite linear; +} + +.lni-fade-up-effect-hover:hover { + -webkit-animation: fade-up 1.5s infinite linear; + animation: fade-up 1.5s infinite linear; +} + +.lni-fade-down-effect { + -webkit-animation: fade-down 1.5s infinite linear; + animation: fade-down 1.5s infinite linear; +} + +.lni-fade-down-effect-hover:hover { + -webkit-animation: fade-down 1.5s infinite linear; + animation: fade-down 1.5s infinite linear; +} + +.lni-fade-left-effect { + -webkit-animation: fade-left 1.5s infinite linear; + animation: fade-left 1.5s infinite linear; +} + +.lni-fade-left-effect-hover:hover { + -webkit-animation: fade-left 1.5s infinite linear; + animation: fade-left 1.5s infinite linear; +} + +.lni-fade-right-effect { + -webkit-animation: fade-right 1.5s infinite linear; + animation: fade-right 1.5s infinite linear; +} + +.lni-fade-right-effect-hover:hover { + -webkit-animation: fade-right 1.5s infinite linear; + animation: fade-right 1.5s infinite linear; +} + +.size-xs { + font-size: 1rem !important; +} + +.size-sm { + font-size: 1.55rem !important; +} + +.size-md { + font-size: 2.25rem !important; +} + +.size-fw { + font-size: 1.2857142857em; + line-height: .8em; + width: 1.2857142857em; + height: .8em; + margin-top: -0.2em !important; + vertical-align: middle; +} + +.size-lg { + font-size: 3rem !important; +} + + +@-webkit-keyframes spin +{ + 0% + { + -webkit-transform: rotate(0); + transform: rotate(0); + } + 100% + { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin +{ + 0% + { + -webkit-transform: rotate(0); + transform: rotate(0); + } + 100% + { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-webkit-keyframes burst +{ + 0% + { + -webkit-transform: scale(1); + transform: scale(1); + + opacity: 1; + } + 90% + { + -webkit-transform: scale(1.5); + transform: scale(1.5); + + opacity: 0; + } +} +@keyframes burst +{ + 0% + { + -webkit-transform: scale(1); + transform: scale(1); + + opacity: 1; + } + 90% + { + -webkit-transform: scale(1.5); + transform: scale(1.5); + + opacity: 0; + } +} +@-webkit-keyframes flashing +{ + 0% + { + opacity: 1; + } + 45% + { + opacity: 0; + } + 90% + { + opacity: 1; + } +} +@keyframes flashing +{ + 0% + { + opacity: 1; + } + 45% + { + opacity: 0; + } + 90% + { + opacity: 1; + } +} +@-webkit-keyframes fade-left +{ + 0% + { + -webkit-transform: translateX(0); + transform: translateX(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + + opacity: 0; + } +} +@keyframes fade-left +{ + 0% + { + -webkit-transform: translateX(0); + transform: translateX(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateX(-20px); + transform: translateX(-20px); + + opacity: 0; + } +} +@-webkit-keyframes fade-right +{ + 0% + { + -webkit-transform: translateX(0); + transform: translateX(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateX(20px); + transform: translateX(20px); + + opacity: 0; + } +} +@keyframes fade-right +{ + 0% + { + -webkit-transform: translateX(0); + transform: translateX(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateX(20px); + transform: translateX(20px); + + opacity: 0; + } +} +@-webkit-keyframes fade-up +{ + 0% + { + -webkit-transform: translateY(0); + transform: translateY(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + + opacity: 0; + } +} +@keyframes fade-up +{ + 0% + { + -webkit-transform: translateY(0); + transform: translateY(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateY(-20px); + transform: translateY(-20px); + + opacity: 0; + } +} +@-webkit-keyframes fade-down +{ + 0% + { + -webkit-transform: translateY(0); + transform: translateY(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateY(20px); + transform: translateY(20px); + + opacity: 0; + } +} +@keyframes fade-down +{ + 0% + { + -webkit-transform: translateY(0); + transform: translateY(0); + + opacity: 1; + } + 75% + { + -webkit-transform: translateY(20px); + transform: translateY(20px); + + opacity: 0; + } +} +@-webkit-keyframes tada +{ + from + { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, + 20% + { + -webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); + transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); + } + + 30%, + 50%, + 70%, + 90% + { + -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); + transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); + } + + 40%, + 60%, + 80% + { + -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg); + transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, -10deg); + } + + to + { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes tada +{ + from + { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, + 20% + { + -webkit-transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); + transform: scale3d(.95, .95, .95) rotate3d(0, 0, 1, -10deg); + } + + 30%, + 50%, + 70%, + 90% + { + -webkit-transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); + transform: scale3d(1, 1, 1) rotate3d(0, 0, 1, 10deg); + } + + 40%, + 60%, + 80% + { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + to + { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} +.lni-spin-effect +{ + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; +} +.lni-spin-effect-hover:hover +{ + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; +} + +.lni-tada-effect +{ + -webkit-animation: tada 1.5s ease infinite; + animation: tada 1.5s ease infinite; +} +.lni-tada-effect-hover:hover +{ + -webkit-animation: tada 1.5s ease infinite; + animation: tada 1.5s ease infinite; +} + +.lni-flashing-effect +{ + -webkit-animation: flashing 1.5s infinite linear; + animation: flashing 1.5s infinite linear; +} +.lni-flashing-effect-hover:hover +{ + -webkit-animation: flashing 1.5s infinite linear; + animation: flashing 1.5s infinite linear; +} + +.lni-burst-effect +{ + -webkit-animation: burst 1.5s infinite linear; + animation: burst 1.5s infinite linear; +} +.lni-burst-effect-hover:hover +{ + -webkit-animation: burst 1.5s infinite linear; + animation: burst 1.5s infinite linear; +} +.lni-fade-up-effect +{ + -webkit-animation: fade-up 1.5s infinite linear; + animation: fade-up 1.5s infinite linear; +} +.lni-fade-up-effect-hover:hover +{ + -webkit-animation: fade-up 1.5s infinite linear; + animation: fade-up 1.5s infinite linear; +} +.lni-fade-down-effect +{ + -webkit-animation: fade-down 1.5s infinite linear; + animation: fade-down 1.5s infinite linear; +} +.lni-fade-down-effect-hover:hover +{ + -webkit-animation: fade-down 1.5s infinite linear; + animation: fade-down 1.5s infinite linear; +} +.lni-fade-left-effect +{ + -webkit-animation: fade-left 1.5s infinite linear; + animation: fade-left 1.5s infinite linear; +} +.lni-fade-left-effect-hover:hover +{ + -webkit-animation: fade-left 1.5s infinite linear; + animation: fade-left 1.5s infinite linear; +} +.lni-fade-right-effect +{ + -webkit-animation: fade-right 1.5s infinite linear; + animation: fade-right 1.5s infinite linear; +} +.lni-fade-right-effect-hover:hover +{ + -webkit-animation: fade-right 1.5s infinite linear; + animation: fade-right 1.5s infinite linear; +} + + + + diff --git a/microsite-v2-templates/eventify/assets/css/animate.css b/microsite-v2-templates/eventify/assets/css/animate.css new file mode 100644 index 0000000..d26682f --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/animate.css @@ -0,0 +1,3625 @@ +@charset "UTF-8"; + +/*! + * animate.css -https://daneden.github.io/animate.css/ + * Version - 3.7.2 + * Licensed under the MIT license - http://opensource.org/licenses/MIT + * + * Copyright (c) 2019 Daniel Eden + */ + +@-webkit-keyframes bounce { + from, + 20%, + 53%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 40%, + 43% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -30px, 0); + transform: translate3d(0, -30px, 0); + } + + 70% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -15px, 0); + transform: translate3d(0, -15px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -4px, 0); + transform: translate3d(0, -4px, 0); + } +} + +@keyframes bounce { + from, + 20%, + 53%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 40%, + 43% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -30px, 0); + transform: translate3d(0, -30px, 0); + } + + 70% { + -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); + -webkit-transform: translate3d(0, -15px, 0); + transform: translate3d(0, -15px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -4px, 0); + transform: translate3d(0, -4px, 0); + } +} + +.bounce { + -webkit-animation-name: bounce; + animation-name: bounce; + -webkit-transform-origin: center bottom; + transform-origin: center bottom; +} + +@-webkit-keyframes flash { + from, + 50%, + to { + opacity: 1; + } + + 25%, + 75% { + opacity: 0; + } +} + +@keyframes flash { + from, + 50%, + to { + opacity: 1; + } + + 25%, + 75% { + opacity: 0; + } +} + +.flash { + -webkit-animation-name: flash; + animation-name: flash; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes pulse { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes pulse { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 50% { + -webkit-transform: scale3d(1.05, 1.05, 1.05); + transform: scale3d(1.05, 1.05, 1.05); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.pulse { + -webkit-animation-name: pulse; + animation-name: pulse; +} + +@-webkit-keyframes rubberBand { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 30% { + -webkit-transform: scale3d(1.25, 0.75, 1); + transform: scale3d(1.25, 0.75, 1); + } + + 40% { + -webkit-transform: scale3d(0.75, 1.25, 1); + transform: scale3d(0.75, 1.25, 1); + } + + 50% { + -webkit-transform: scale3d(1.15, 0.85, 1); + transform: scale3d(1.15, 0.85, 1); + } + + 65% { + -webkit-transform: scale3d(0.95, 1.05, 1); + transform: scale3d(0.95, 1.05, 1); + } + + 75% { + -webkit-transform: scale3d(1.05, 0.95, 1); + transform: scale3d(1.05, 0.95, 1); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes rubberBand { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 30% { + -webkit-transform: scale3d(1.25, 0.75, 1); + transform: scale3d(1.25, 0.75, 1); + } + + 40% { + -webkit-transform: scale3d(0.75, 1.25, 1); + transform: scale3d(0.75, 1.25, 1); + } + + 50% { + -webkit-transform: scale3d(1.15, 0.85, 1); + transform: scale3d(1.15, 0.85, 1); + } + + 65% { + -webkit-transform: scale3d(0.95, 1.05, 1); + transform: scale3d(0.95, 1.05, 1); + } + + 75% { + -webkit-transform: scale3d(1.05, 0.95, 1); + transform: scale3d(1.05, 0.95, 1); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.rubberBand { + -webkit-animation-name: rubberBand; + animation-name: rubberBand; +} + +@-webkit-keyframes shake { + from, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 10%, + 30%, + 50%, + 70%, + 90% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 20%, + 40%, + 60%, + 80% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } +} + +@keyframes shake { + from, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 10%, + 30%, + 50%, + 70%, + 90% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 20%, + 40%, + 60%, + 80% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } +} + +.shake { + -webkit-animation-name: shake; + animation-name: shake; +} + +@-webkit-keyframes headShake { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 6.5% { + -webkit-transform: translateX(-6px) rotateY(-9deg); + transform: translateX(-6px) rotateY(-9deg); + } + + 18.5% { + -webkit-transform: translateX(5px) rotateY(7deg); + transform: translateX(5px) rotateY(7deg); + } + + 31.5% { + -webkit-transform: translateX(-3px) rotateY(-5deg); + transform: translateX(-3px) rotateY(-5deg); + } + + 43.5% { + -webkit-transform: translateX(2px) rotateY(3deg); + transform: translateX(2px) rotateY(3deg); + } + + 50% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +@keyframes headShake { + 0% { + -webkit-transform: translateX(0); + transform: translateX(0); + } + + 6.5% { + -webkit-transform: translateX(-6px) rotateY(-9deg); + transform: translateX(-6px) rotateY(-9deg); + } + + 18.5% { + -webkit-transform: translateX(5px) rotateY(7deg); + transform: translateX(5px) rotateY(7deg); + } + + 31.5% { + -webkit-transform: translateX(-3px) rotateY(-5deg); + transform: translateX(-3px) rotateY(-5deg); + } + + 43.5% { + -webkit-transform: translateX(2px) rotateY(3deg); + transform: translateX(2px) rotateY(3deg); + } + + 50% { + -webkit-transform: translateX(0); + transform: translateX(0); + } +} + +.headShake { + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + -webkit-animation-name: headShake; + animation-name: headShake; +} + +@-webkit-keyframes swing { + 20% { + -webkit-transform: rotate3d(0, 0, 1, 15deg); + transform: rotate3d(0, 0, 1, 15deg); + } + + 40% { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + 60% { + -webkit-transform: rotate3d(0, 0, 1, 5deg); + transform: rotate3d(0, 0, 1, 5deg); + } + + 80% { + -webkit-transform: rotate3d(0, 0, 1, -5deg); + transform: rotate3d(0, 0, 1, -5deg); + } + + to { + -webkit-transform: rotate3d(0, 0, 1, 0deg); + transform: rotate3d(0, 0, 1, 0deg); + } +} + +@keyframes swing { + 20% { + -webkit-transform: rotate3d(0, 0, 1, 15deg); + transform: rotate3d(0, 0, 1, 15deg); + } + + 40% { + -webkit-transform: rotate3d(0, 0, 1, -10deg); + transform: rotate3d(0, 0, 1, -10deg); + } + + 60% { + -webkit-transform: rotate3d(0, 0, 1, 5deg); + transform: rotate3d(0, 0, 1, 5deg); + } + + 80% { + -webkit-transform: rotate3d(0, 0, 1, -5deg); + transform: rotate3d(0, 0, 1, -5deg); + } + + to { + -webkit-transform: rotate3d(0, 0, 1, 0deg); + transform: rotate3d(0, 0, 1, 0deg); + } +} + +.swing { + -webkit-transform-origin: top center; + transform-origin: top center; + -webkit-animation-name: swing; + animation-name: swing; +} + +@-webkit-keyframes tada { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + } + + 30%, + 50%, + 70%, + 90% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, + 60%, + 80% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes tada { + from { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } + + 10%, + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); + } + + 30%, + 50%, + 70%, + 90% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); + } + + 40%, + 60%, + 80% { + -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); + } + + to { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.tada { + -webkit-animation-name: tada; + animation-name: tada; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes wobble { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 15% { + -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + } + + 30% { + -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + } + + 45% { + -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + } + + 60% { + -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + } + + 75% { + -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes wobble { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 15% { + -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); + } + + 30% { + -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); + } + + 45% { + -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); + } + + 60% { + -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); + } + + 75% { + -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.wobble { + -webkit-animation-name: wobble; + animation-name: wobble; +} + +@-webkit-keyframes jello { + from, + 11.1%, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 22.2% { + -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); + transform: skewX(-12.5deg) skewY(-12.5deg); + } + + 33.3% { + -webkit-transform: skewX(6.25deg) skewY(6.25deg); + transform: skewX(6.25deg) skewY(6.25deg); + } + + 44.4% { + -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); + transform: skewX(-3.125deg) skewY(-3.125deg); + } + + 55.5% { + -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); + transform: skewX(1.5625deg) skewY(1.5625deg); + } + + 66.6% { + -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); + transform: skewX(-0.78125deg) skewY(-0.78125deg); + } + + 77.7% { + -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); + transform: skewX(0.390625deg) skewY(0.390625deg); + } + + 88.8% { + -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + } +} + +@keyframes jello { + from, + 11.1%, + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + 22.2% { + -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); + transform: skewX(-12.5deg) skewY(-12.5deg); + } + + 33.3% { + -webkit-transform: skewX(6.25deg) skewY(6.25deg); + transform: skewX(6.25deg) skewY(6.25deg); + } + + 44.4% { + -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); + transform: skewX(-3.125deg) skewY(-3.125deg); + } + + 55.5% { + -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); + transform: skewX(1.5625deg) skewY(1.5625deg); + } + + 66.6% { + -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); + transform: skewX(-0.78125deg) skewY(-0.78125deg); + } + + 77.7% { + -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); + transform: skewX(0.390625deg) skewY(0.390625deg); + } + + 88.8% { + -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + transform: skewX(-0.1953125deg) skewY(-0.1953125deg); + } +} + +.jello { + -webkit-animation-name: jello; + animation-name: jello; + -webkit-transform-origin: center; + transform-origin: center; +} + +@-webkit-keyframes heartBeat { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 14% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 28% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 42% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 70% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes heartBeat { + 0% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 14% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 28% { + -webkit-transform: scale(1); + transform: scale(1); + } + + 42% { + -webkit-transform: scale(1.3); + transform: scale(1.3); + } + + 70% { + -webkit-transform: scale(1); + transform: scale(1); + } +} + +.heartBeat { + -webkit-animation-name: heartBeat; + animation-name: heartBeat; + -webkit-animation-duration: 1.3s; + animation-duration: 1.3s; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; +} + +@-webkit-keyframes bounceIn { + from, + 20%, + 40%, + 60%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 20% { + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(1.03, 1.03, 1.03); + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + -webkit-transform: scale3d(0.97, 0.97, 0.97); + transform: scale3d(0.97, 0.97, 0.97); + } + + to { + opacity: 1; + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes bounceIn { + from, + 20%, + 40%, + 60%, + 80%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 20% { + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + 40% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(1.03, 1.03, 1.03); + transform: scale3d(1.03, 1.03, 1.03); + } + + 80% { + -webkit-transform: scale3d(0.97, 0.97, 0.97); + transform: scale3d(0.97, 0.97, 0.97); + } + + to { + opacity: 1; + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +.bounceIn { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-animation-name: bounceIn; + animation-name: bounceIn; +} + +@-webkit-keyframes bounceInDown { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -3000px, 0); + transform: translate3d(0, -3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 25px, 0); + transform: translate3d(0, 25px, 0); + } + + 75% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, 5px, 0); + transform: translate3d(0, 5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInDown { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(0, -3000px, 0); + transform: translate3d(0, -3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, 25px, 0); + transform: translate3d(0, 25px, 0); + } + + 75% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, 5px, 0); + transform: translate3d(0, 5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInDown { + -webkit-animation-name: bounceInDown; + animation-name: bounceInDown; +} + +@-webkit-keyframes bounceInLeft { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(-3000px, 0, 0); + transform: translate3d(-3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(25px, 0, 0); + transform: translate3d(25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(5px, 0, 0); + transform: translate3d(5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInLeft { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + 0% { + opacity: 0; + -webkit-transform: translate3d(-3000px, 0, 0); + transform: translate3d(-3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(25px, 0, 0); + transform: translate3d(25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(-10px, 0, 0); + transform: translate3d(-10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(5px, 0, 0); + transform: translate3d(5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInLeft { + -webkit-animation-name: bounceInLeft; + animation-name: bounceInLeft; +} + +@-webkit-keyframes bounceInRight { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(3000px, 0, 0); + transform: translate3d(3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(-25px, 0, 0); + transform: translate3d(-25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(-5px, 0, 0); + transform: translate3d(-5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInRight { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(3000px, 0, 0); + transform: translate3d(3000px, 0, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(-25px, 0, 0); + transform: translate3d(-25px, 0, 0); + } + + 75% { + -webkit-transform: translate3d(10px, 0, 0); + transform: translate3d(10px, 0, 0); + } + + 90% { + -webkit-transform: translate3d(-5px, 0, 0); + transform: translate3d(-5px, 0, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInRight { + -webkit-animation-name: bounceInRight; + animation-name: bounceInRight; +} + +@-webkit-keyframes bounceInUp { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(0, 3000px, 0); + transform: translate3d(0, 3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 75% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -5px, 0); + transform: translate3d(0, -5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes bounceInUp { + from, + 60%, + 75%, + 90%, + to { + -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + } + + from { + opacity: 0; + -webkit-transform: translate3d(0, 3000px, 0); + transform: translate3d(0, 3000px, 0); + } + + 60% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + 75% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 90% { + -webkit-transform: translate3d(0, -5px, 0); + transform: translate3d(0, -5px, 0); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.bounceInUp { + -webkit-animation-name: bounceInUp; + animation-name: bounceInUp; +} + +@-webkit-keyframes bounceOut { + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 50%, + 55% { + opacity: 1; + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } +} + +@keyframes bounceOut { + 20% { + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } + + 50%, + 55% { + opacity: 1; + -webkit-transform: scale3d(1.1, 1.1, 1.1); + transform: scale3d(1.1, 1.1, 1.1); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } +} + +.bounceOut { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-animation-name: bounceOut; + animation-name: bounceOut; +} + +@-webkit-keyframes bounceOutDown { + 20% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +@keyframes bounceOutDown { + 20% { + -webkit-transform: translate3d(0, 10px, 0); + transform: translate3d(0, 10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, -20px, 0); + transform: translate3d(0, -20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +.bounceOutDown { + -webkit-animation-name: bounceOutDown; + animation-name: bounceOutDown; +} + +@-webkit-keyframes bounceOutLeft { + 20% { + opacity: 1; + -webkit-transform: translate3d(20px, 0, 0); + transform: translate3d(20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +@keyframes bounceOutLeft { + 20% { + opacity: 1; + -webkit-transform: translate3d(20px, 0, 0); + transform: translate3d(20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +.bounceOutLeft { + -webkit-animation-name: bounceOutLeft; + animation-name: bounceOutLeft; +} + +@-webkit-keyframes bounceOutRight { + 20% { + opacity: 1; + -webkit-transform: translate3d(-20px, 0, 0); + transform: translate3d(-20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +@keyframes bounceOutRight { + 20% { + opacity: 1; + -webkit-transform: translate3d(-20px, 0, 0); + transform: translate3d(-20px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +.bounceOutRight { + -webkit-animation-name: bounceOutRight; + animation-name: bounceOutRight; +} + +@-webkit-keyframes bounceOutUp { + 20% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, 20px, 0); + transform: translate3d(0, 20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +@keyframes bounceOutUp { + 20% { + -webkit-transform: translate3d(0, -10px, 0); + transform: translate3d(0, -10px, 0); + } + + 40%, + 45% { + opacity: 1; + -webkit-transform: translate3d(0, 20px, 0); + transform: translate3d(0, 20px, 0); + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +.bounceOutUp { + -webkit-animation-name: bounceOutUp; + animation-name: bounceOutUp; +} + +@-webkit-keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +.fadeIn { + -webkit-animation-name: fadeIn; + animation-name: fadeIn; +} + +@-webkit-keyframes fadeInDown { + from { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInDown { + from { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInDown { + -webkit-animation-name: fadeInDown; + animation-name: fadeInDown; +} + +@-webkit-keyframes fadeInDownBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInDownBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInDownBig { + -webkit-animation-name: fadeInDownBig; + animation-name: fadeInDownBig; +} + +@-webkit-keyframes fadeInLeft { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInLeft { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInLeft { + -webkit-animation-name: fadeInLeft; + animation-name: fadeInLeft; +} + +@-webkit-keyframes fadeInLeftBig { + from { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInLeftBig { + from { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInLeftBig { + -webkit-animation-name: fadeInLeftBig; + animation-name: fadeInLeftBig; +} + +@-webkit-keyframes fadeInRight { + from { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInRight { + from { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInRight { + -webkit-animation-name: fadeInRight; + animation-name: fadeInRight; +} + +@-webkit-keyframes fadeInRightBig { + from { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInRightBig { + from { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInRightBig { + -webkit-animation-name: fadeInRightBig; + animation-name: fadeInRightBig; +} + +@-webkit-keyframes fadeInUp { + from { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInUp { + -webkit-animation-name: fadeInUp; + animation-name: fadeInUp; +} + +@-webkit-keyframes fadeInUpBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes fadeInUpBig { + from { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.fadeInUpBig { + -webkit-animation-name: fadeInUpBig; + animation-name: fadeInUpBig; +} + +@-webkit-keyframes fadeOut { + from { + opacity: 1; + } + + to { + opacity: 0; + } +} + +@keyframes fadeOut { + from { + opacity: 1; + } + + to { + opacity: 0; + } +} + +.fadeOut { + -webkit-animation-name: fadeOut; + animation-name: fadeOut; +} + +@-webkit-keyframes fadeOutDown { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +@keyframes fadeOutDown { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +.fadeOutDown { + -webkit-animation-name: fadeOutDown; + animation-name: fadeOutDown; +} + +@-webkit-keyframes fadeOutDownBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +@keyframes fadeOutDownBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, 2000px, 0); + transform: translate3d(0, 2000px, 0); + } +} + +.fadeOutDownBig { + -webkit-animation-name: fadeOutDownBig; + animation-name: fadeOutDownBig; +} + +@-webkit-keyframes fadeOutLeft { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +@keyframes fadeOutLeft { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.fadeOutLeft { + -webkit-animation-name: fadeOutLeft; + animation-name: fadeOutLeft; +} + +@-webkit-keyframes fadeOutLeftBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +@keyframes fadeOutLeftBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(-2000px, 0, 0); + transform: translate3d(-2000px, 0, 0); + } +} + +.fadeOutLeftBig { + -webkit-animation-name: fadeOutLeftBig; + animation-name: fadeOutLeftBig; +} + +@-webkit-keyframes fadeOutRight { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +@keyframes fadeOutRight { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.fadeOutRight { + -webkit-animation-name: fadeOutRight; + animation-name: fadeOutRight; +} + +@-webkit-keyframes fadeOutRightBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +@keyframes fadeOutRightBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(2000px, 0, 0); + transform: translate3d(2000px, 0, 0); + } +} + +.fadeOutRightBig { + -webkit-animation-name: fadeOutRightBig; + animation-name: fadeOutRightBig; +} + +@-webkit-keyframes fadeOutUp { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +@keyframes fadeOutUp { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +.fadeOutUp { + -webkit-animation-name: fadeOutUp; + animation-name: fadeOutUp; +} + +@-webkit-keyframes fadeOutUpBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +@keyframes fadeOutUpBig { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(0, -2000px, 0); + transform: translate3d(0, -2000px, 0); + } +} + +.fadeOutUpBig { + -webkit-animation-name: fadeOutUpBig; + animation-name: fadeOutUpBig; +} + +@-webkit-keyframes flip { + from { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, -360deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, -360deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + to { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +@keyframes flip { + from { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, -360deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, -360deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 40% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -190deg); + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; + } + + 50% { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) + rotate3d(0, 1, 0, -170deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 80% { + -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + to { + -webkit-transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) + rotate3d(0, 1, 0, 0deg); + transform: perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, 0deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } +} + +.animated.flip { + -webkit-backface-visibility: visible; + backface-visibility: visible; + -webkit-animation-name: flip; + animation-name: flip; +} + +@-webkit-keyframes flipInX { + from { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +@keyframes flipInX { + from { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + transform: perspective(400px) rotate3d(1, 0, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + transform: perspective(400px) rotate3d(1, 0, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +.flipInX { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInX; + animation-name: flipInX; +} + +@-webkit-keyframes flipInY { + from { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +@keyframes flipInY { + from { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + opacity: 0; + } + + 40% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + transform: perspective(400px) rotate3d(0, 1, 0, -20deg); + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; + } + + 60% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + transform: perspective(400px) rotate3d(0, 1, 0, 10deg); + opacity: 1; + } + + 80% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + transform: perspective(400px) rotate3d(0, 1, 0, -5deg); + } + + to { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } +} + +.flipInY { + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipInY; + animation-name: flipInY; +} + +@-webkit-keyframes flipOutX { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + opacity: 0; + } +} + +@keyframes flipOutX { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + transform: perspective(400px) rotate3d(1, 0, 0, -20deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + transform: perspective(400px) rotate3d(1, 0, 0, 90deg); + opacity: 0; + } +} + +.flipOutX { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-animation-name: flipOutX; + animation-name: flipOutX; + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; +} + +@-webkit-keyframes flipOutY { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + opacity: 0; + } +} + +@keyframes flipOutY { + from { + -webkit-transform: perspective(400px); + transform: perspective(400px); + } + + 30% { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + transform: perspective(400px) rotate3d(0, 1, 0, -15deg); + opacity: 1; + } + + to { + -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + transform: perspective(400px) rotate3d(0, 1, 0, 90deg); + opacity: 0; + } +} + +.flipOutY { + -webkit-animation-duration: 0.75s; + animation-duration: 0.75s; + -webkit-backface-visibility: visible !important; + backface-visibility: visible !important; + -webkit-animation-name: flipOutY; + animation-name: flipOutY; +} + +@-webkit-keyframes lightSpeedIn { + from { + -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); + transform: translate3d(100%, 0, 0) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: skewX(20deg); + transform: skewX(20deg); + opacity: 1; + } + + 80% { + -webkit-transform: skewX(-5deg); + transform: skewX(-5deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes lightSpeedIn { + from { + -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); + transform: translate3d(100%, 0, 0) skewX(-30deg); + opacity: 0; + } + + 60% { + -webkit-transform: skewX(20deg); + transform: skewX(20deg); + opacity: 1; + } + + 80% { + -webkit-transform: skewX(-5deg); + transform: skewX(-5deg); + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.lightSpeedIn { + -webkit-animation-name: lightSpeedIn; + animation-name: lightSpeedIn; + -webkit-animation-timing-function: ease-out; + animation-timing-function: ease-out; +} + +@-webkit-keyframes lightSpeedOut { + from { + opacity: 1; + } + + to { + -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); + transform: translate3d(100%, 0, 0) skewX(30deg); + opacity: 0; + } +} + +@keyframes lightSpeedOut { + from { + opacity: 1; + } + + to { + -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); + transform: translate3d(100%, 0, 0) skewX(30deg); + opacity: 0; + } +} + +.lightSpeedOut { + -webkit-animation-name: lightSpeedOut; + animation-name: lightSpeedOut; + -webkit-animation-timing-function: ease-in; + animation-timing-function: ease-in; +} + +@-webkit-keyframes rotateIn { + from { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, -200deg); + transform: rotate3d(0, 0, 1, -200deg); + opacity: 0; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateIn { + from { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, -200deg); + transform: rotate3d(0, 0, 1, -200deg); + opacity: 0; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateIn { + -webkit-animation-name: rotateIn; + animation-name: rotateIn; +} + +@-webkit-keyframes rotateInDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInDownLeft { + -webkit-animation-name: rotateInDownLeft; + animation-name: rotateInDownLeft; +} + +@-webkit-keyframes rotateInDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInDownRight { + -webkit-animation-name: rotateInDownRight; + animation-name: rotateInDownRight; +} + +@-webkit-keyframes rotateInUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInUpLeft { + -webkit-animation-name: rotateInUpLeft; + animation-name: rotateInUpLeft; +} + +@-webkit-keyframes rotateInUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -90deg); + transform: rotate3d(0, 0, 1, -90deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +@keyframes rotateInUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -90deg); + transform: rotate3d(0, 0, 1, -90deg); + opacity: 0; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + opacity: 1; + } +} + +.rotateInUpRight { + -webkit-animation-name: rotateInUpRight; + animation-name: rotateInUpRight; +} + +@-webkit-keyframes rotateOut { + from { + -webkit-transform-origin: center; + transform-origin: center; + opacity: 1; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, 200deg); + transform: rotate3d(0, 0, 1, 200deg); + opacity: 0; + } +} + +@keyframes rotateOut { + from { + -webkit-transform-origin: center; + transform-origin: center; + opacity: 1; + } + + to { + -webkit-transform-origin: center; + transform-origin: center; + -webkit-transform: rotate3d(0, 0, 1, 200deg); + transform: rotate3d(0, 0, 1, 200deg); + opacity: 0; + } +} + +.rotateOut { + -webkit-animation-name: rotateOut; + animation-name: rotateOut; +} + +@-webkit-keyframes rotateOutDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } +} + +@keyframes rotateOutDownLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, 45deg); + transform: rotate3d(0, 0, 1, 45deg); + opacity: 0; + } +} + +.rotateOutDownLeft { + -webkit-animation-name: rotateOutDownLeft; + animation-name: rotateOutDownLeft; +} + +@-webkit-keyframes rotateOutDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +@keyframes rotateOutDownRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +.rotateOutDownRight { + -webkit-animation-name: rotateOutDownRight; + animation-name: rotateOutDownRight; +} + +@-webkit-keyframes rotateOutUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +@keyframes rotateOutUpLeft { + from { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: left bottom; + transform-origin: left bottom; + -webkit-transform: rotate3d(0, 0, 1, -45deg); + transform: rotate3d(0, 0, 1, -45deg); + opacity: 0; + } +} + +.rotateOutUpLeft { + -webkit-animation-name: rotateOutUpLeft; + animation-name: rotateOutUpLeft; +} + +@-webkit-keyframes rotateOutUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 90deg); + transform: rotate3d(0, 0, 1, 90deg); + opacity: 0; + } +} + +@keyframes rotateOutUpRight { + from { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + opacity: 1; + } + + to { + -webkit-transform-origin: right bottom; + transform-origin: right bottom; + -webkit-transform: rotate3d(0, 0, 1, 90deg); + transform: rotate3d(0, 0, 1, 90deg); + opacity: 0; + } +} + +.rotateOutUpRight { + -webkit-animation-name: rotateOutUpRight; + animation-name: rotateOutUpRight; +} + +@-webkit-keyframes hinge { + 0% { + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, + 60% { + -webkit-transform: rotate3d(0, 0, 1, 80deg); + transform: rotate3d(0, 0, 1, 80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40%, + 80% { + -webkit-transform: rotate3d(0, 0, 1, 60deg); + transform: rotate3d(0, 0, 1, 60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + opacity: 1; + } + + to { + -webkit-transform: translate3d(0, 700px, 0); + transform: translate3d(0, 700px, 0); + opacity: 0; + } +} + +@keyframes hinge { + 0% { + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 20%, + 60% { + -webkit-transform: rotate3d(0, 0, 1, 80deg); + transform: rotate3d(0, 0, 1, 80deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + } + + 40%, + 80% { + -webkit-transform: rotate3d(0, 0, 1, 60deg); + transform: rotate3d(0, 0, 1, 60deg); + -webkit-transform-origin: top left; + transform-origin: top left; + -webkit-animation-timing-function: ease-in-out; + animation-timing-function: ease-in-out; + opacity: 1; + } + + to { + -webkit-transform: translate3d(0, 700px, 0); + transform: translate3d(0, 700px, 0); + opacity: 0; + } +} + +.hinge { + -webkit-animation-duration: 2s; + animation-duration: 2s; + -webkit-animation-name: hinge; + animation-name: hinge; +} + +@-webkit-keyframes jackInTheBox { + from { + opacity: 0; + -webkit-transform: scale(0.1) rotate(30deg); + transform: scale(0.1) rotate(30deg); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + } + + 50% { + -webkit-transform: rotate(-10deg); + transform: rotate(-10deg); + } + + 70% { + -webkit-transform: rotate(3deg); + transform: rotate(3deg); + } + + to { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } +} + +@keyframes jackInTheBox { + from { + opacity: 0; + -webkit-transform: scale(0.1) rotate(30deg); + transform: scale(0.1) rotate(30deg); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + } + + 50% { + -webkit-transform: rotate(-10deg); + transform: rotate(-10deg); + } + + 70% { + -webkit-transform: rotate(3deg); + transform: rotate(3deg); + } + + to { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } +} + +.jackInTheBox { + -webkit-animation-name: jackInTheBox; + animation-name: jackInTheBox; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollIn { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes rollIn { + from { + opacity: 0; + -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); + } + + to { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.rollIn { + -webkit-animation-name: rollIn; + animation-name: rollIn; +} + +/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ + +@-webkit-keyframes rollOut { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + } +} + +@keyframes rollOut { + from { + opacity: 1; + } + + to { + opacity: 0; + -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); + } +} + +.rollOut { + -webkit-animation-name: rollOut; + animation-name: rollOut; +} + +@-webkit-keyframes zoomIn { + from { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 50% { + opacity: 1; + } +} + +@keyframes zoomIn { + from { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + 50% { + opacity: 1; + } +} + +.zoomIn { + -webkit-animation-name: zoomIn; + animation-name: zoomIn; +} + +@-webkit-keyframes zoomInDown { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInDown { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInDown { + -webkit-animation-name: zoomInDown; + animation-name: zoomInDown; +} + +@-webkit-keyframes zoomInLeft { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInLeft { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInLeft { + -webkit-animation-name: zoomInLeft; + animation-name: zoomInLeft; +} + +@-webkit-keyframes zoomInRight { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInRight { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInRight { + -webkit-animation-name: zoomInRight; + animation-name: zoomInRight; +} + +@-webkit-keyframes zoomInUp { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomInUp { + from { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + 60% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomInUp { + -webkit-animation-name: zoomInUp; + animation-name: zoomInUp; +} + +@-webkit-keyframes zoomOut { + from { + opacity: 1; + } + + 50% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + to { + opacity: 0; + } +} + +@keyframes zoomOut { + from { + opacity: 1; + } + + 50% { + opacity: 0; + -webkit-transform: scale3d(0.3, 0.3, 0.3); + transform: scale3d(0.3, 0.3, 0.3); + } + + to { + opacity: 0; + } +} + +.zoomOut { + -webkit-animation-name: zoomOut; + animation-name: zoomOut; +} + +@-webkit-keyframes zoomOutDown { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomOutDown { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomOutDown { + -webkit-animation-name: zoomOutDown; + animation-name: zoomOutDown; +} + +@-webkit-keyframes zoomOutLeft { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0); + transform: scale(0.1) translate3d(-2000px, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + } +} + +@keyframes zoomOutLeft { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0); + transform: scale(0.1) translate3d(-2000px, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + } +} + +.zoomOutLeft { + -webkit-animation-name: zoomOutLeft; + animation-name: zoomOutLeft; +} + +@-webkit-keyframes zoomOutRight { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(2000px, 0, 0); + transform: scale(0.1) translate3d(2000px, 0, 0); + -webkit-transform-origin: right center; + transform-origin: right center; + } +} + +@keyframes zoomOutRight { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0); + } + + to { + opacity: 0; + -webkit-transform: scale(0.1) translate3d(2000px, 0, 0); + transform: scale(0.1) translate3d(2000px, 0, 0); + -webkit-transform-origin: right center; + transform-origin: right center; + } +} + +.zoomOutRight { + -webkit-animation-name: zoomOutRight; + animation-name: zoomOutRight; +} + +@-webkit-keyframes zoomOutUp { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +@keyframes zoomOutUp { + 40% { + opacity: 1; + -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0); + -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + + to { + opacity: 0; + -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0); + -webkit-transform-origin: center bottom; + transform-origin: center bottom; + -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); + } +} + +.zoomOutUp { + -webkit-animation-name: zoomOutUp; + animation-name: zoomOutUp; +} + +@-webkit-keyframes slideInDown { + from { + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInDown { + from { + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInDown { + -webkit-animation-name: slideInDown; + animation-name: slideInDown; +} + +@-webkit-keyframes slideInLeft { + from { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInLeft { + from { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInLeft { + -webkit-animation-name: slideInLeft; + animation-name: slideInLeft; +} + +@-webkit-keyframes slideInRight { + from { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInRight { + from { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInRight { + -webkit-animation-name: slideInRight; + animation-name: slideInRight; +} + +@-webkit-keyframes slideInUp { + from { + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +@keyframes slideInUp { + from { + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + visibility: visible; + } + + to { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.slideInUp { + -webkit-animation-name: slideInUp; + animation-name: slideInUp; +} + +@-webkit-keyframes slideOutDown { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +@keyframes slideOutDown { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + } +} + +.slideOutDown { + -webkit-animation-name: slideOutDown; + animation-name: slideOutDown; +} + +@-webkit-keyframes slideOutLeft { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +@keyframes slideOutLeft { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.slideOutLeft { + -webkit-animation-name: slideOutLeft; + animation-name: slideOutLeft; +} + +@-webkit-keyframes slideOutRight { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +@keyframes slideOutRight { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.slideOutRight { + -webkit-animation-name: slideOutRight; + animation-name: slideOutRight; +} + +@-webkit-keyframes slideOutUp { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +@keyframes slideOutUp { + from { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + } +} + +.slideOutUp { + -webkit-animation-name: slideOutUp; + animation-name: slideOutUp; +} + +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.animated.infinite { + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; +} + +.animated.delay-1s { + -webkit-animation-delay: 1s; + animation-delay: 1s; +} + +.animated.delay-2s { + -webkit-animation-delay: 2s; + animation-delay: 2s; +} + +.animated.delay-3s { + -webkit-animation-delay: 3s; + animation-delay: 3s; +} + +.animated.delay-4s { + -webkit-animation-delay: 4s; + animation-delay: 4s; +} + +.animated.delay-5s { + -webkit-animation-delay: 5s; + animation-delay: 5s; +} + +.animated.fast { + -webkit-animation-duration: 800ms; + animation-duration: 800ms; +} + +.animated.faster { + -webkit-animation-duration: 500ms; + animation-duration: 500ms; +} + +.animated.slow { + -webkit-animation-duration: 2s; + animation-duration: 2s; +} + +.animated.slower { + -webkit-animation-duration: 3s; + animation-duration: 3s; +} + +@media (print), (prefers-reduced-motion: reduce) { + .animated { + -webkit-animation-duration: 1ms !important; + animation-duration: 1ms !important; + -webkit-transition-duration: 1ms !important; + transition-duration: 1ms !important; + -webkit-animation-iteration-count: 1 !important; + animation-iteration-count: 1 !important; + } +} diff --git a/microsite-v2-templates/eventify/assets/css/bootstrap.min.css b/microsite-v2-templates/eventify/assets/css/bootstrap.min.css new file mode 100644 index 0000000..92e3fe8 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.3.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/microsite-v2-templates/eventify/assets/css/default.css b/microsite-v2-templates/eventify/assets/css/default.css new file mode 100644 index 0000000..96f51c2 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/default.css @@ -0,0 +1,933 @@ +/* Deafult Margin & Padding */ +/*-- Margin Top --*/ +.mt-5 { + margin-top: 5px; +} +.mt-10 { + margin-top: 10px; +} +.mt-15 { + margin-top: 15px; +} +.mt-20 { + margin-top: 20px; +} +.mt-25 { + margin-top: 25px; +} +.mt-30 { + margin-top: 30px; +} +.mt-35 { + margin-top: 35px; +} +.mt-40 { + margin-top: 40px; +} +.mt-45 { + margin-top: 45px; +} +.mt-50 { + margin-top: 50px; +} +.mt-55 { + margin-top: 55px; +} +.mt-60 { + margin-top: 60px; +} +.mt-65 { + margin-top: 65px; +} +.mt-70 { + margin-top: 70px; +} +.mt-75 { + margin-top: 75px; +} +.mt-80 { + margin-top: 80px; +} +.mt-85 { + margin-top: 85px; +} +.mt-90 { + margin-top: 90px; +} +.mt-95 { + margin-top: 95px; +} +.mt-100 { + margin-top: 100px; +} +.mt-105 { + margin-top: 105px; +} +.mt-110 { + margin-top: 110px; +} +.mt-115 { + margin-top: 115px; +} +.mt-120 { + margin-top: 120px; +} +.mt-125 { + margin-top: 125px; +} +.mt-130 { + margin-top: 130px; +} +.mt-135 { + margin-top: 135px; +} +.mt-140 { + margin-top: 140px; +} +.mt-145 { + margin-top: 145px; +} +.mt-150 { + margin-top: 150px; +} +.mt-155 { + margin-top: 155px; +} +.mt-160 { + margin-top: 160px; +} +.mt-165 { + margin-top: 165px; +} +.mt-170 { + margin-top: 170px; +} +.mt-175 { + margin-top: 175px; +} +.mt-180 { + margin-top: 180px; +} +.mt-185 { + margin-top: 185px; +} +.mt-190 { + margin-top: 190px; +} +.mt-195 { + margin-top: 195px; +} +.mt-200 { + margin-top: 200px; +} +/*-- Margin Bottom --*/ + +.mb-5 { + margin-bottom: 5px; +} +.mb-10 { + margin-bottom: 10px; +} +.mb-15 { + margin-bottom: 15px; +} +.mb-20 { + margin-bottom: 20px; +} +.mb-25 { + margin-bottom: 25px; +} +.mb-30 { + margin-bottom: 30px; +} +.mb-35 { + margin-bottom: 35px; +} +.mb-40 { + margin-bottom: 40px; +} +.mb-45 { + margin-bottom: 45px; +} +.mb-50 { + margin-bottom: 50px; +} +.mb-55 { + margin-bottom: 55px; +} +.mb-60 { + margin-bottom: 60px; +} +.mb-65 { + margin-bottom: 65px; +} +.mb-70 { + margin-bottom: 70px; +} +.mb-75 { + margin-bottom: 75px; +} +.mb-80 { + margin-bottom: 80px; +} +.mb-85 { + margin-bottom: 85px; +} +.mb-90 { + margin-bottom: 90px; +} +.mb-95 { + margin-bottom: 95px; +} +.mb-100 { + margin-bottom: 100px; +} +.mb-105 { + margin-bottom: 105px; +} +.mb-110 { + margin-bottom: 110px; +} +.mb-115 { + margin-bottom: 115px; +} +.mb-120 { + margin-bottom: 120px; +} +.mb-125 { + margin-bottom: 125px; +} +.mb-130 { + margin-bottom: 130px; +} +.mb-135 { + margin-bottom: 135px; +} +.mb-140 { + margin-bottom: 140px; +} +.mb-145 { + margin-bottom: 145px; +} +.mb-150 { + margin-bottom: 150px; +} +.mb-155 { + margin-bottom: 155px; +} +.mb-160 { + margin-bottom: 160px; +} +.mb-165 { + margin-bottom: 165px; +} +.mb-170 { + margin-bottom: 170px; +} +.mb-175 { + margin-bottom: 175px; +} +.mb-180 { + margin-bottom: 180px; +} +.mb-185 { + margin-bottom: 185px; +} +.mb-190 { + margin-bottom: 190px; +} +.mb-195 { + margin-bottom: 195px; +} +.mb-200 { + margin-bottom: 200px; +} +/*-- margin left --*/ +.ml-5 { + margin-left: 5px; +} +.ml-10 { + margin-left: 10px; +} +.ml-15 { + margin-left: 15px; +} +.ml-20 { + margin-left: 20px; +} +.ml-25 { + margin-left: 25px; +} +.ml-30 { + margin-left: 30px; +} +.ml-35 { + margin-left: 35px; +} +.ml-40 { + margin-left: 40px; +} +.ml-45 { + margin-left: 45px; +} +.ml-50 { + margin-left: 50px; +} +.ml-55 { + margin-left: 55px; +} +.ml-60 { + margin-left: 60px; +} +.ml-65 { + margin-left: 65px; +} +.ml-70 { + margin-left: 70px; +} +.ml-75 { + margin-left: 75px; +} +.ml-80 { + margin-left: 80px; +} +.ml-85 { + margin-left: 85px; +} +.ml-90 { + margin-left: 90px; +} +.ml-95 { + margin-left: 95px; +} +.ml-100 { + margin-left: 100px; +} +.ml-105 { + margin-left: 105px; +} +.ml-110 { + margin-left: 110px; +} +.ml-115 { + margin-left: 115px; +} +.ml-120 { + margin-left: 120px; +} +.ml-125 { + margin-left: 125px; +} +.ml-130 { + margin-left: 130px; +} +.ml-135 { + margin-left: 135px; +} +.ml-140 { + margin-left: 140px; +} +.ml-145 { + margin-left: 145px; +} +.ml-150 { + margin-left: 150px; +} +.ml-155 { + margin-left: 155px; +} +.ml-160 { + margin-left: 160px; +} +.ml-165 { + margin-left: 165px; +} +.ml-170 { + margin-left: 170px; +} +.ml-175 { + margin-left: 175px; +} +.ml-180 { + margin-left: 180px; +} +.ml-185 { + margin-left: 185px; +} +.ml-190 { + margin-left: 190px; +} +.ml-195 { + margin-left: 195px; +} +.ml-200 { + margin-left: 200px; +} +/*-- margin right --*/ +.mr-5 { + margin-right: 5px; +} +.mr-10 { + margin-right: 10px; +} +.mr-15 { + margin-right: 15px; +} +.mr-20 { + margin-right: 20px; +} +.mr-25 { + margin-right: 25px; +} +.mr-30 { + margin-right: 30px; +} +.mr-35 { + margin-right: 35px; +} +.mr-40 { + margin-right: 40px; +} +.mr-45 { + margin-right: 45px; +} +.mr-50 { + margin-right: 50px; +} +.mr-55 { + margin-right: 55px; +} +.mr-60 { + margin-right: 60px; +} +.mr-65 { + margin-right: 65px; +} +.mr-70 { + margin-right: 70px; +} +.mr-75 { + margin-right: 75px; +} +.mr-80 { + margin-right: 80px; +} +.mr-85 { + margin-right: 85px; +} +.mr-90 { + margin-right: 90px; +} +.mr-95 { + margin-right: 95px; +} +.mr-100 { + margin-right: 100px; +} +.mr-105 { + margin-right: 105px; +} +.mr-110 { + margin-right: 110px; +} +.mr-115 { + margin-right: 115px; +} +.mr-120 { + margin-right: 120px; +} +.mr-125 { + margin-right: 125px; +} +.mr-130 { + margin-right: 130px; +} +.mr-135 { + margin-right: 135px; +} +.mr-140 { + margin-right: 140px; +} +.mr-145 { + margin-right: 145px; +} +.mr-150 { + margin-right: 150px; +} +.mr-155 { + margin-right: 155px; +} +.mr-160 { + margin-right: 160px; +} +.mr-165 { + margin-right: 165px; +} +.mr-170 { + margin-right: 170px; +} +.mr-175 { + margin-right: 175px; +} +.mr-180 { + margin-right: 180px; +} +.mr-185 { + margin-right: 185px; +} +.mr-190 { + margin-right: 190px; +} +.mr-195 { + margin-right: 195px; +} +.mr-200 { + margin-right: 200px; +} + + +/*-- Padding Top --*/ + +.pt-5 { + padding-top: 5px; +} +.pt-10 { + padding-top: 10px; +} +.pt-15 { + padding-top: 15px; +} +.pt-20 { + padding-top: 20px; +} +.pt-25 { + padding-top: 25px; +} +.pt-30 { + padding-top: 30px; +} +.pt-35 { + padding-top: 35px; +} +.pt-40 { + padding-top: 40px; +} +.pt-45 { + padding-top: 45px; +} +.pt-50 { + padding-top: 50px; +} +.pt-55 { + padding-top: 55px; +} +.pt-60 { + padding-top: 60px; +} +.pt-65 { + padding-top: 65px; +} +.pt-70 { + padding-top: 70px; +} +.pt-75 { + padding-top: 75px; +} +.pt-80 { + padding-top: 80px; +} +.pt-85 { + padding-top: 85px; +} +.pt-90 { + padding-top: 90px; +} +.pt-95 { + padding-top: 95px; +} +.pt-100 { + padding-top: 100px; +} +.pt-105 { + padding-top: 105px; +} +.pt-110 { + padding-top: 110px; +} +.pt-115 { + padding-top: 115px; +} +.pt-120 { + padding-top: 120px; +} +.pt-125 { + padding-top: 125px; +} +.pt-130 { + padding-top: 130px; +} +.pt-135 { + padding-top: 135px; +} +.pt-140 { + padding-top: 140px; +} +.pt-145 { + padding-top: 145px; +} +.pt-150 { + padding-top: 150px; +} +.pt-155 { + padding-top: 155px; +} +.pt-160 { + padding-top: 160px; +} +.pt-165 { + padding-top: 165px; +} +.pt-170 { + padding-top: 170px; +} +.pt-175 { + padding-top: 175px; +} +.pt-180 { + padding-top: 180px; +} +.pt-185 { + padding-top: 185px; +} +.pt-190 { + padding-top: 190px; +} +.pt-195 { + padding-top: 195px; +} +.pt-200 { + padding-top: 200px; +} +/*-- Padding Bottom --*/ + +.pb-5 { + padding-bottom: 5px; +} +.pb-10 { + padding-bottom: 10px; +} +.pb-15 { + padding-bottom: 15px; +} +.pb-20 { + padding-bottom: 20px; +} +.pb-25 { + padding-bottom: 25px; +} +.pb-30 { + padding-bottom: 30px; +} +.pb-35 { + padding-bottom: 35px; +} +.pb-40 { + padding-bottom: 40px; +} +.pb-45 { + padding-bottom: 45px; +} +.pb-50 { + padding-bottom: 50px; +} +.pb-55 { + padding-bottom: 55px; +} +.pb-60 { + padding-bottom: 60px; +} +.pb-65 { + padding-bottom: 65px; +} +.pb-70 { + padding-bottom: 70px; +} +.pb-75 { + padding-bottom: 75px; +} +.pb-80 { + padding-bottom: 80px; +} +.pb-85 { + padding-bottom: 85px; +} +.pb-90 { + padding-bottom: 90px; +} +.pb-95 { + padding-bottom: 95px; +} +.pb-100 { + padding-bottom: 100px; +} +.pb-105 { + padding-bottom: 105px; +} +.pb-110 { + padding-bottom: 110px; +} +.pb-115 { + padding-bottom: 115px; +} +.pb-120 { + padding-bottom: 120px; +} +.pb-125 { + padding-bottom: 125px; +} +.pb-130 { + padding-bottom: 130px; +} +.pb-135 { + padding-bottom: 135px; +} +.pb-140 { + padding-bottom: 140px; +} +.pb-145 { + padding-bottom: 145px; +} +.pb-150 { + padding-bottom: 150px; +} +.pb-155 { + padding-bottom: 155px; +} +.pb-160 { + padding-bottom: 160px; +} +.pb-165 { + padding-bottom: 165px; +} +.pb-170 { + padding-bottom: 170px; +} +.pb-175 { + padding-bottom: 175px; +} +.pb-180 { + padding-bottom: 180px; +} +.pb-185 { + padding-bottom: 185px; +} +.pb-190 { + padding-bottom: 190px; +} +.pb-195 { + padding-bottom: 195px; +} +.pb-200 { + padding-bottom: 200px; +} + +/*-- Padding left --*/ + +.pl-0 { + padding-left: 0px; +} +.pl-5 { + padding-left: 5px; +} +.pl-10 { + padding-left: 10px; +} +.pl-15 { + padding-left: 15px; +} +.pl-20 { + padding-left: 20px; +} +.pl-25 { + padding-left: 25px; +} +.pl-30 { + padding-left: 30px; +} +.pl-35 { + padding-left: 35px; +} +.pl-40 { + padding-left: 40px; +} +.pl-45 { + padding-left: 45px; +} +.pl-50 { + padding-left: 50px; +} +.pl-55 { + padding-left: 55px; +} +.pl-60 { + padding-left: 60px; +} +.pl-65 { + padding-left: 65px; +} +.pl-70 { + padding-left: 70px; +} +.pl-75 { + padding-left: 75px; +} +.pl-80 { + padding-left: 80px; +} +.pl-85 { + padding-left: 85px; +} +.pl-90 { + padding-left: 90px; +} +.pl-100 { + padding-left: 100px; +} +.pl-105 { + padding-left: 105px; +} +.pl-110 { + padding-left: 110px; +} +.pl-115 { + padding-left: 115px; +} +.pl-120 { + padding-left: 120px; +} +.pl-125 { + padding-left: 125px; +} +/*-- Padding right --*/ + +.pr-0 { + padding-right: 0px; +} +.pr-5 { + padding-right: 5px; +} +.pr-10 { + padding-right: 10px; +} +.pr-15 { + padding-right: 15px; +} +.pr-20 { + padding-right: 20px; +} +.pr-25 { + padding-right: 25px; +} +.pr-30 { + padding-right: 30px; +} +.pr-35 { + padding-right: 35px; +} +.pr-40 { + padding-right: 40px; +} +.pr-45 { + padding-right: 45px; +} +.pr-50 { + padding-right: 50px; +} +.pr-55 { + padding-right: 55px; +} +.pr-60 { + padding-right: 60px; +} +.pr-65 { + padding-right: 65px; +} +.pr-70 { + padding-right: 70px; +} +.pr-75 { + padding-right: 75px; +} +.pr-80 { + padding-right: 80px; +} +.pr-85 { + padding-right: 85px; +} +.pr-90 { + padding-right: 90px; +} +.pr-95 { + padding-right: 95px; +} +.pr-100 { + padding-right: 100px; +} +.pr-105 { + padding-right: 105px; +} +/* Background Color */ + +.gray-bg { + background: #f5f8ff; +} +.white-bg { + background: #fff; +} +.black-bg { + background: #222; +} +/* Color */ + +.white { + color: #fff; +} +.black { + color: #222; +} +/* black overlay */ + +[data-overlay] { + position: relative; +} +[data-overlay]::before { + background: #000 none repeat scroll 0 0; + content: ""; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + z-index: 1; +} +[data-overlay="3"]::before { + opacity: 0.3; +} +[data-overlay="4"]::before { + opacity: 0.4; +} +[data-overlay="5"]::before { + opacity: 0.5; +} +[data-overlay="6"]::before { + opacity: 0.6; +} +[data-overlay="7"]::before { + opacity: 0.7; +} +[data-overlay="8"]::before { + opacity: 0.8; +} +[data-overlay="9"]::before { + opacity: 0.9; +} \ No newline at end of file diff --git a/microsite-v2-templates/eventify/assets/css/flaticon.css b/microsite-v2-templates/eventify/assets/css/flaticon.css new file mode 100644 index 0000000..223832c --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/flaticon.css @@ -0,0 +1,40 @@ + /* + Flaticon icon font: Flaticon + Creation date: 17/07/2019 12:06 + */ + +@font-face { + font-family: "Flaticon"; + src: url("../fonts/Flaticon.eot"); + src: url("../fonts/Flaticon.eot%3F") format("embedded-opentype"), + url("../fonts/Flaticon.woff2") format("woff2"), + url("../fonts/Flaticon.woff") format("woff"), + url("../fonts/Flaticon.ttf") format("truetype"), + url("../fonts/Flaticon.svg") format("svg"); + font-weight: normal; + font-style: normal; +} + +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: "Flaticon"; + src: url("../fonts/Flaticon.svg") format("svg"); + } +} + +[class^="flaticon-"]:before, [class*=" flaticon-"]:before, +[class^="flaticon-"]:after, [class*=" flaticon-"]:after { + font-family: Flaticon; + font-style: normal; +} + +.flaticon-microphone:before { content: "\f100"; } +.flaticon-coffee-cup:before { content: "\f101"; } +.flaticon-chair:before { content: "\f102"; } +.flaticon-dollar-sing:before { content: "\f103"; } +.flaticon-karaoke:before { content: "\f104"; } +.flaticon-team:before { content: "\f105"; } +.flaticon-calendar:before { content: "\f106"; } +.flaticon-creative:before { content: "\f107"; } +.flaticon-network:before { content: "\f108"; } +.flaticon-laugh:before { content: "\f109"; } \ No newline at end of file diff --git a/microsite-v2-templates/eventify/assets/css/magnific-popup.css b/microsite-v2-templates/eventify/assets/css/magnific-popup.css new file mode 100644 index 0000000..8561e18 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/magnific-popup.css @@ -0,0 +1,351 @@ +/* Magnific Popup CSS */ +.mfp-bg { + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1042; + overflow: hidden; + position: fixed; + background: #0b0b0b; + opacity: 0.8; } + +.mfp-wrap { + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1043; + position: fixed; + outline: none !important; + -webkit-backface-visibility: hidden; } + +.mfp-container { + text-align: center; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + padding: 0 8px; + box-sizing: border-box; } + +.mfp-container:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; } + +.mfp-align-top .mfp-container:before { + display: none; } + +.mfp-content { + position: relative; + display: inline-block; + vertical-align: middle; + margin: 0 auto; + text-align: left; + z-index: 1045; } + +.mfp-inline-holder .mfp-content, +.mfp-ajax-holder .mfp-content { + width: 100%; + cursor: auto; } + +.mfp-ajax-cur { + cursor: progress; } + +.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { + cursor: -moz-zoom-out; + cursor: -webkit-zoom-out; + cursor: zoom-out; } + +.mfp-zoom { + cursor: pointer; + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; + cursor: zoom-in; } + +.mfp-auto-cursor .mfp-content { + cursor: auto; } + +.mfp-close, +.mfp-arrow, +.mfp-preloader, +.mfp-counter { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; } + +.mfp-loading.mfp-figure { + display: none; } + +.mfp-hide { + display: none !important; } + +.mfp-preloader { + color: #CCC; + position: absolute; + top: 50%; + width: auto; + text-align: center; + margin-top: -0.8em; + left: 8px; + right: 8px; + z-index: 1044; } + .mfp-preloader a { + color: #CCC; } + .mfp-preloader a:hover { + color: #FFF; } + +.mfp-s-ready .mfp-preloader { + display: none; } + +.mfp-s-error .mfp-content { + display: none; } + +button.mfp-close, +button.mfp-arrow { + overflow: visible; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + display: block; + outline: none; + padding: 0; + z-index: 1046; + box-shadow: none; + touch-action: manipulation; } + +button::-moz-focus-inner { + padding: 0; + border: 0; } + +.mfp-close { + width: 44px; + height: 44px; + line-height: 44px; + position: absolute; + right: 0; + top: 0; + text-decoration: none; + text-align: center; + opacity: 0.65; + padding: 0 0 18px 10px; + color: #FFF; + font-style: normal; + font-size: 28px; + font-family: Arial, Baskerville, monospace; } + .mfp-close:hover, + .mfp-close:focus { + opacity: 1; } + .mfp-close:active { + top: 1px; } + +.mfp-close-btn-in .mfp-close { + color: #333; } + +.mfp-image-holder .mfp-close, +.mfp-iframe-holder .mfp-close { + color: #FFF; + right: -6px; + text-align: right; + padding-right: 6px; + width: 100%; } + +.mfp-counter { + position: absolute; + top: 0; + right: 0; + color: #CCC; + font-size: 12px; + line-height: 18px; + white-space: nowrap; } + +.mfp-arrow { + position: absolute; + opacity: 0.65; + margin: 0; + top: 50%; + margin-top: -55px; + padding: 0; + width: 90px; + height: 110px; + -webkit-tap-highlight-color: transparent; } + .mfp-arrow:active { + margin-top: -54px; } + .mfp-arrow:hover, + .mfp-arrow:focus { + opacity: 1; } + .mfp-arrow:before, + .mfp-arrow:after { + content: ''; + display: block; + width: 0; + height: 0; + position: absolute; + left: 0; + top: 0; + margin-top: 35px; + margin-left: 35px; + border: medium inset transparent; } + .mfp-arrow:after { + border-top-width: 13px; + border-bottom-width: 13px; + top: 8px; } + .mfp-arrow:before { + border-top-width: 21px; + border-bottom-width: 21px; + opacity: 0.7; } + +.mfp-arrow-left { + left: 0; } + .mfp-arrow-left:after { + border-right: 17px solid #FFF; + margin-left: 31px; } + .mfp-arrow-left:before { + margin-left: 25px; + border-right: 27px solid #3F3F3F; } + +.mfp-arrow-right { + right: 0; } + .mfp-arrow-right:after { + border-left: 17px solid #FFF; + margin-left: 39px; } + .mfp-arrow-right:before { + border-left: 27px solid #3F3F3F; } + +.mfp-iframe-holder { + padding-top: 40px; + padding-bottom: 40px; } + .mfp-iframe-holder .mfp-content { + line-height: 0; + width: 100%; + max-width: 900px; } + .mfp-iframe-holder .mfp-close { + top: -40px; } + +.mfp-iframe-scaler { + width: 100%; + height: 0; + overflow: hidden; + padding-top: 56.25%; } + .mfp-iframe-scaler iframe { + position: absolute; + display: block; + top: 0; + left: 0; + width: 100%; + height: 100%; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); + background: #000; } + +/* Main image in popup */ +img.mfp-img { + width: auto; + max-width: 100%; + height: auto; + display: block; + line-height: 0; + box-sizing: border-box; + padding: 40px 0 40px; + margin: 0 auto; } + +/* The shadow behind the image */ +.mfp-figure { + line-height: 0; } + .mfp-figure:after { + content: ''; + position: absolute; + left: 0; + top: 40px; + bottom: 40px; + display: block; + right: 0; + width: auto; + height: auto; + z-index: -1; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); + background: #444; } + .mfp-figure small { + color: #BDBDBD; + display: block; + font-size: 12px; + line-height: 14px; } + .mfp-figure figure { + margin: 0; } + +.mfp-bottom-bar { + margin-top: -36px; + position: absolute; + top: 100%; + left: 0; + width: 100%; + cursor: auto; } + +.mfp-title { + text-align: left; + line-height: 18px; + color: #F3F3F3; + word-wrap: break-word; + padding-right: 36px; } + +.mfp-image-holder .mfp-content { + max-width: 100%; } + +.mfp-gallery .mfp-image-holder .mfp-figure { + cursor: pointer; } + +@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { + /** + * Remove all paddings around the image on small screen + */ + .mfp-img-mobile .mfp-image-holder { + padding-left: 0; + padding-right: 0; } + .mfp-img-mobile img.mfp-img { + padding: 0; } + .mfp-img-mobile .mfp-figure:after { + top: 0; + bottom: 0; } + .mfp-img-mobile .mfp-figure small { + display: inline; + margin-left: 5px; } + .mfp-img-mobile .mfp-bottom-bar { + background: rgba(0, 0, 0, 0.6); + bottom: 0; + margin: 0; + top: auto; + padding: 3px 5px; + position: fixed; + box-sizing: border-box; } + .mfp-img-mobile .mfp-bottom-bar:empty { + padding: 0; } + .mfp-img-mobile .mfp-counter { + right: 5px; + top: 3px; } + .mfp-img-mobile .mfp-close { + top: 0; + right: 0; + width: 35px; + height: 35px; + line-height: 35px; + background: rgba(0, 0, 0, 0.6); + position: fixed; + text-align: center; + padding: 0; } } + +@media all and (max-width: 900px) { + .mfp-arrow { + -webkit-transform: scale(0.75); + transform: scale(0.75); } + .mfp-arrow-left { + -webkit-transform-origin: 0; + transform-origin: 0; } + .mfp-arrow-right { + -webkit-transform-origin: 100%; + transform-origin: 100%; } + .mfp-container { + padding-left: 6px; + padding-right: 6px; } } diff --git a/microsite-v2-templates/eventify/assets/css/slick.css b/microsite-v2-templates/eventify/assets/css/slick.css new file mode 100644 index 0000000..57477e8 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/slick.css @@ -0,0 +1,119 @@ +/* Slider */ +.slick-slider +{ + position: relative; + + display: block; + box-sizing: border-box; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + -webkit-touch-callout: none; + -khtml-user-select: none; + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-tap-highlight-color: transparent; +} + +.slick-list +{ + position: relative; + + display: block; + overflow: hidden; + + margin: 0; + padding: 0; +} +.slick-list:focus +{ + outline: none; +} +.slick-list.dragging +{ + cursor: pointer; + cursor: hand; +} + +.slick-slider .slick-track, +.slick-slider .slick-list +{ + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.slick-track +{ + position: relative; + top: 0; + left: 0; + + display: block; + margin-left: auto; + margin-right: auto; +} +.slick-track:before, +.slick-track:after +{ + display: table; + + content: ''; +} +.slick-track:after +{ + clear: both; +} +.slick-loading .slick-track +{ + visibility: hidden; +} + +.slick-slide +{ + display: none; + float: left; + + height: 100%; + min-height: 1px; +} +[dir='rtl'] .slick-slide +{ + float: right; +} +.slick-slide img +{ + display: block; +} +.slick-slide.slick-loading img +{ + display: none; +} +.slick-slide.dragging img +{ + pointer-events: none; +} +.slick-initialized .slick-slide +{ + display: block; +} +.slick-loading .slick-slide +{ + visibility: hidden; +} +.slick-vertical .slick-slide +{ + display: block; + + height: auto; + + border: 1px solid transparent; +} +.slick-arrow.slick-hidden { + display: none; +} diff --git a/microsite-v2-templates/eventify/assets/css/style.css b/microsite-v2-templates/eventify/assets/css/style.css new file mode 100644 index 0000000..d886bd8 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/css/style.css @@ -0,0 +1,1511 @@ +/*----------------------------------------------------------------------------------- + + Template Name: Eventify - Event and Conference Template + Template URI: graygrids.com + Description: Eventify - Event and Conference Template + Author: GrayGrids + Author URI: graygrids.com + Version: 1.0 + +----------------------------------------------------------------------------------- + + CSS INDEX + =================== + + 01. Theme default CSS + 02. Header + 03. Hero + 04. Footer + +-----------------------------------------------------------------------------------*/ +/*=========================== + 1. COMMON css +===========================*/ +@import url("https://fonts.googleapis.com/css?family=Poppins:400,500,600,700,800"); +body { + font-family: "Poppins", sans-serif; + font-weight: normal; + font-style: normal; + color: #777777; + overflow-x: hidden; } + +* { + margin: 0; + padding: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } + +img { + max-width: 100%; } + +a:focus, +input:focus, +textarea:focus, +button:focus { + text-decoration: none; + outline: none; } + +a:focus, +a:hover { + text-decoration: none; } + +i, +span, +a { + display: inline-block; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Poppins", sans-serif; + font-weight: 600; + color: #1b273d; + margin: 0px; } + +h1 { + font-size: 48px; } + +h2 { + font-size: 36px; } + +h3 { + font-size: 28px; } + +h4 { + font-size: 22px; } + +h5 { + font-size: 18px; } + +h6 { + font-size: 16px; } + +ul, ol { + margin: 0px; + padding: 0px; + list-style-type: none; } + +p { + font-size: 16px; + font-weight: 400; + line-height: 24px; + color: #777777; + margin: 0px; } + +.bg_cover { + background-position: center center; + background-size: cover; + background-repeat: no-repeat; + width: 100%; + height: 100%; } + +/*===== All Button Style =====*/ +.main-btn { + display: inline-block; + font-weight: 500; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + padding: 0 40px; + font-size: 16px; + line-height: 48px; + border-radius: 50px; + color: var(--primarycolor); + cursor: pointer; + z-index: 5; + -webkit-transition: all 0.4s ease-out 0s; + -moz-transition: all 0.4s ease-out 0s; + -ms-transition: all 0.4s ease-out 0s; + -o-transition: all 0.4s ease-out 0s; + transition: all 0.4s ease-out 0s; + background-color: #fff; + border: 0; } + .main-btn:hover { + background-color: #fff; + color: var(--primarycolor); + -webkit-box-shadow: 0px 5px 29px 0px rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0px 5px 29px 0px rgba(0, 0, 0, 0.25); + box-shadow: 0px 5px 29px 0px rgba(0, 0, 0, 0.25); } + .main-btn.main-btn-2 { + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background-size: 200% auto; + color: #fff; + background-position: left center; + -webkit-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.23); + -moz-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.23); + box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.23); } + .main-btn.main-btn-2:hover { + background-position: right center; + color: #fff; } + +/*===== All Section Title Style =====*/ +.section-title .title { + font-size: 50px; } + @media (max-width: 767px) { + .section-title .title { + font-size: 30px; } } + +.section-title .text { + margin-top: 20px; } + +/*===== All Preloader Style =====*/ +.preloader { + /* Body Overlay */ + position: fixed; + top: 0; + left: 0; + display: table; + height: 100%; + width: 100%; + /* Change Background Color */ + background: #fff; + z-index: 99999; } + .preloader .loader { + display: table-cell; + vertical-align: middle; + text-align: center; } + .preloader .loader .ytp-spinner { + position: absolute; + left: 50%; + top: 50%; + width: 64px; + margin-left: -32px; + z-index: 18; + pointer-events: none; } + .preloader .loader .ytp-spinner .ytp-spinner-container { + pointer-events: none; + position: absolute; + width: 100%; + padding-bottom: 100%; + top: 50%; + left: 50%; + margin-top: -50%; + margin-left: -50%; + -webkit-animation: ytp-spinner-linspin 1568.23529647ms linear infinite; + -moz-animation: ytp-spinner-linspin 1568.23529647ms linear infinite; + -o-animation: ytp-spinner-linspin 1568.23529647ms linear infinite; + animation: ytp-spinner-linspin 1568.23529647ms linear infinite; } + .preloader .loader .ytp-spinner .ytp-spinner-container .ytp-spinner-rotator { + position: absolute; + width: 100%; + height: 100%; + -webkit-animation: ytp-spinner-easespin 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + -moz-animation: ytp-spinner-easespin 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + -o-animation: ytp-spinner-easespin 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: ytp-spinner-easespin 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; } + .preloader .loader .ytp-spinner .ytp-spinner-container .ytp-spinner-rotator .ytp-spinner-left { + position: absolute; + top: 0; + left: 0; + bottom: 0; + overflow: hidden; + right: 50%; } + .preloader .loader .ytp-spinner .ytp-spinner-container .ytp-spinner-rotator .ytp-spinner-right { + position: absolute; + top: 0; + right: 0; + bottom: 0; + overflow: hidden; + left: 50%; } + .preloader .loader .ytp-spinner-circle { + box-sizing: border-box; + position: absolute; + width: 200%; + height: 100%; + border-style: solid; + /* Spinner Color */ + border-color: var(--primarycolor) var(--primarycolor) #e6e6e6; + border-radius: 50%; + border-width: 6px; } + .preloader .loader .ytp-spinner-left .ytp-spinner-circle { + left: 0; + right: -100%; + border-right-color: #e6e6e6; + -webkit-animation: ytp-spinner-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + -moz-animation: ytp-spinner-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + -o-animation: ytp-spinner-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: ytp-spinner-left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; } + .preloader .loader .ytp-spinner-right .ytp-spinner-circle { + left: -100%; + right: 0; + border-left-color: #e6e6e6; + -webkit-animation: ytp-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + -moz-animation: ytp-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + -o-animation: ytp-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: ytp-right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; } + +/* Preloader Animations */ +@-webkit-keyframes ytp-spinner-linspin { + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes ytp-spinner-linspin { + to { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); } } + +@-webkit-keyframes ytp-spinner-easespin { + 12.5% { + -webkit-transform: rotate(135deg); + -moz-transform: rotate(135deg); + -ms-transform: rotate(135deg); + -o-transform: rotate(135deg); + transform: rotate(135deg); } + 25% { + -webkit-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -ms-transform: rotate(270deg); + -o-transform: rotate(270deg); + transform: rotate(270deg); } + 37.5% { + -webkit-transform: rotate(405deg); + -moz-transform: rotate(405deg); + -ms-transform: rotate(405deg); + -o-transform: rotate(405deg); + transform: rotate(405deg); } + 50% { + -webkit-transform: rotate(540deg); + -moz-transform: rotate(540deg); + -ms-transform: rotate(540deg); + -o-transform: rotate(540deg); + transform: rotate(540deg); } + 62.5% { + -webkit-transform: rotate(675deg); + -moz-transform: rotate(675deg); + -ms-transform: rotate(675deg); + -o-transform: rotate(675deg); + transform: rotate(675deg); } + 75% { + -webkit-transform: rotate(810deg); + -moz-transform: rotate(810deg); + -ms-transform: rotate(810deg); + -o-transform: rotate(810deg); + transform: rotate(810deg); } + 87.5% { + -webkit-transform: rotate(945deg); + -moz-transform: rotate(945deg); + -ms-transform: rotate(945deg); + -o-transform: rotate(945deg); + transform: rotate(945deg); } + to { + -webkit-transform: rotate(1080deg); + -moz-transform: rotate(1080deg); + -ms-transform: rotate(1080deg); + -o-transform: rotate(1080deg); + transform: rotate(1080deg); } } + +@keyframes ytp-spinner-easespin { + 12.5% { + -webkit-transform: rotate(135deg); + -moz-transform: rotate(135deg); + -ms-transform: rotate(135deg); + -o-transform: rotate(135deg); + transform: rotate(135deg); } + 25% { + -webkit-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -ms-transform: rotate(270deg); + -o-transform: rotate(270deg); + transform: rotate(270deg); } + 37.5% { + -webkit-transform: rotate(405deg); + -moz-transform: rotate(405deg); + -ms-transform: rotate(405deg); + -o-transform: rotate(405deg); + transform: rotate(405deg); } + 50% { + -webkit-transform: rotate(540deg); + -moz-transform: rotate(540deg); + -ms-transform: rotate(540deg); + -o-transform: rotate(540deg); + transform: rotate(540deg); } + 62.5% { + -webkit-transform: rotate(675deg); + -moz-transform: rotate(675deg); + -ms-transform: rotate(675deg); + -o-transform: rotate(675deg); + transform: rotate(675deg); } + 75% { + -webkit-transform: rotate(810deg); + -moz-transform: rotate(810deg); + -ms-transform: rotate(810deg); + -o-transform: rotate(810deg); + transform: rotate(810deg); } + 87.5% { + -webkit-transform: rotate(945deg); + -moz-transform: rotate(945deg); + -ms-transform: rotate(945deg); + -o-transform: rotate(945deg); + transform: rotate(945deg); } + to { + -webkit-transform: rotate(1080deg); + -moz-transform: rotate(1080deg); + -ms-transform: rotate(1080deg); + -o-transform: rotate(1080deg); + transform: rotate(1080deg); } } + +@-webkit-keyframes ytp-spinner-left-spin { + 0% { + -webkit-transform: rotate(130deg); + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + transform: rotate(130deg); } + 50% { + -webkit-transform: rotate(-5deg); + -moz-transform: rotate(-5deg); + -ms-transform: rotate(-5deg); + -o-transform: rotate(-5deg); + transform: rotate(-5deg); } + to { + -webkit-transform: rotate(130deg); + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + transform: rotate(130deg); } } + +@keyframes ytp-spinner-left-spin { + 0% { + -webkit-transform: rotate(130deg); + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + transform: rotate(130deg); } + 50% { + -webkit-transform: rotate(-5deg); + -moz-transform: rotate(-5deg); + -ms-transform: rotate(-5deg); + -o-transform: rotate(-5deg); + transform: rotate(-5deg); } + to { + -webkit-transform: rotate(130deg); + -moz-transform: rotate(130deg); + -ms-transform: rotate(130deg); + -o-transform: rotate(130deg); + transform: rotate(130deg); } } + +@-webkit-keyframes ytp-right-spin { + 0% { + -webkit-transform: rotate(-130deg); + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + transform: rotate(-130deg); } + 50% { + -webkit-transform: rotate(5deg); + -moz-transform: rotate(5deg); + -ms-transform: rotate(5deg); + -o-transform: rotate(5deg); + transform: rotate(5deg); } + to { + -webkit-transform: rotate(-130deg); + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + transform: rotate(-130deg); } } + +@keyframes ytp-right-spin { + 0% { + -webkit-transform: rotate(-130deg); + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + transform: rotate(-130deg); } + 50% { + -webkit-transform: rotate(5deg); + -moz-transform: rotate(5deg); + -ms-transform: rotate(5deg); + -o-transform: rotate(5deg); + transform: rotate(5deg); } + to { + -webkit-transform: rotate(-130deg); + -moz-transform: rotate(-130deg); + -ms-transform: rotate(-130deg); + -o-transform: rotate(-130deg); + transform: rotate(-130deg); } } + +/*=========================== + 2.HEADER css +===========================*/ +.header-area { + padding-left: 15px; + padding-right: 15px; } + @media (max-width: 767px) { + .header-area { + padding: 0; } } + +/*===== Navbar =====*/ +.navbar-area { + padding: 10px 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: 999; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .navbar-area::before { + position: absolute; + content: ''; + width: 100%; + height: 100%; + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + top: 0; + left: 0; + z-index: -1; + opacity: 0; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .navbar-area.sticky { + position: fixed; + z-index: 999; } + .navbar-area.sticky::before { + opacity: 1; } + .navbar-area .navbar { + position: relative; + padding: 0; } + .navbar-area .navbar .navbar-toggler .toggler-icon { + width: 30px; + height: 2px; + background-color: #fff; + margin: 5px 0; + display: block; + position: relative; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .navbar-area .navbar .navbar-toggler.active .toggler-icon:nth-of-type(1) { + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + top: 7px; } + .navbar-area .navbar .navbar-toggler.active .toggler-icon:nth-of-type(2) { + opacity: 0; } + .navbar-area .navbar .navbar-toggler.active .toggler-icon:nth-of-type(3) { + -webkit-transform: rotate(135deg); + -moz-transform: rotate(135deg); + -ms-transform: rotate(135deg); + -o-transform: rotate(135deg); + transform: rotate(135deg); + top: -7px; } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .navbar-area .navbar .navbar-collapse { + position: absolute; + top: 116%; + left: 0; + width: 100%; + background-color: var(--primarycolor); + z-index: 8; } } + @media (max-width: 767px) { + .navbar-area .navbar .navbar-collapse { + position: absolute; + top: 116%; + left: 0; + width: 100%; + background-color: var(--primarycolor); + z-index: 8; } } + .navbar-area .navbar .navbar-nav .nav-item { + margin: 0 16px; + position: relative; } + .navbar-area .navbar .navbar-nav .nav-item a { + font-size: 16px; + line-height: 24px; + font-weight: 500; + padding: 26px 0; + color: #fff; + position: relative; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .navbar-area .navbar .navbar-nav .nav-item a::before { + position: absolute; + content: ''; + width: 0; + height: 2px; + background-color: #fff; + left: 0; + bottom: 20px; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .navbar-area .navbar .navbar-nav .nav-item a::before { + display: none; } } + @media (max-width: 767px) { + .navbar-area .navbar .navbar-nav .nav-item a::before { + display: none; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .navbar-area .navbar .navbar-nav .nav-item a { + padding: 10px 0; + display: block; } } + @media (max-width: 767px) { + .navbar-area .navbar .navbar-nav .nav-item a { + padding: 10px 0; + display: block; } } + .navbar-area .navbar .navbar-nav .nav-item.active > a::before, .navbar-area .navbar .navbar-nav .nav-item:hover > a::before { + width: 100%; } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .navbar-area .navbar .navbar-btn { + position: absolute; + right: 70px; + top: 7px; } } + @media (max-width: 767px) { + .navbar-area .navbar .navbar-btn { + position: absolute; + right: 60px; + top: 7px; } } + .navbar-area .navbar .navbar-btn .main-btn:hover { + background-color: #fff; + color: var(--primarycolor); } + +/*===== Header =====*/ +.header-content-area { + height: 750px; + border-bottom-left-radius: 30px; + border-bottom-right-radius: 30px; + position: relative; + overflow: hidden; } + @media only screen and (min-width: 1400px) { + .header-content-area { + height: 850px; } } + @media (max-width: 767px) { + .header-content-area { + height: 650px; } } + @media only screen and (min-width: 576px) and (max-width: 767px) { + .header-content-area { + height: 550px; } } + .header-content-area::before { + position: absolute; + content: ''; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: -webkit-linear-gradient( + left, + color-mix(in srgb, var(--primarycolor) 20%, transparent) 0%, + color-mix(in srgb, var(--primarycolor) 20%, transparent) 100% +); +background: -o-linear-gradient( + left, + color-mix(in srgb, var(--primarycolor) 20%, transparent) 0%, + color-mix(in srgb, var(--primarycolor) 20%, transparent) 100% +); +background: linear-gradient( + to right, + color-mix(in srgb, var(--primarycolor) 20%, transparent) 0%, + color-mix(in srgb, var(--primarycolor) 20%, transparent) 100% +); } + +.header-countdown .single-count-content { + padding: 0 45px; + text-align: center; } + @media (max-width: 767px) { + .header-countdown .single-count-content { + padding: 0 10px; } } + @media only screen and (min-width: 576px) and (max-width: 767px) { + .header-countdown .single-count-content { + padding: 0 15px; } } + .header-countdown .single-count-content .count { + font-size: 72px; + font-weight: 600; + line-height: 60px; } + @media (max-width: 767px) { + .header-countdown .single-count-content .count { + font-size: 24px; + line-height: 30px; } } + @media only screen and (min-width: 576px) and (max-width: 767px) { + .header-countdown .single-count-content .count { + font-size: 36px; + line-height: 40px; } } + .header-countdown .single-count-content .text { + font-size: 20px; + font-weight: 600; + margin-top: 10px; } + @media (max-width: 767px) { + .header-countdown .single-count-content .text { + font-size: 14px; + margin-top: 0; } } + @media only screen and (min-width: 576px) and (max-width: 767px) { + .header-countdown .single-count-content .text { + font-size: 18px; + margin-top: 0; } } + .header-countdown .single-count-content.count-color-1 .count, + .header-countdown .single-count-content.count-color-1 .text { + color: #ee163a; } + .header-countdown .single-count-content.count-color-2 .count, + .header-countdown .single-count-content.count-color-2 .text { + color: #ffc107; } + .header-countdown .single-count-content.count-color-3 .count, + .header-countdown .single-count-content.count-color-3 .text { + color: #03a9f4; } + .header-countdown .single-count-content.count-color-4 .count, + .header-countdown .single-count-content.count-color-4 .text { + color: #8bc34a; } + +.header-content { + margin-top: 60px; } + .header-content .header-title { + font-size: 75px; + color: #fff; + text-transform: uppercase; } + @media only screen and (min-width: 992px) and (max-width: 1200px) { + .header-content .header-title { + font-size: 60px; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .header-content .header-title { + font-size: 54px; } } + @media (max-width: 767px) { + .header-content .header-title { + font-size: 30px; } } + .header-content .sub-title { + font-size: 30px; + font-weight: 500; + color: #fff; + text-transform: uppercase; + margin-top: 22px; } + @media (max-width: 767px) { + .header-content .sub-title { + font-size: 20px; } } + .header-content .header-btn { + padding-top: 50px; } + .header-content .header-btn li { + display: inline-block; + margin: 10px 13px 0; } + +/*=========================== + 3.ABOUT css +===========================*/ +.about-image img { + width: 100%; } +.about-content .date { + font-size: 18px; + font-weight: 600; + color: #1b273d; + margin-top: 45px; } + .about-content .date span { + font-size: 30px; + color: var(--primarycolor); + position: relative; + padding-left: 15px; } + .about-content .date span::before { + position: absolute; + content: ''; + width: 55px; + height: 55px; + border: 6px solid rgba(24, 99, 255, 0.18); + top: -18px; + left: 0; } + +/*=========================== + 4.COUNTER css +===========================*/ +.counter-area { + background-image: url(../images/dots.jpg); + background-repeat: repeat; } + +.single-counter { + background-color: #f5f8ff; + border: 2px solid #e6e6e6; + padding: 0 15px 15px; } + .single-counter .counter-icon { + position: relative; + margin-top: -50px; } + .single-counter .counter-icon i { + font-size: 65px; + color: var(--primarycolor); + background-color: #f5f8ff; + border: 2px solid #e6e6e6; + width: 100px; + height: 100px; + line-height: 100px; + border-radius: 50%; } + .single-counter .counter-content .count { + font-size: 45px; + color: var(--primarycolor); + font-weight: 600; + margin-top: 5px; } + .single-counter .counter-content .text { + font-weight: 500; } + +/*=========================== + 5.EVENT SCHEDULE css +===========================*/ +.event-tab { + border: 3px solid rgba(24, 99, 255, 0.1); + padding: 40px 70px; } + @media only screen and (min-width: 992px) and (max-width: 1200px) { + .event-tab { + padding: 40px; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab { + padding: 30px; } } + @media (max-width: 767px) { + .event-tab { + padding: 10px; + padding-top: 0; } } + @media (max-width: 767px) { + .event-tab .nav .nav-item { + width: 48%; + margin-top: 10px; } } + .event-tab .nav .nav-item a { + text-align: center; + width: 225px; + border: 3px solid rgba(24, 99, 255, 0.1); + padding: 15px 0; + position: relative; + z-index: 5; } + @media only screen and (min-width: 992px) and (max-width: 1200px) { + .event-tab .nav .nav-item a { + width: 200px; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .nav .nav-item a { + width: 150px; + padding: 10px 0; } } + @media (max-width: 767px) { + .event-tab .nav .nav-item a { + width: 100%; + padding: 10px 0; } } + .event-tab .nav .nav-item a .nav-title { + text-transform: uppercase; + font-size: 24px; + font-weight: 600; + color: #777777; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .nav .nav-item a .nav-title { + font-size: 18px; } } + @media (max-width: 767px) { + .event-tab .nav .nav-item a .nav-title { + font-size: 18px; } } + .event-tab .nav .nav-item a span { + font-size: 16px; + color: #777777; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .nav .nav-item a span { + font-size: 14px; } } + @media (max-width: 767px) { + .event-tab .nav .nav-item a span { + font-size: 14px; } } + .event-tab .nav .nav-item a::before { + position: absolute; + content: ''; + width: 100%; + height: 100%; + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + top: 0; + left: 0; + z-index: -1; + opacity: 0; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .event-tab .nav .nav-item a.active { + border-color: transparent; + padding: 18px 0; } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .nav .nav-item a.active { + padding: 13px 0; } } + @media (max-width: 767px) { + .event-tab .nav .nav-item a.active { + padding: 13px 0; } } + .event-tab .nav .nav-item a.active .nav-title, + .event-tab .nav .nav-item a.active span { + color: #fff; } + .event-tab .nav .nav-item a.active::before { + opacity: 1; } + .event-tab .tab-content .event-content .single-event { + padding: 40px; + z-index: 5; + position: relative; + background-color: #f5f8ff; } + @media only screen and (min-width: 992px) and (max-width: 1200px) { + .event-tab .tab-content .event-content .single-event { + padding: 20px; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .tab-content .event-content .single-event { + padding: 15px; } } + @media (max-width: 767px) { + .event-tab .tab-content .event-content .single-event { + padding: 15px; } } + .event-tab .tab-content .event-content .single-event::before { + position: absolute; + content: ''; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + z-index: -1; + opacity: 0; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media (max-width: 767px) { + .event-tab .tab-content .event-content .single-event .event-image img { + width: 100%; } } + .event-tab .tab-content .event-content .single-event .event-content { + padding-left: 30px; } + @media only screen and (min-width: 992px) and (max-width: 1200px) { + .event-tab .tab-content .event-content .single-event .event-content { + padding-left: 20px; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .tab-content .event-content .single-event .event-content { + padding-left: 15px; } } + @media (max-width: 767px) { + .event-tab .tab-content .event-content .single-event .event-content { + padding-left: 0; + margin-top: 15px; } } + .event-tab .tab-content .event-content .single-event .event-content .event-title { + font-size: 24px; } + @media (max-width: 767px) { + .event-tab .tab-content .event-content .single-event .event-content .event-title { + font-size: 18px; } } + .event-tab .tab-content .event-content .single-event .event-content .text { + margin-top: 20px; } + .event-tab .tab-content .event-content .single-event .event-content .event-meta { + padding-top: 10px; } + .event-tab .tab-content .event-content .single-event .event-content .event-meta li { + display: inline-block; + padding-top: 10px; + font-size: 16px; + color: #777777; + margin-right: 20px; } + @media only screen and (min-width: 992px) and (max-width: 1200px) { + .event-tab .tab-content .event-content .single-event .event-content .event-meta li { + font-size: 14px; + margin-right: 10px; } } + @media only screen and (min-width: 768px) and (max-width: 991px) { + .event-tab .tab-content .event-content .single-event .event-content .event-meta li { + font-size: 14px; } } + .event-tab .tab-content .event-content .single-event .event-content .event-meta li:last-child li { + margin-right: 0; } + .event-tab .tab-content .event-content .single-event:hover::before { + opacity: 1; } + .event-tab .tab-content .event-content .single-event:hover .event-content .event-title, + .event-tab .tab-content .event-content .single-event:hover .event-content .text { + color: #fff; } + .event-tab .tab-content .event-content .single-event:hover .event-content .event-meta li { + color: #fff; } + +/*=========================== + 6.FEATURES css +===========================*/ +.single-features { + -webkit-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + -moz-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + background-color: #fff; + padding: 45px 20px; + border-top-right-radius: 30px; + border-bottom-left-radius: 30px; + position: relative; + z-index: 5; + overflow: hidden; } + .single-features::before { + position: absolute; + content: ''; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + z-index: -1; + opacity: 0; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-features .features-icon { + position: relative; + display: inline-block; } + .single-features .features-icon i { + font-size: 75px; + color: var(--primarycolor); + position: absolute; + top: 50%; + left: 50%; + z-index: 5; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-features .features-icon span { + font-size: 124px; + color: #1b273d; + line-height: 100px; + opacity: 0.08; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; + font-weight: 600; } + .single-features .features-content { + padding-top: 5px; + position: relative; + z-index: 9; } + .single-features .features-content .features-title a { + font-size: 24px; + color: #1b273d; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-features .features-content .text { + margin-top: 25px; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-features:hover::before { + opacity: 1; } + .single-features:hover .features-icon i, + .single-features:hover .features-icon span { + color: #fff; } + .single-features:hover .features-content .features-title a { + color: #fff; } + .single-features:hover .features-content .text { + color: #fff; } + +/*=========================== + 6.TEAM css +===========================*/ +.single-team { + position: relative; + -webkit-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + -moz-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); } + .single-team .team-image img { + width: 100%; } + .single-team .team-content { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + background-color: #fff; + padding-top: 25px; + padding-bottom: 25px; + z-index: 5; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media (max-width: 767px) { + .single-team .team-content { + padding-top: 15px; + padding-bottom: 15px; } } + .single-team .team-content::before { + position: absolute; + content: ''; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 100%); + z-index: -1; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; + opacity: 0; } + .single-team .team-content .team-social { + position: absolute; + top: 0; + left: 0; + width: 100%; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; + visibility: hidden; + opacity: 0; } + .single-team .team-content .team-social .social { + background-color: #fff; + display: inline-block; + padding: 10px 20px 6px; + border-radius: 50px; } + .single-team .team-content .team-social .social li { + display: inline-block; + margin: 0 8px; } + .single-team .team-content .team-social .social li a { + font-size: 16px; + color: #777777; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-team .team-content .team-social .social li a:hover { + color: var(--primarycolor); } + .single-team .team-content .team-name a { + color: #1b273d; + font-size: 24px; + font-weight: 600; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media (max-width: 767px) { + .single-team .team-content .team-name a { + font-size: 18px; } } + .single-team .team-content .sub-title { + font-size: 16px; + color: var(--primarycolor); + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + @media (max-width: 767px) { + .single-team .team-content .sub-title { + font-size: 14px; } } + .single-team:hover .team-content { + padding-top: 50px; } + @media (max-width: 767px) { + .single-team:hover .team-content { + padding-top: 35px; } } + .single-team:hover .team-content::before { + opacity: 1; } + .single-team:hover .team-content .team-social { + top: -20px; + visibility: visible; + opacity: 1; } + .single-team:hover .team-content .team-name a { + color: #fff; } + .single-team:hover .team-content .sub-title { + color: #fff; } + +/*=========================== + 7.GALLERY css +===========================*/ +.single-gallery { + position: relative; } + .single-gallery .gallery-image img { + width: 100%; } + .single-gallery .gallery-image::before { + position: absolute; + content: ''; + top: 0; + left: 0; + background-color: var(--primarycolor); + opacity: 0.9; + width: 100%; + height: 100%; + -webkit-transform: scale(0.9); + -moz-transform: scale(0.9); + -ms-transform: scale(0.9); + -o-transform: scale(0.9); + transform: scale(0.9); + opacity: 0; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-gallery .gallery-content { + position: absolute; + position: absolute; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -moz-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + -o-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + opacity: 0; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-gallery .gallery-content a { + color: #fff; + font-size: 140px; } + .single-gallery:hover .gallery-image::before { + opacity: 1; } + .single-gallery:hover .gallery-content { + opacity: 1; } + +/*=========================== + 8.PRICING css +===========================*/ +.single-pricing { + border: 3px solid rgba(24, 99, 255, 0.1); + padding: 50px 30px; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .single-pricing .pricing-name .pricing-title { + font-size: 24px; + text-transform: uppercase; } + .single-pricing .pricing-name .sub-title { + font-size: 16px; + color: #777777; + margin-top: 10px; } + .single-pricing .pricing-price { + background-image: url(../images/pricing-bg.jpg); + background-position: center center; + background-size: cover; + position: relative; + z-index: 5; + padding: 20px 0 30px; + border-radius: 8px; + overflow: hidden; + margin-top: 35px; } + .single-pricing .pricing-price::before { + position: absolute; + content: ''; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-color: var(--primarycolor); +opacity: 0.85; + z-index: -1; } + .single-pricing .pricing-price span { + font-size: 36px; + font-weight: 600; + color: #fff; } + .single-pricing .pricing-price .text { + color: #fff; } + .single-pricing .pricing-list { + padding-top: 15px; } + .single-pricing .pricing-list ul li { + font-size: 16px; + color: #777777; + margin-top: 15px; } + .single-pricing .pricing-btn { + padding-top: 30px; } + .single-pricing .pricing-btn .main-btn { + border: 2px solid rgba(24, 99, 255, 0.1); } + .single-pricing .pricing-btn .main-btn:hover { + -webkit-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + -moz-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); } + .single-pricing .pricing-btn .main-btn.main-btn-2 { + border: 0; } + .single-pricing:hover, .single-pricing.active { + -webkit-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + -moz-box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); + box-shadow: 0px 8px 16px 0px rgba(72, 127, 255, 0.1); } + +/*=========================== + 9.CLICNT css +===========================*/ +.single-client img { + width: 100%; } + +/*=========================== + 10.CONTACT css +===========================*/ +.single-info .info-icon i { + font-size: 26px; + width: 55px; + height: 55px; + line-height: 53px; + text-align: center; + background-color: var(--primarycolor); + color: #fff; + border-radius: 50%; } + +.single-info .info-content { + padding-left: 20px; } + .single-info .info-content .info-title { + font-size: 18px; + font-weight: 400; + color: #777777; } + .single-info .info-content .text { + font-size: 16px; + font-weight: 600; + color: #1b273d; + margin-top: 5px; } + +.form-message { + margin-left: 15px; } + .form-message.error, .form-message.success { + font-size: 16px; + color: #1b273d; + background-color: #fff; + padding: 10px 15px; + margin-top: 15px; + background-color: #f5f8ff; } + .form-message.error { + color: #f00; } + +.single-form { + position: relative; + margin-top: 30px; } + .single-form input, + .single-form textarea { + width: 100%; + height: 65px; + border: 1px solid #e6e6e6; + border-radius: 5px; + padding: 0 25px; + color: #777777; } + .single-form input::placeholder, + .single-form textarea::placeholder { + opacity: 1; + color: #777777; } + .single-form input::-moz-placeholder, + .single-form textarea::-moz-placeholder { + opacity: 1; + color: #777777; } + .single-form input::-moz-placeholder, + .single-form textarea::-moz-placeholder { + opacity: 1; + color: #777777; } + .single-form input::-webkit-input-placeholder, + .single-form textarea::-webkit-input-placeholder { + opacity: 1; + color: #777777; } + .single-form input:focus, + .single-form textarea:focus { + border-color: var(--primarycolor); + background-color: #eaf1ff; } + .single-form textarea { + padding-top: 15px; + height: 180px; + resize: none; } + .single-form i { + position: absolute; + right: 25px; + top: 22px; + font-size: 16px; + color: #777777; } + +.contact-map .gmap_canvas { + padding: 8px; + background-color: #fff; + -webkit-box-shadow: 0px 0px 21px 0px rgba(72, 127, 255, 0.29); + -moz-box-shadow: 0px 0px 21px 0px rgba(72, 127, 255, 0.29); + box-shadow: 0px 0px 21px 0px rgba(72, 127, 255, 0.29); } + .contact-map .gmap_canvas iframe { + width: 100%; + height: 480px; } + +/*=========================== + 11.FOOTER css +===========================*/ +.footer-area { + position: relative; } + .footer-area::before { + position: absolute; + content: ''; + top: 0; + height: 100%; + width: 100%; + left: 0; + background: -webkit-linear-gradient(left, var(--primarycolor) 0%, var(--primarycolor) 100%); +background: -o-linear-gradient(left, var(--primarycolor) 0%, var(--primarycolor) 100%); +background: linear-gradient(to right, var(--primarycolor) 0%, var(--primarycolor) 100%); +opacity: 0.9; } + +.footer-subscribe .subscribe-title { + font-size: 50px; + color: #fff; } + @media (max-width: 767px) { + .footer-subscribe .subscribe-title { + font-size: 30px; } } + +.footer-subscribe .subscribe-form { + position: relative; } + .footer-subscribe .subscribe-form input { + width: 100%; + height: 80px; + padding: 0 40px; + background-color: rgba(255, 255, 255, 0.13); + border: 0; + border-radius: 50px; + color: #fff; } + .footer-subscribe .subscribe-form input::placeholder { + opacity: 1; + color: #fff; } + .footer-subscribe .subscribe-form input::-moz-placeholder { + opacity: 1; + color: #fff; } + .footer-subscribe .subscribe-form input::-moz-placeholder { + opacity: 1; + color: #fff; } + .footer-subscribe .subscribe-form input::-webkit-input-placeholder { + opacity: 1; + color: #fff; } + .footer-subscribe .subscribe-form .main-btn { + height: 60px; + line-height: 60px; + position: absolute; + top: 10px; + right: 10px; } + @media (max-width: 767px) { + .footer-subscribe .subscribe-form .main-btn { + position: relative; + top: 0; + right: 0; + margin-top: 10px; } } + @media only screen and (min-width: 576px) and (max-width: 767px) { + .footer-subscribe .subscribe-form .main-btn { + position: absolute; + top: 10px; + right: 10px; + margin-top: 0; } } + .footer-subscribe .subscribe-form .main-btn:hover { + background-color: #f5f8ff; + color: var(--primarycolor); } + +.widget { + border-top: 1px solid rgba(255, 255, 255, 0.4); + position: relative; + z-index: 5; } + .widget .f-title { + font-size: 24px; + color: #fff; } + +.footer-address .text { + color: #fff; + margin-top: 20px; } + +.footer-address .contact-link { + font-size: 16px; + font-weight: 500; + color: #fff; + text-decoration: underline; + margin-top: 15px; } + +.footer-contact .text { + color: #fff; + margin-top: 20px; } + +.footer-contact .social { + margin-top: 30px; } + .footer-contact .social li { + display: inline-block; } + .footer-contact .social li + li { + margin-left: 15px; } + .footer-contact .social li a { + font-size: 16px; + width: 50px; + height: 50px; + line-height: 50px; + border-radius: 50%; + /* background-color: var(--primarycolor); */ + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + text-align: center; + color: #fff; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; } + .footer-contact .social li a:hover { + color: var(--primarycolor); + background-color: #fff; } + +.footer-copyright { + position: relative; + z-index: 5; } + +.copyright { + border-top: 1px solid rgba(255, 255, 255, 0.4); + padding: 25px 0; } + .copyright .text { + color: #fff; + font-size: 16px; } + .copyright .text a { + color: #fff; } + +/*===== BACK TO TOP =====*/ +.back-to-top { + font-size: 20px; + color: #fff; + position: fixed; + right: 20px; + bottom: 20px; + width: 45px; + height: 45px; + line-height: 45px; + border-radius: 50%; + background: -webkit-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background: -o-linear-gradient(left, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background: linear-gradient(to right, var(--secondarycolor) 0%, var(--secondarygradcolor) 50%, var(--secondarycolor) 100%); + background-size: 200% auto; + text-align: center; + z-index: 99; + -webkit-transition: all 0.3s ease-out 0s; + -moz-transition: all 0.3s ease-out 0s; + -ms-transition: all 0.3s ease-out 0s; + -o-transition: all 0.3s ease-out 0s; + transition: all 0.3s ease-out 0s; + display: none; } + .back-to-top:hover { + color: #fff; + background-position: right center; } diff --git a/microsite-v2-templates/eventify/assets/fonts/Flaticon.eot b/microsite-v2-templates/eventify/assets/fonts/Flaticon.eot new file mode 100644 index 0000000..91d4fd8 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/fonts/Flaticon.eot differ diff --git a/microsite-v2-templates/eventify/assets/fonts/Flaticon.svg b/microsite-v2-templates/eventify/assets/fonts/Flaticon.svg new file mode 100644 index 0000000..3d40f38 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/fonts/Flaticon.svg @@ -0,0 +1,215 @@ + + + + + +Created by FontForge 20170731 at Wed Jul 17 12:06:05 2019 + By root + + + + + + + + + + + + + + + + + + + diff --git a/microsite-v2-templates/eventify/assets/fonts/Flaticon.ttf b/microsite-v2-templates/eventify/assets/fonts/Flaticon.ttf new file mode 100644 index 0000000..c212171 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/fonts/Flaticon.ttf differ diff --git a/microsite-v2-templates/eventify/assets/fonts/Flaticon.woff b/microsite-v2-templates/eventify/assets/fonts/Flaticon.woff new file mode 100644 index 0000000..8ac88e0 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/fonts/Flaticon.woff differ diff --git a/microsite-v2-templates/eventify/assets/fonts/Flaticon.woff2 b/microsite-v2-templates/eventify/assets/fonts/Flaticon.woff2 new file mode 100644 index 0000000..11f74f3 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/fonts/Flaticon.woff2 differ diff --git a/microsite-v2-templates/eventify/assets/images/about.png b/microsite-v2-templates/eventify/assets/images/about.png new file mode 100644 index 0000000..1fa0756 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/about.png differ diff --git a/microsite-v2-templates/eventify/assets/images/client-1.png b/microsite-v2-templates/eventify/assets/images/client-1.png new file mode 100644 index 0000000..7bd4bc8 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/client-1.png differ diff --git a/microsite-v2-templates/eventify/assets/images/client-2.png b/microsite-v2-templates/eventify/assets/images/client-2.png new file mode 100644 index 0000000..8a3019e Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/client-2.png differ diff --git a/microsite-v2-templates/eventify/assets/images/client-3.png b/microsite-v2-templates/eventify/assets/images/client-3.png new file mode 100644 index 0000000..c70d500 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/client-3.png differ diff --git a/microsite-v2-templates/eventify/assets/images/client-4.png b/microsite-v2-templates/eventify/assets/images/client-4.png new file mode 100644 index 0000000..d998456 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/client-4.png differ diff --git a/microsite-v2-templates/eventify/assets/images/client-5.png b/microsite-v2-templates/eventify/assets/images/client-5.png new file mode 100644 index 0000000..7235b90 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/client-5.png differ diff --git a/microsite-v2-templates/eventify/assets/images/dots.jpg b/microsite-v2-templates/eventify/assets/images/dots.jpg new file mode 100644 index 0000000..b0727dd Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/dots.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/event-1.jpg b/microsite-v2-templates/eventify/assets/images/event-1.jpg new file mode 100644 index 0000000..d65b3c3 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/event-1.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/event-2.jpg b/microsite-v2-templates/eventify/assets/images/event-2.jpg new file mode 100644 index 0000000..d65b3c3 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/event-2.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/event-3.jpg b/microsite-v2-templates/eventify/assets/images/event-3.jpg new file mode 100644 index 0000000..d65b3c3 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/event-3.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/favicon.png b/microsite-v2-templates/eventify/assets/images/favicon.png new file mode 100644 index 0000000..8c5a8c2 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/favicon.png differ diff --git a/microsite-v2-templates/eventify/assets/images/footer.jpg b/microsite-v2-templates/eventify/assets/images/footer.jpg new file mode 100644 index 0000000..fc6518a Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/footer.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/gallery-1.jpg b/microsite-v2-templates/eventify/assets/images/gallery-1.jpg new file mode 100644 index 0000000..993cc4b Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/gallery-1.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/gallery-2.jpg b/microsite-v2-templates/eventify/assets/images/gallery-2.jpg new file mode 100644 index 0000000..53a4607 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/gallery-2.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/gallery-3.jpg b/microsite-v2-templates/eventify/assets/images/gallery-3.jpg new file mode 100644 index 0000000..53a4607 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/gallery-3.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/gallery-4.jpg b/microsite-v2-templates/eventify/assets/images/gallery-4.jpg new file mode 100644 index 0000000..53a4607 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/gallery-4.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/gallery-5.jpg b/microsite-v2-templates/eventify/assets/images/gallery-5.jpg new file mode 100644 index 0000000..53a4607 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/gallery-5.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/header-bg.jpg b/microsite-v2-templates/eventify/assets/images/header-bg.jpg new file mode 100644 index 0000000..3a0544d Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/header-bg.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/logo.png b/microsite-v2-templates/eventify/assets/images/logo.png new file mode 100644 index 0000000..583081b Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/logo.png differ diff --git a/microsite-v2-templates/eventify/assets/images/pricing-bg.jpg b/microsite-v2-templates/eventify/assets/images/pricing-bg.jpg new file mode 100644 index 0000000..f3c7ea7 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/pricing-bg.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/team-1.jpg b/microsite-v2-templates/eventify/assets/images/team-1.jpg new file mode 100644 index 0000000..2bf0ff1 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/team-1.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/team-2.jpg b/microsite-v2-templates/eventify/assets/images/team-2.jpg new file mode 100644 index 0000000..2bf0ff1 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/team-2.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/team-3.jpg b/microsite-v2-templates/eventify/assets/images/team-3.jpg new file mode 100644 index 0000000..2bf0ff1 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/team-3.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/team-4.jpg b/microsite-v2-templates/eventify/assets/images/team-4.jpg new file mode 100644 index 0000000..2bf0ff1 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/team-4.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/team-5.jpg b/microsite-v2-templates/eventify/assets/images/team-5.jpg new file mode 100644 index 0000000..2bf0ff1 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/team-5.jpg differ diff --git a/microsite-v2-templates/eventify/assets/images/team-6.jpg b/microsite-v2-templates/eventify/assets/images/team-6.jpg new file mode 100644 index 0000000..2bf0ff1 Binary files /dev/null and b/microsite-v2-templates/eventify/assets/images/team-6.jpg differ diff --git a/microsite-v2-templates/eventify/assets/js/ajax-contact.js b/microsite-v2-templates/eventify/assets/js/ajax-contact.js new file mode 100644 index 0000000..0260d86 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/ajax-contact.js @@ -0,0 +1,48 @@ +$(function() { + + // Get the form. + var form = $('#contact-form'); + + // Get the messages div. + var formMessages = $('.form-message'); + + // Set up an event listener for the contact form. + $(form).submit(function(e) { + // Stop the browser from submitting the form. + e.preventDefault(); + + // Serialize the form data. + var formData = $(form).serialize(); + + // Submit the form using AJAX. + $.ajax({ + type: 'POST', + url: $(form).attr('action'), + data: formData + }) + .done(function(response) { + // Make sure that the formMessages div has the 'success' class. + $(formMessages).removeClass('error'); + $(formMessages).addClass('success'); + + // Set the message text. + $(formMessages).text(response); + + // Clear the form. + $('#contact-form input,#contact-form textarea').val(''); + }) + .fail(function(data) { + // Make sure that the formMessages div has the 'error' class. + $(formMessages).removeClass('success'); + $(formMessages).addClass('error'); + + // Set the message text. + if (data.responseText !== '') { + $(formMessages).text(data.responseText); + } else { + $(formMessages).text('Oops! An error occured and your message could not be sent.'); + } + }); + }); + +}); diff --git a/microsite-v2-templates/eventify/assets/js/bootstrap.min.js b/microsite-v2-templates/eventify/assets/js/bootstrap.min.js new file mode 100644 index 0000000..c4c0d1f --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.3.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t=t||self).bootstrap={},t.jQuery,t.Popper)}(this,function(t,g,u){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Ee},je="show",He="out",Re={HIDE:"hide"+De,HIDDEN:"hidden"+De,SHOW:"show"+De,SHOWN:"shown"+De,INSERTED:"inserted"+De,CLICK:"click"+De,FOCUSIN:"focusin"+De,FOCUSOUT:"focusout"+De,MOUSEENTER:"mouseenter"+De,MOUSELEAVE:"mouseleave"+De},xe="fade",Fe="show",Ue=".tooltip-inner",We=".arrow",qe="hover",Me="focus",Ke="click",Qe="manual",Be=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Fe))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(xe);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:We},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),g(o).addClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===He&&e._leave(null,e)};if(g(this.tip).hasClass(xe)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=g.Event(this.constructor.Event.HIDE),o=function(){e._hoverState!==je&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),g(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(g(this.element).trigger(i),!i.isDefaultPrevented()){if(g(n).removeClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[Ke]=!1,this._activeTrigger[Me]=!1,this._activeTrigger[qe]=!1,g(this.tip).hasClass(xe)){var r=_.getTransitionDurationFromElement(n);g(n).one(_.TRANSITION_END,o).emulateTransitionEnd(r)}else o();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Ae+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(Ue)),this.getTitle()),g(t).removeClass(xe+" "+Fe)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Se(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return Pe[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==Qe){var e=t===qe?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===qe?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),g(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Me:qe]=!0),g(e.getTipElement()).hasClass(Fe)||e._hoverState===je?e._hoverState=je:(clearTimeout(e._timeout),e._hoverState=je,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===je&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Me:qe]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=He,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===He&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=g(this.element).data();return Object.keys(e).forEach(function(t){-1!==Oe.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(be,t,this.constructor.DefaultType),t.sanitize&&(t.template=Se(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ne);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(xe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(Ie),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(Ie,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Le}},{key:"NAME",get:function(){return be}},{key:"DATA_KEY",get:function(){return Ie}},{key:"Event",get:function(){return Re}},{key:"EVENT_KEY",get:function(){return De}},{key:"DefaultType",get:function(){return ke}}]),i}();g.fn[be]=Be._jQueryInterface,g.fn[be].Constructor=Be,g.fn[be].noConflict=function(){return g.fn[be]=we,Be._jQueryInterface};var Ve="popover",Ye="bs.popover",ze="."+Ye,Xe=g.fn[Ve],$e="bs-popover",Ge=new RegExp("(^|\\s)"+$e+"\\S+","g"),Je=l({},Be.Default,{placement:"right",trigger:"click",content:"",template:''}),Ze=l({},Be.DefaultType,{content:"(string|element|function)"}),tn="fade",en="show",nn=".popover-header",on=".popover-body",rn={HIDE:"hide"+ze,HIDDEN:"hidden"+ze,SHOW:"show"+ze,SHOWN:"shown"+ze,INSERTED:"inserted"+ze,CLICK:"click"+ze,FOCUSIN:"focusin"+ze,FOCUSOUT:"focusout"+ze,MOUSEENTER:"mouseenter"+ze,MOUSELEAVE:"mouseleave"+ze},sn=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(t){g(this.getTipElement()).addClass($e+"-"+t)},o.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},o.setContent=function(){var t=g(this.getTipElement());this.setElementContent(t.find(nn),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(on),e),t.removeClass(tn+" "+en)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ge);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t1?c:d}var f=[],g=[],h={precision:100,elapse:!1,defer:!1};g.push(/^[0-9]*$/.source),g.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g=new RegExp(g.join("|"));var i={Y:"years",m:"months",n:"daysToMonth",d:"daysToWeek",w:"weeks",W:"weeksToMonth",H:"hours",M:"minutes",S:"seconds",D:"totalDays",I:"totalHours",N:"totalMinutes",T:"totalSeconds"},j=function(b,c,d){this.el=b,this.$el=a(b),this.interval=null,this.offset={},this.options=a.extend({},h),this.instanceNumber=f.length,f.push(this),this.$el.data("countdown-instance",this.instanceNumber),d&&("function"==typeof d?(this.$el.on("update.countdown",d),this.$el.on("stoped.countdown",d),this.$el.on("finish.countdown",d)):this.options=a.extend({},h,d)),this.setFinalDate(c),this.options.defer===!1&&this.start()};a.extend(j.prototype,{start:function(){null!==this.interval&&clearInterval(this.interval);var a=this;this.update(),this.interval=setInterval(function(){a.update.call(a)},this.options.precision)},stop:function(){clearInterval(this.interval),this.interval=null,this.dispatchEvent("stoped")},toggle:function(){this.interval?this.stop():this.start()},pause:function(){this.stop()},resume:function(){this.start()},remove:function(){this.stop.call(this),f[this.instanceNumber]=null,delete this.$el.data().countdownInstance},setFinalDate:function(a){this.finalDate=b(a)},update:function(){if(0===this.$el.closest("html").length)return void this.remove();var b,c=void 0!==a._data(this.el,"events"),d=new Date;b=this.finalDate.getTime()-d.getTime(),b=Math.ceil(b/1e3),b=!this.options.elapse&&b<0?0:Math.abs(b),this.totalSecsLeft!==b&&c&&(this.totalSecsLeft=b,this.elapsed=d>=this.finalDate,this.offset={seconds:this.totalSecsLeft%60,minutes:Math.floor(this.totalSecsLeft/60)%60,hours:Math.floor(this.totalSecsLeft/60/60)%24,days:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToWeek:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToMonth:Math.floor(this.totalSecsLeft/60/60/24%30.4368),weeks:Math.floor(this.totalSecsLeft/60/60/24/7),weeksToMonth:Math.floor(this.totalSecsLeft/60/60/24/7)%4,months:Math.floor(this.totalSecsLeft/60/60/24/30.4368),years:Math.abs(this.finalDate.getFullYear()-d.getFullYear()),totalDays:Math.floor(this.totalSecsLeft/60/60/24),totalHours:Math.floor(this.totalSecsLeft/60/60),totalMinutes:Math.floor(this.totalSecsLeft/60),totalSeconds:this.totalSecsLeft},this.options.elapse||0!==this.totalSecsLeft?this.dispatchEvent("update"):(this.stop(),this.dispatchEvent("finish")))},dispatchEvent:function(b){var c=a.Event(b+".countdown");c.finalDate=this.finalDate,c.elapsed=this.elapsed,c.offset=a.extend({},this.offset),c.strftime=d(this.offset),this.$el.trigger(c)}}),a.fn.countdown=function(){var b=Array.prototype.slice.call(arguments,0);return this.each(function(){var c=a(this).data("countdown-instance");if(void 0!==c){var d=f[c],e=b[0];j.prototype.hasOwnProperty(e)?d[e].apply(d,b.slice(1)):null===String(e).match(/^[$A-Z_][0-9A-Z_$]*$/i)?(d.setFinalDate.call(d,e),d.start()):a.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi,e))}else new j(this,b[0],b[1])})}}); \ No newline at end of file diff --git a/microsite-v2-templates/eventify/assets/js/jquery.counterup.min.js b/microsite-v2-templates/eventify/assets/js/jquery.counterup.min.js new file mode 100644 index 0000000..cddf5a1 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/jquery.counterup.min.js @@ -0,0 +1,8 @@ +/*! +* jquery.counterup.js 1.0 +* +* Copyright 2013, Benjamin Intal http://gambit.ph @bfintal +* Released under the GPL v2 License +* +* Date: Nov 26, 2013 +*/(function(e){"use strict";e.fn.counterUp=function(t){var n=e.extend({time:400,delay:10},t);return this.each(function(){var t=e(this),r=n,i=function(){var e=[],n=r.time/r.delay,i=t.text(),s=/[0-9]+,[0-9]+/.test(i);i=i.replace(/,/g,"");var o=/^[0-9]+$/.test(i),u=/^[0-9]+\.[0-9]+$/.test(i),a=u?(i.split(".")[1]||[]).length:0;for(var f=n;f>=1;f--){var l=parseInt(i/n*f);u&&(l=parseFloat(i/n*f).toFixed(a));if(s)while(/(\d+)(\d{3})/.test(l.toString()))l=l.toString().replace(/(\d+)(\d{3})/,"$1,$2");e.unshift(l)}t.data("counterup-nums",e);t.text("0");var c=function(){t.text(t.data("counterup-nums").shift());if(t.data("counterup-nums").length)setTimeout(t.data("counterup-func"),r.delay);else{delete t.data("counterup-nums");t.data("counterup-nums",null);t.data("counterup-func",null)}};t.data("counterup-func",c);setTimeout(t.data("counterup-func"),r.delay)};t.waypoint(i,{offset:"100%",triggerOnce:!0})})}})(jQuery); \ No newline at end of file diff --git a/microsite-v2-templates/eventify/assets/js/jquery.easing.min.js b/microsite-v2-templates/eventify/assets/js/jquery.easing.min.js new file mode 100644 index 0000000..6cf5f20 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/jquery.easing.min.js @@ -0,0 +1,44 @@ +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright © 2001 Robert Penner + * All rights reserved. + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright © 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ +jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g(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/microsite-v2-templates/eventify/assets/js/main.js b/microsite-v2-templates/eventify/assets/js/main.js new file mode 100644 index 0000000..cac568a --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/main.js @@ -0,0 +1,170 @@ +$(function() { + + "use strict"; + + //===== Prealoder + + $(window).on('load', function(event) { + $('.preloader').delay(500).fadeOut(500); + }); + + + //===== Sticky + + $(window).on('scroll', function(event) { + var scroll = $(window).scrollTop(); + if (scroll < 10) { + $(".navbar-area").removeClass("sticky"); + } else{ + $(".navbar-area").addClass("sticky"); + } + }); + + + //===== close navbar-collapse when a clicked + + $(".navbar-nav a").on('click', function () { + $(".navbar-collapse").removeClass("show"); + }); + + + //===== Section Menu Active + + var scrollLink = $('.page-scroll'); + // Active link switching + $(window).scroll(function() { + var scrollbarLocation = $(this).scrollTop(); + + scrollLink.each(function() { + + var sectionOffset = $(this.hash).offset().top - 73; + + if ( sectionOffset <= scrollbarLocation ) { + $(this).parent().addClass('active'); + $(this).parent().siblings().removeClass('active'); + } + }); + }); + + + //===== Mobile Menu + + $(".navbar-toggler").on('click', function(){ + $(this).toggleClass("active"); + }); + + $(".navbar-nav a").on('click', function() { + $(".navbar-toggler").removeClass('active'); + }); + + + //===== Countdown + + $('[data-countdown]').each(function() { + var $this = $(this), finalDate = $(this).data('countdown'); + $this.countdown(finalDate, function(event) { + $this.html(event.strftime('
%D

Days

%H

Hours

%M

Minutes

%S

Seconds

')); + }); + }); + + + //===== WOW + + new WOW().init(); + + + //===== Magnific Popup + + $('.image-popup').magnificPopup({ + type: 'image', + gallery:{ + enabled:true + } + }); + + + //===== Counter Up + + $('.counter').counterUp({ + delay: 10, + time: 2000 + }); + + + $('.client-active').slick({ + dots: false, + arrows: false, + infinite: true, + autoplay: true, + speed: 800, + slidesToShow: 4, + slidesToScroll: 1, + responsive: [ + { + breakpoint: 1200, + settings: { + slidesToShow: 3, + } + }, + { + breakpoint: 992, + settings: { + slidesToShow: 2, + } + }, + { + breakpoint: 768, + settings: { + slidesToShow: 2, + } + }, + { + breakpoint: 576, + settings: { + slidesToShow: 1, + } + } + ] + }); + + + //===== Back to top + + // Show or hide the sticky footer button + $(window).on('scroll', function(event) { + if($(this).scrollTop() > 600){ + $('.back-to-top').fadeIn(200) + } else{ + $('.back-to-top').fadeOut(200) + } + }); + + + //Animate the scroll to yop + $('.back-to-top').on('click', function(event) { + event.preventDefault(); + + $('html, body').animate({ + scrollTop: 0, + }, 1500); + }); + + + //===== + + + + + + + + + + + + + + + + +}); \ No newline at end of file diff --git a/microsite-v2-templates/eventify/assets/js/popper.min.js b/microsite-v2-templates/eventify/assets/js/popper.min.js new file mode 100644 index 0000000..94a5c26 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/popper.min.js @@ -0,0 +1,5 @@ +/* + Copyright (C) Federico Zivolo 2019 + Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). + */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function r(e){return 11===e?pe:10===e?se:pe||se}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),le({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=fe({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},le(n,m,$(v)),le(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ge.FLIP:p=[n,i];break;case ge.CLOCKWISE:p=G(n);break;case ge.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u);(m||b||y)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),y&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=fe({},e.offsets.popper,D(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=C(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.rightwindow.devicePixelRatio||!me),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=H('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=fe({},E,e.attributes),e.styles=fe({},m,e.styles),e.arrowStyles=fe({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return j(e.instance.popper,e.styles),V(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&j(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),j(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ue}); +//# sourceMappingURL=popper.min.js.map diff --git a/microsite-v2-templates/eventify/assets/js/scrolling-nav.js b/microsite-v2-templates/eventify/assets/js/scrolling-nav.js new file mode 100644 index 0000000..4dbdb03 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/scrolling-nav.js @@ -0,0 +1,19 @@ + +//jQuery for page scrolling feature - requires jQuery Easing plugin +$(function() { + + $('a.page-scroll[href*="#"]:not([href="#"])').on('click', function () { + if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { + var target = $(this.hash); + target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); + if (target.length) { + $('html, body').animate({ + scrollTop: (target.offset().top -70) + }, 1200, "easeInOutExpo"); + return false; + } + } + }); + +}); + diff --git a/microsite-v2-templates/eventify/assets/js/slick.min.js b/microsite-v2-templates/eventify/assets/js/slick.min.js new file mode 100644 index 0000000..42172c2 --- /dev/null +++ b/microsite-v2-templates/eventify/assets/js/slick.min.js @@ -0,0 +1 @@ +!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'',nextArrow:'',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('',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/microsite-v2-templates/eventre/assets/plugins/magnific-popup/magnific-popup.css b/microsite-v2-templates/eventre/assets/plugins/magnific-popup/magnific-popup.css new file mode 100644 index 0000000..8561e18 --- /dev/null +++ b/microsite-v2-templates/eventre/assets/plugins/magnific-popup/magnific-popup.css @@ -0,0 +1,351 @@ +/* Magnific Popup CSS */ +.mfp-bg { + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1042; + overflow: hidden; + position: fixed; + background: #0b0b0b; + opacity: 0.8; } + +.mfp-wrap { + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1043; + position: fixed; + outline: none !important; + -webkit-backface-visibility: hidden; } + +.mfp-container { + text-align: center; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + padding: 0 8px; + box-sizing: border-box; } + +.mfp-container:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; } + +.mfp-align-top .mfp-container:before { + display: none; } + +.mfp-content { + position: relative; + display: inline-block; + vertical-align: middle; + margin: 0 auto; + text-align: left; + z-index: 1045; } + +.mfp-inline-holder .mfp-content, +.mfp-ajax-holder .mfp-content { + width: 100%; + cursor: auto; } + +.mfp-ajax-cur { + cursor: progress; } + +.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { + cursor: -moz-zoom-out; + cursor: -webkit-zoom-out; + cursor: zoom-out; } + +.mfp-zoom { + cursor: pointer; + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; + cursor: zoom-in; } + +.mfp-auto-cursor .mfp-content { + cursor: auto; } + +.mfp-close, +.mfp-arrow, +.mfp-preloader, +.mfp-counter { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; } + +.mfp-loading.mfp-figure { + display: none; } + +.mfp-hide { + display: none !important; } + +.mfp-preloader { + color: #CCC; + position: absolute; + top: 50%; + width: auto; + text-align: center; + margin-top: -0.8em; + left: 8px; + right: 8px; + z-index: 1044; } + .mfp-preloader a { + color: #CCC; } + .mfp-preloader a:hover { + color: #FFF; } + +.mfp-s-ready .mfp-preloader { + display: none; } + +.mfp-s-error .mfp-content { + display: none; } + +button.mfp-close, +button.mfp-arrow { + overflow: visible; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + display: block; + outline: none; + padding: 0; + z-index: 1046; + box-shadow: none; + touch-action: manipulation; } + +button::-moz-focus-inner { + padding: 0; + border: 0; } + +.mfp-close { + width: 44px; + height: 44px; + line-height: 44px; + position: absolute; + right: 0; + top: 0; + text-decoration: none; + text-align: center; + opacity: 0.65; + padding: 0 0 18px 10px; + color: #FFF; + font-style: normal; + font-size: 28px; + font-family: Arial, Baskerville, monospace; } + .mfp-close:hover, + .mfp-close:focus { + opacity: 1; } + .mfp-close:active { + top: 1px; } + +.mfp-close-btn-in .mfp-close { + color: #333; } + +.mfp-image-holder .mfp-close, +.mfp-iframe-holder .mfp-close { + color: #FFF; + right: -6px; + text-align: right; + padding-right: 6px; + width: 100%; } + +.mfp-counter { + position: absolute; + top: 0; + right: 0; + color: #CCC; + font-size: 12px; + line-height: 18px; + white-space: nowrap; } + +.mfp-arrow { + position: absolute; + opacity: 0.65; + margin: 0; + top: 50%; + margin-top: -55px; + padding: 0; + width: 90px; + height: 110px; + -webkit-tap-highlight-color: transparent; } + .mfp-arrow:active { + margin-top: -54px; } + .mfp-arrow:hover, + .mfp-arrow:focus { + opacity: 1; } + .mfp-arrow:before, + .mfp-arrow:after { + content: ''; + display: block; + width: 0; + height: 0; + position: absolute; + left: 0; + top: 0; + margin-top: 35px; + margin-left: 35px; + border: medium inset transparent; } + .mfp-arrow:after { + border-top-width: 13px; + border-bottom-width: 13px; + top: 8px; } + .mfp-arrow:before { + border-top-width: 21px; + border-bottom-width: 21px; + opacity: 0.7; } + +.mfp-arrow-left { + left: 0; } + .mfp-arrow-left:after { + border-right: 17px solid #FFF; + margin-left: 31px; } + .mfp-arrow-left:before { + margin-left: 25px; + border-right: 27px solid #3F3F3F; } + +.mfp-arrow-right { + right: 0; } + .mfp-arrow-right:after { + border-left: 17px solid #FFF; + margin-left: 39px; } + .mfp-arrow-right:before { + border-left: 27px solid #3F3F3F; } + +.mfp-iframe-holder { + padding-top: 40px; + padding-bottom: 40px; } + .mfp-iframe-holder .mfp-content { + line-height: 0; + width: 100%; + max-width: 900px; } + .mfp-iframe-holder .mfp-close { + top: -40px; } + +.mfp-iframe-scaler { + width: 100%; + height: 0; + overflow: hidden; + padding-top: 56.25%; } + .mfp-iframe-scaler iframe { + position: absolute; + display: block; + top: 0; + left: 0; + width: 100%; + height: 100%; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); + background: #000; } + +/* Main image in popup */ +img.mfp-img { + width: auto; + max-width: 100%; + height: auto; + display: block; + line-height: 0; + box-sizing: border-box; + padding: 40px 0 40px; + margin: 0 auto; } + +/* The shadow behind the image */ +.mfp-figure { + line-height: 0; } + .mfp-figure:after { + content: ''; + position: absolute; + left: 0; + top: 40px; + bottom: 40px; + display: block; + right: 0; + width: auto; + height: auto; + z-index: -1; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); + background: #444; } + .mfp-figure small { + color: #BDBDBD; + display: block; + font-size: 12px; + line-height: 14px; } + .mfp-figure figure { + margin: 0; } + +.mfp-bottom-bar { + margin-top: -36px; + position: absolute; + top: 100%; + left: 0; + width: 100%; + cursor: auto; } + +.mfp-title { + text-align: left; + line-height: 18px; + color: #F3F3F3; + word-wrap: break-word; + padding-right: 36px; } + +.mfp-image-holder .mfp-content { + max-width: 100%; } + +.mfp-gallery .mfp-image-holder .mfp-figure { + cursor: pointer; } + +@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { + /** + * Remove all paddings around the image on small screen + */ + .mfp-img-mobile .mfp-image-holder { + padding-left: 0; + padding-right: 0; } + .mfp-img-mobile img.mfp-img { + padding: 0; } + .mfp-img-mobile .mfp-figure:after { + top: 0; + bottom: 0; } + .mfp-img-mobile .mfp-figure small { + display: inline; + margin-left: 5px; } + .mfp-img-mobile .mfp-bottom-bar { + background: rgba(0, 0, 0, 0.6); + bottom: 0; + margin: 0; + top: auto; + padding: 3px 5px; + position: fixed; + box-sizing: border-box; } + .mfp-img-mobile .mfp-bottom-bar:empty { + padding: 0; } + .mfp-img-mobile .mfp-counter { + right: 5px; + top: 3px; } + .mfp-img-mobile .mfp-close { + top: 0; + right: 0; + width: 35px; + height: 35px; + line-height: 35px; + background: rgba(0, 0, 0, 0.6); + position: fixed; + text-align: center; + padding: 0; } } + +@media all and (max-width: 900px) { + .mfp-arrow { + -webkit-transform: scale(0.75); + transform: scale(0.75); } + .mfp-arrow-left { + -webkit-transform-origin: 0; + transform-origin: 0; } + .mfp-arrow-right { + -webkit-transform-origin: 100%; + transform-origin: 100%; } + .mfp-container { + padding-left: 6px; + padding-right: 6px; } } diff --git a/microsite-v2-templates/eventre/assets/plugins/popper/popper.min.js b/microsite-v2-templates/eventre/assets/plugins/popper/popper.min.js new file mode 100644 index 0000000..ef28b3a --- /dev/null +++ b/microsite-v2-templates/eventre/assets/plugins/popper/popper.min.js @@ -0,0 +1,4 @@ +/* + Copyright (C) Federico Zivolo 2017 + Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). + */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=window.getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e||-1!==['HTML','BODY','#document'].indexOf(e.nodeName))return window.document.body;var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:window.document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return window.document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var f=a.commonAncestorContainer;if(e!==f&&t!==f||i.contains(n))return p(f)?f:r(f);var l=s(e);return l.host?d(l.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),f=0i[e]&&!t.escapeWithReference&&(n=z(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=V,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var o=t.element;if('string'==typeof o){if(o=e.instance.popper.querySelector(o),!o)return e;}else if(!e.instance.popper.contains(o))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var i=e.placement.split('-')[0],n=e.offsets,r=n.popper,p=n.reference,s=-1!==['left','right'].indexOf(i),d=s?'height':'width',a=s?'top':'left',f=s?'left':'top',l=s?'bottom':'right',m=O(o)[d];p[l]-mr[l]&&(e.offsets.popper[a]+=p[a]+m-r[l]);var h=p[a]+p[d]/2-m/2,g=h-c(e.offsets.popper)[a];return g=_(z(r[d]-m,g),0),e.arrowElement=o,e.offsets.arrow={},e.offsets.arrow[a]=Math.round(g),e.offsets.arrow[f]='',e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=w(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=L(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case fe.FLIP:p=[i,n];break;case fe.CLOCKWISE:p=K(i);break;case fe.COUNTERCLOCKWISE:p=K(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=L(i);var a=e.offsets.popper,f=e.offsets.reference,l=V,m='left'===i&&l(a.right)>l(f.left)||'right'===i&&l(a.left)l(f.top)||'bottom'===i&&l(a.top)l(o.right),g=l(a.top)l(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,y=-1!==['top','bottom'].indexOf(i),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),w&&(r=j(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=N(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[t]-(s?n[p?'width':'height']:0),e.placement=L(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right + + +Generated by Fontastic.me + + + + + + + + + + diff --git a/microsite-v2-templates/eventre/assets/plugins/slick/fonts/slick.ttf b/microsite-v2-templates/eventre/assets/plugins/slick/fonts/slick.ttf new file mode 100644 index 0000000..9d03461 Binary files /dev/null and b/microsite-v2-templates/eventre/assets/plugins/slick/fonts/slick.ttf differ diff --git a/microsite-v2-templates/eventre/assets/plugins/slick/fonts/slick.woff b/microsite-v2-templates/eventre/assets/plugins/slick/fonts/slick.woff new file mode 100644 index 0000000..8ee9972 Binary files /dev/null and b/microsite-v2-templates/eventre/assets/plugins/slick/fonts/slick.woff differ diff --git a/microsite-v2-templates/eventre/assets/plugins/slick/slick-theme.css b/microsite-v2-templates/eventre/assets/plugins/slick/slick-theme.css new file mode 100644 index 0000000..5e086c3 --- /dev/null +++ b/microsite-v2-templates/eventre/assets/plugins/slick/slick-theme.css @@ -0,0 +1,204 @@ +@charset 'UTF-8'; +/* Slider */ +.slick-loading .slick-list +{ + background: #fff url('ajax-loader.gif') center center no-repeat; +} + +/* Icons */ +@font-face +{ + font-family: 'slick'; + font-weight: normal; + font-style: normal; + + src: url('fonts/slick.eot'); + src: url('fonts/slick.eot%3F') format('embedded-opentype'), url('fonts/slick.woff') format('woff'), url('fonts/slick.ttf') format('truetype'), url('fonts/slick.svg') format('svg'); +} +/* Arrows */ +.slick-prev, +.slick-next +{ + font-size: 0; + line-height: 0; + + position: absolute; + top: 50%; + + display: block; + + width: 20px; + height: 20px; + padding: 0; + -webkit-transform: translate(0, -50%); + -ms-transform: translate(0, -50%); + transform: translate(0, -50%); + + cursor: pointer; + + color: transparent; + border: none; + outline: none; + background: transparent; +} +.slick-prev:hover, +.slick-prev:focus, +.slick-next:hover, +.slick-next:focus +{ + color: transparent; + outline: none; + background: transparent; +} +.slick-prev:hover:before, +.slick-prev:focus:before, +.slick-next:hover:before, +.slick-next:focus:before +{ + opacity: 1; +} +.slick-prev.slick-disabled:before, +.slick-next.slick-disabled:before +{ + opacity: .25; +} + +.slick-prev:before, +.slick-next:before +{ + font-family: 'slick'; + font-size: 20px; + line-height: 1; + + opacity: .75; + color: white; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.slick-prev +{ + left: -25px; +} +[dir='rtl'] .slick-prev +{ + right: -25px; + left: auto; +} +.slick-prev:before +{ + content: '←'; +} +[dir='rtl'] .slick-prev:before +{ + content: '→'; +} + +.slick-next +{ + right: -25px; +} +[dir='rtl'] .slick-next +{ + right: auto; + left: -25px; +} +.slick-next:before +{ + content: '→'; +} +[dir='rtl'] .slick-next:before +{ + content: '←'; +} + +/* Dots */ +.slick-dotted.slick-slider +{ + margin-bottom: 30px; +} + +.slick-dots +{ + position: absolute; + bottom: -25px; + + display: block; + + width: 100%; + padding: 0; + margin: 0; + + list-style: none; + + text-align: center; +} +.slick-dots li +{ + position: relative; + + display: inline-block; + + width: 20px; + height: 20px; + margin: 0 5px; + padding: 0; + + cursor: pointer; +} +.slick-dots li button +{ + font-size: 0; + line-height: 0; + + display: block; + + width: 20px; + height: 20px; + padding: 5px; + + cursor: pointer; + + color: transparent; + border: 0; + outline: none; + background: transparent; +} +.slick-dots li button:hover, +.slick-dots li button:focus +{ + outline: none; +} +.slick-dots li button:hover:before, +.slick-dots li button:focus:before +{ + opacity: 1; +} +.slick-dots li button:before +{ + font-family: 'slick'; + font-size: 6px; + line-height: 20px; + + position: absolute; + top: 0; + left: 0; + + width: 20px; + height: 20px; + + content: '•'; + text-align: center; + + opacity: .25; + color: black; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.slick-dots li.slick-active button:before +{ + opacity: .75; + color: black; +} diff --git a/microsite-v2-templates/eventre/assets/plugins/slick/slick.css b/microsite-v2-templates/eventre/assets/plugins/slick/slick.css new file mode 100644 index 0000000..57477e8 --- /dev/null +++ b/microsite-v2-templates/eventre/assets/plugins/slick/slick.css @@ -0,0 +1,119 @@ +/* Slider */ +.slick-slider +{ + position: relative; + + display: block; + box-sizing: border-box; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + -webkit-touch-callout: none; + -khtml-user-select: none; + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-tap-highlight-color: transparent; +} + +.slick-list +{ + position: relative; + + display: block; + overflow: hidden; + + margin: 0; + padding: 0; +} +.slick-list:focus +{ + outline: none; +} +.slick-list.dragging +{ + cursor: pointer; + cursor: hand; +} + +.slick-slider .slick-track, +.slick-slider .slick-list +{ + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.slick-track +{ + position: relative; + top: 0; + left: 0; + + display: block; + margin-left: auto; + margin-right: auto; +} +.slick-track:before, +.slick-track:after +{ + display: table; + + content: ''; +} +.slick-track:after +{ + clear: both; +} +.slick-loading .slick-track +{ + visibility: hidden; +} + +.slick-slide +{ + display: none; + float: left; + + height: 100%; + min-height: 1px; +} +[dir='rtl'] .slick-slide +{ + float: right; +} +.slick-slide img +{ + display: block; +} +.slick-slide.slick-loading img +{ + display: none; +} +.slick-slide.dragging img +{ + pointer-events: none; +} +.slick-initialized .slick-slide +{ + display: block; +} +.slick-loading .slick-slide +{ + visibility: hidden; +} +.slick-vertical .slick-slide +{ + display: block; + + height: auto; + + border: 1px solid transparent; +} +.slick-arrow.slick-hidden { + display: none; +} diff --git a/microsite-v2-templates/eventre/assets/plugins/slick/slick.min.js b/microsite-v2-templates/eventre/assets/plugins/slick/slick.min.js new file mode 100644 index 0000000..42172c2 --- /dev/null +++ b/microsite-v2-templates/eventre/assets/plugins/slick/slick.min.js @@ -0,0 +1 @@ +!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'',nextArrow:'',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i(' + +
+ + + + + + + + +
+
+
+
+
+

Error Page

+
+ +
+
+
+
+ + + + + + +
+
+
+
+
+ 404 +

Oops!... Page Not Found.

+ Go to home +
+
+
+
+
+ + + + + +
+
+
+
+ +
+

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/FAQ.html b/microsite-v2-templates/eventre/other_html_file/FAQ.html new file mode 100644 index 0000000..75aa352 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/FAQ.html @@ -0,0 +1,468 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

FAQS

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

Our FAQ

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore dolore magna

+
+
+
+
+
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+
+
+
+
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+ +
+ + + +
+
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium. +
+
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+ +
+

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/about-us.html b/microsite-v2-templates/eventre/other_html_file/about-us.html new file mode 100644 index 0000000..37d98a0 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/about-us.html @@ -0,0 +1,578 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

About Us

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

About The Eventre

+
+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud exercitation ullamco. +

+
+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmtempor incididunt ut labore et dolore magna aliq enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea.

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

Who Speaking?

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore

+
+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

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

What People Say?

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti aliquid vero harum rerum voluptates, ab, ullam.

+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Espen Brunberg

+ +

Web Developer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Kaite Stricker

+ +

Designer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Adam Smith

+ +

Web Developer

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/microsite-v2-templates/eventre/other_html_file/contact.html b/microsite-v2-templates/eventre/other_html_file/contact.html new file mode 100644 index 0000000..41bf150 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/contact.html @@ -0,0 +1,261 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Contact Us

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

Get in Touch

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maiores, velit.

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/gallery-two.html b/microsite-v2-templates/eventre/other_html_file/gallery-two.html new file mode 100644 index 0000000..4049cae --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/gallery-two.html @@ -0,0 +1,369 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our Gallery

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/gallery.html b/microsite-v2-templates/eventre/other_html_file/gallery.html new file mode 100644 index 0000000..1d6747f --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/gallery.html @@ -0,0 +1,349 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our Gallery

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/homepage-two.html b/microsite-v2-templates/eventre/other_html_file/homepage-two.html new file mode 100644 index 0000000..9c994c4 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/homepage-two.html @@ -0,0 +1,1195 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+

About The Eventre

+
+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad +

+
+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmtempor incididunt ut labore et dolore magna aliq enim ad minim

+
+ +
+
+
+
+
+ + + +
+
+
+
+ +
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+ speaker +
+
GEORGE G. HERNANDEZ
+

CEO Rancom Motor

+
    +
  • +
  • +
  • +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+

Event Schedule

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore

+
+
+
+
+ +
+
+
+
+ +
    +
  • +
    Time
    +
    Speaker
    +
    Subject
    +
    Venue
    +
  • + +
  • +
    + +
    + 9.00 AM +
    + +
    + Samanta Doe +
    + +
    Introduction to Wp
    + +
    Auditorium A
    +
    +
  • + +
  • +
    + +
    + 10.00 AM +
    + +
    + Zerad Pawel +
    + +
    Principle of Wp
    + +
    Auditorium B
    +
    +
  • + +
  • +
    + +
    + 12.00 AM +
    + +
    + Henry Mong +
    + +
    Wp Requirements
    + +
    Auditorium C
    +
    +
  • + +
  • +
    + +
    + 2.00 PM +
    + +
    + Baily Leo +
    + +
    Introduction to Wp
    + +
    Auditorium D
    +
    +
  • + +
  • +
    + +
    + 3.00 PM +
    + +
    + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • + +
  • +
    + +
    + 3.00 PM +
    + +
    + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • +
+
+
+ +
    +
  • +
    Time
    +
    Speaker
    +
    Subject
    +
    Venue
    +
  • + +
  • +
    + +
    + 9.00 AM +
    + +
    + Samanta Doe +
    + +
    Introduction to Wp
    + +
    Auditorium A
    +
    +
  • + +
  • +
    + +
    + 10.00 AM +
    + +
    + Zerad Pawel +
    + +
    Principle of Wp
    + +
    Auditorium B
    +
    +
  • + +
  • +
    + +
    + 12.00 AM +
    + +
    + Henry Mong +
    + +
    Wp Requirements
    + +
    Auditorium C
    +
    +
  • + +
  • +
    + +
    + 2.00 PM +
    + +
    + Baily Leo +
    + +
    Introduction to Wp
    + +
    Auditorium D
    +
    +
  • + +
  • +
    + +
    + 3.00 PM +
    + +
    + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • + +
  • +
    + +
    + 3.00 PM +
    + +
    + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • +
+
+
+ +
    +
  • +
    Time
    +
    Speaker
    +
    Subject
    +
    Venue
    +
  • + +
  • +
    + +
    + 9.00 AM +
    + +
    + Samanta Doe +
    + +
    Introduction to Wp
    + +
    Auditorium A
    +
    +
  • + +
  • +
    + +
    + 10.00 AM +
    + +
    + Zerad Pawel +
    + +
    Principle of Wp
    + +
    Auditorium B
    +
    +
  • + +
  • +
    + +
    + 12.00 AM +
    + +
    + Henry Mong +
    + +
    Wp Requirements
    + +
    Auditorium C
    +
    +
  • + +
  • +
    + +
    + 2.00 PM +
    + +
    + Baily Leo +
    + +
    Introduction to Wp
    + +
    Auditorium D
    +
    +
  • + +
  • +
    + +
    + 3.00 PM +
    + +
    + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • + +
  • +
    + +
    + 3.00 PM +
    + +
    + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • +
+
+
+
+
+
+
+ +
+ + + + + +
+
+
+
+
+
+

Limited Audience Seats

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm

+
+ +
+ Buy Ticket +
+
+
+
+
+
+ +
+ +
8 Speakers
+
+
+
+ +
+ +
500 + Seats
+
+
+
+ +
+ +
300 tickets
+
+
+
+ +
+ +
3 days event
+
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+

Eventre News

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Necessitatibus, enim.

+
+
+
+
+
+
+
+ + post-image + +
+
+
Default title here
+
+

Lorem ipsum dolor sit amet conse ctetur adipisicing elit, sed doeiuse tempor incididunt ut +

+
+ +
+

20May

+
+
+ Show more +
+
+
+
+
+
+
+ + post-image + +
+
+
Default title here
+
+

Lorem ipsum dolor sit amet conse ctetur adipisicing elit, sed doeiuse tempor incididunt ut +

+
+ +
+

20May

+
+
+ Show more +
+
+
+
+
+
+
+ + post-image + +
+
+
Default title here
+
+

Lorem ipsum dolor sit amet conse ctetur adipisicing elit, sed doeiuse tempor incididunt ut +

+
+ +
+

20May

+
+
+ Show more +
+
+
+
+
+
+
+ + post-image + +
+
+
Default title here
+
+

Lorem ipsum dolor sit amet conse ctetur adipisicing elit, sed doeiuse tempor incididunt ut +

+
+ +
+

20May

+
+
+ Show more +
+
+
+
+
+
+
+ + + + + + + + + + + +
+
+
+
+
+

Get ticket

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore

+
+
+
+
+
+ +
+
+ +
+
Starter
+
+ +
+

$39.00

+
+
+
+ +
    +
  • 1 Comfortable Seats

  • +
  • Free Lunch and Coffee

  • +
  • Certificate

  • +
  • Easy Access

  • +
+
+ +
+
+
+ + +
+
+ +
+
+ +
+
Platinum
+
+ +
+

$99.00

+
+
+
+ +
    +
  • 1 Comfortable Seats

  • +
  • Free Lunch and Coffee

  • +
  • Certificate

  • +
  • Easy Access

  • +
+
+ +
+
+
+
+
+ + + + + +
+ +
+
+

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+
+
+

Register to Eventre

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit

+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/news-left-sidebar.html b/microsite-v2-templates/eventre/other_html_file/news-left-sidebar.html new file mode 100644 index 0000000..e53dc74 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/news-left-sidebar.html @@ -0,0 +1,575 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our News

+
+ +
+
+
+
+ + + + + + +
+
+
+
+ +
+
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/news-right-sidebar.html b/microsite-v2-templates/eventre/other_html_file/news-right-sidebar.html new file mode 100644 index 0000000..b920e2c --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/news-right-sidebar.html @@ -0,0 +1,575 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our News

+
+ +
+
+
+
+ + + + + + +
+
+
+
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/news-single.html b/microsite-v2-templates/eventre/other_html_file/news-single.html new file mode 100644 index 0000000..f0fcea3 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/news-single.html @@ -0,0 +1,504 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

News Details

+
+ +
+
+
+
+ + + + + + +
+
+
+
+
+ +
+
+ post-image +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud.laboris nisi ut aliquip ex ea commodo conse + quat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. +

+

+ Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. +

+

+ Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam. + quaerat voluptatem. +

+
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud.laboris nisi ut aliquip ex ea commodo consequat.
+
+

+ Amet consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud.laboris nisi ut aliquip ex ea commodo conse +

+ +
+
+
+ +
+
Comments (3)
+ +
+ image +
+
Jessica Brown
+
    +
  • Mar 20, 2016
  • +
  • Reply
  • +
+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudant tota rem ape riamipsa eaque quae nisi ut aliquip commodo consequat. +

+ +
+ image +
+
Jonathan Doe
+
    +
  • Mar 20, 2016
  • +
+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudant tota rem ape riamipsa eaque quae nisi +

+
+
+
+
+ +
+ image +
+
Adam Smith
+
    +
  • Mar 20, 2016
  • +
  • Reply
  • +
+

+ Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudant tota rem ape riamipsa eaque quae nisi ut aliquip commodo consequat. +

+
+
+
+
+
Leave A Comment
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+ + + + + +
+
+
+
+ +
+

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/news.html b/microsite-v2-templates/eventre/other_html_file/news.html new file mode 100644 index 0000000..9a7ec05 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/news.html @@ -0,0 +1,596 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our News

+
+ +
+
+
+
+ + + + + + +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

+
+ +
+
+
+
+
+
+ + post-image + +
+
+
+

20May

+
+
+

Elementum purus id ultrices.

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/pricing.html b/microsite-v2-templates/eventre/other_html_file/pricing.html new file mode 100644 index 0000000..4298627 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/pricing.html @@ -0,0 +1,371 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Pricing Table

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

Get ticket

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore

+
+
+
+
+
+ +
+
+ +
+
Starter
+
+ +
+

39.00$

+

/Person

+
+
+
+ +
    +
  • 1 Comfortable Seats

  • +
  • Free Lunch and Coffee

  • +
  • Certificate

  • +
  • Easy Access

  • +
+
+ +
+
+
+ + +
+
+ +
+
+ +
+
Platinum
+
+ +
+

99.00$

+

/Person

+
+
+
+ +
    +
  • 1 Comfortable Seats

  • +
  • Free Lunch and Coffee

  • +
  • Certificate

  • +
  • Easy Access

  • +
+
+ +
+
+
+
+
+ + + + + + +
+
+
+
+ +
+

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/schedule.html b/microsite-v2-templates/eventre/other_html_file/schedule.html new file mode 100644 index 0000000..6b0f46f --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/schedule.html @@ -0,0 +1,693 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Event Schedule

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

Event Schedule

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore

+
+
+
+
+
+ +
+
+
+ +
    +
  • +
    Time
    +
    Speaker
    +
    Subject
    +
    Venue
    +
  • + +
  • +
    + +
    + + 9.00 AM +
    + +
    + speaker-thumb-one + Samanta Doe +
    + +
    Introduction to Wp
    + +
    Auditorium A
    +
    +
  • + +
  • +
    + +
    + + 10.00 AM +
    + +
    + speaker-thumb-two + Zerad Pawel +
    + +
    Principle of Wp
    + +
    Auditorium B
    +
    +
  • + +
  • +
    + +
    + + 12.00 AM +
    + +
    + speaker-thumb-three + Henry Mong +
    + +
    Wp Requirements
    + +
    Auditorium C
    +
    +
  • + +
  • +
    + +
    + + 2.00 PM +
    + +
    + speaker-thumb-four + Baily Leo +
    + +
    Introduction to Wp
    + +
    Auditorium D
    +
    +
  • + +
  • +
    + +
    + + 3.00 PM +
    + +
    + speaker-thumb-five + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • + +
  • +
    + +
    + + 3.00 PM +
    + +
    + speaker-thumb-six + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • +
+
+
+ +
    +
  • +
    Time
    +
    Speaker
    +
    Subject
    +
    Venue
    +
  • + +
  • +
    + +
    + + 9.00 AM +
    + +
    + speaker-thumb-one + Samanta Doe +
    + +
    Introduction to Wp
    + +
    Auditorium A
    +
    +
  • + +
  • +
    + +
    + + 10.00 AM +
    + +
    + speaker-thumb-two + Zerad Pawel +
    + +
    Principle of Wp
    + +
    Auditorium B
    +
    +
  • + +
  • +
    + +
    + + 12.00 AM +
    + +
    + speaker-thumb-three + Henry Mong +
    + +
    Wp Requirements
    + +
    Auditorium C
    +
    +
  • + +
  • +
    + +
    + + 2.00 PM +
    + +
    + speaker-thumb-four + Baily Leo +
    + +
    Introduction to Wp
    + +
    Auditorium D
    +
    +
  • + +
  • +
    + +
    + + 3.00 PM +
    + +
    + speaker-thumb-five + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • + +
  • +
    + +
    + + 3.00 PM +
    + +
    + speaker-thumb-six + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • +
+
+
+ +
    +
  • +
    Time
    +
    Speaker
    +
    Subject
    +
    Venue
    +
  • + +
  • +
    + +
    + + 9.00 AM +
    + +
    + speaker-thumb-one + Samanta Doe +
    + +
    Introduction to Wp
    + +
    Auditorium A
    +
    +
  • + +
  • +
    + +
    + + 10.00 AM +
    + +
    + speaker-thumb-two + Zerad Pawel +
    + +
    Principle of Wp
    + +
    Auditorium B
    +
    +
  • + +
  • +
    + +
    + + 12.00 AM +
    + +
    + speaker-thumb-three + Henry Mong +
    + +
    Wp Requirements
    + +
    Auditorium C
    +
    +
  • + +
  • +
    + +
    + + 2.00 PM +
    + +
    + speaker-thumb-four + Baily Leo +
    + +
    Introduction to Wp
    + +
    Auditorium D
    +
    +
  • + +
  • +
    + +
    + + 3.00 PM +
    + +
    + speaker-thumb-five + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • + +
  • +
    + +
    + + 3.00 PM +
    + +
    + speaker-thumb-six + Lee Mun +
    + +
    Useful tips for Wp
    + +
    Auditorium E
    +
    +
  • +
+
+
+
+ + + +
+
+
+
+ + + + + +
+
+
+
+ +
+

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/single-speaker.html b/microsite-v2-templates/eventre/other_html_file/single-speaker.html new file mode 100644 index 0000000..f58b54b --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/single-speaker.html @@ -0,0 +1,385 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Speaker Details

+
+ +
+
+
+
+ + + + +
+
+
+
+
+
+ speaker +
+
+
+
+
+

Jonathan Franco

+
+
+

Web Developer

+
+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud.laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse. + Duis aute irure dolor in reprehenderit in voluptate velit esse. +
+

+

+ Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. +
+ Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur

+
+ +
+
+
+
+
+
+
+
+
Personal Information
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi explicabo suscipit deleniti voluptatum quos nostrum iure doloremque cupiditate voluptatem a enim eaque quod perspiciatis repudiandae, mollitia adipisci ea, quidem eveniet consequatur veniam error. Adipisci, suscipit corporis repellat, soluta vitae deserunt perspiciatis labore reprehenderit sapiente provident vel maxime.

+
    +
  • Morbi fermentum felis nec
  • +
  • Fermentum felis nec gravida tempus.
  • +
  • Morbi fermentum felis nec
  • +
  • Fermentum felis nec gravida tempus.
  • +
  • Morbi fermentum felis nec
  • +
+
+
+
+
+
Personal Skills
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nobis repellat inventore at praesentium perspiciatis labore reprehenderit sapiente provident vel maxime.

+
+ +
+ +

Wordpress

+ +
+
90%
+
+
+ +
+ +

PHP

+ +
+
+ 75% +
+
+
+ +
+ +

Javascript

+ +
+
+ 60% +
+
+
+ +
+ +

HTML

+ +
+
+ 80% +
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ +
+

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/speakers.html b/microsite-v2-templates/eventre/other_html_file/speakers.html new file mode 100644 index 0000000..d151020 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/speakers.html @@ -0,0 +1,454 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our Speaker

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

Who Speaking?

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore

+
+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

+
+
+
+
+ +
+
+ speaker +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
Johnathan Franco
+

Project Manager

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/microsite-v2-templates/eventre/other_html_file/sponsors.html b/microsite-v2-templates/eventre/other_html_file/sponsors.html new file mode 100644 index 0000000..217a6f6 --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/sponsors.html @@ -0,0 +1,357 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our Sponsors

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

Our Sponsors

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore dolore

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/other_html_file/testimonial.html b/microsite-v2-templates/eventre/other_html_file/testimonial.html new file mode 100644 index 0000000..b27ac2d --- /dev/null +++ b/microsite-v2-templates/eventre/other_html_file/testimonial.html @@ -0,0 +1,411 @@ + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Our Testimonial

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

What People Say?

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti aliquid vero harum rerum voluptates, ab, ullam.

+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Espen Brunberg

+ +

Web Developer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Kaite Stricker

+ +

Designer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Adam Smith

+ +

Web Developer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Espen Brunberg

+ +

Web Developer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Kaite Stricker

+ +

Designer

+
+
+
+
+
+
+ +
+ +
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reiciendis voluptate modi sunt placeat in vel illo dolorem, atque maxime voluptates optio fugit iure cum ipsa quo quaerat! Veritatis, modi. Laudantium provident deleniti earum voluptas delectus, labore dolor dolorem amet expedita.

+
+
+
+ + person-image +
+ +

Adam Smith

+ +

Web Developer

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

Subscribe to Our Newsletter

+

Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor

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

Docklands Convention

+
    +
  • 1201 Park Street, Fifth Avenue,
    Dhanmondy, Dhaka.
  • +
  • [88] 657 524 332
  • +
+ Get Direction +
+
+ + + + + +
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/microsite-v2-templates/eventre/sample-config.json b/microsite-v2-templates/eventre/sample-config.json new file mode 100644 index 0000000..65f91c4 --- /dev/null +++ b/microsite-v2-templates/eventre/sample-config.json @@ -0,0 +1,605 @@ +{ + + "meta": { + "title": "Eventre" + }, + "theme": { + "primaryColor": "#ff7700", + "secondaryColor": "#1d1546", + "textColor": "#222222", + "bodyTextColor": "#848484", + "backgroundColor": "#ffffff", + "sectionBackground": "#fafafa", + + "buttonBackground": "#ff6600", + "buttonText": "#ffffff", + + "navbarBackground": "#ffffff", + "navbarText": "#222222", + "navbarActive": "#ff6600", + + "footerBackground": "#111111", + "footerText": "#ffffff" + }, + "sections": { + "navbar": { + "show": true, + "logo": "images/logo.png", + "logoAlt": "logo", + + "homeLabel": "Home", + "homeUrl": "#home", + + "aboutLabel": "About Us", + "aboutUrl": "#about", + + "speakersLabel": "Speakers", + "speakersUrl": "#speakers", + + "scheduleLabel": "Schedule", + "scheduleUrl": "#schedule", + + "contactLabel": "Contact", + "contactUrl": "#registration", + + "sponsorsLabel": "Sponsors", + "sponsorsUrl": "#sponsors", + + "newsLabel": "News", + "newsUrl": "#news", + + "ticketIcon": "images/icon/ticket.png", + "ticketText": "Buy Ticket", + "ticketUrl": "#" +}, + "banner": { + "show": true, + "title": "Business", + "subtitle": "Conference 2026", + "eventDetails": "17-22 July 2026 California", + "buttonText": "book ticket now", + "buttonUrl": "#" + }, + "about": { + "show": true, + "image": "images/speakers/featured-speaker.jpg", + "imageAlt": "Eventre", + "title": "About The", + "highlightTitle": "Eventre", + "descriptionOne": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud exercitation ullamco.", + "descriptionTwo": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmtempor incididunt ut labore et dolore magna aliq enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea.", + "primaryButtonText": "Buy ticket", + "primaryButtonUrl": "#", + "secondaryButtonText": "Read more", + "secondaryButtonUrl": "#" + }, + "speakers": { + "show": true, + "title": "Who", + "highlightTitle": "Speaking?", + "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore", + "speakers": [ + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-one.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-two.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-three.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-four.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-five.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-six.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-five.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-six.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + } + ] + }, + "schedule": { + "show": true, + "title": "Event", + "highlightTitle": "Schedule", + "description": "Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore", + "timeHeading": "Time", + "speakerHeading": "Speaker", + "subjectHeading": "Subject", + "venueHeading": "Venue", + "days": [ + { + "id": "nov20", + "label": "Day-01", + "date": "20 November 2017", + "active": true, + "sessions": [ + { + "time": "9.00 AM", + "speakerName": "Samanta Doe", + "speakerImage": "images/speakers/speaker-thumb-one.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium A" + }, + { + "time": "10.00 AM", + "speakerName": "Zerad Pawel", + "speakerImage": "images/speakers/speaker-thumb-two.jpg", + "subject": "Principle of Wp", + "venue": "Auditorium B" + }, + { + "time": "12.00 AM", + "speakerName": "Henry Mong", + "speakerImage": "images/speakers/speaker-thumb-three.jpg", + "subject": "Wp Requirements", + "venue": "Auditorium C" + }, + { + "time": "2.00 PM", + "speakerName": "Baily Leo", + "speakerImage": "images/speakers/speaker-thumb-four.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium D" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-five.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-six.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + } + ] + }, + { + "id": "nov21", + "label": "Day-02", + "date": "21 November 2017", + "active": false, + "sessions": [ + { + "time": "9.00 AM", + "speakerName": "Samanta Doe", + "speakerImage": "images/speakers/speaker-thumb-one.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium A" + }, + { + "time": "9.00 AM", + "speakerName": "Samanta Doe", + "speakerImage": "images/speakers/speaker-thumb-one.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium A" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-five.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-six.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + } + ] + }, + { + "id": "nov22", + "label": "Day-03", + "date": "22 November 2017", + "active": false, + "sessions": [ + { + "time": "9.00 AM", + "speakerName": "Samanta Doe", + "speakerImage": "images/speakers/speaker-thumb-one.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium A" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-five.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-six.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + } + ] + } + ] + }, + "registration": { + "show": true, + "services": [ + { + "icon": "fa fa-microphone", + "text": "8 Speakers" + }, + { + "icon": "fa fa-flag", + "text": "500 + Seats" + }, + { + "icon": "fa fa-ticket", + "text": "300 tickets" + }, + { + "icon": "fa fa-calendar", + "text": "3 days event" + } + ], + "title": "Get Register to", + "highlightTitle": "Eventre", + "description": "Demo description ", + "namePlaceholder": "Your Name", + "emailPlaceholder": "Email", + "phonePlaceholder": "Phone", + "ticketPlaceholder": "Ticket Type", + "ticketOptions": [ + { + "value": "1", + "label": "1" + }, + { + "value": "2", + "label": "2" + }, + { + "value": "3", + "label": "3" + }, + { + "value": "4", + "label": "4" + }, + { + "value": "5", + "label": "5" + } + ], + "buttonText": "Register Here" + }, + "pricing": { + "show": true, + "title": "Get", + "highlightTitle": "ticket", + "description": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore", + "plans": [ + { + "title": "Starter", + "price": "39.00", + "currency": "$", + "priceLabel": "/Person", + "featured": false, + "center": false, + "buttonText": "Buy a ticket", + "buttonUrl": "#", + "features": [ + { + "text": "1 Comfortable Seats", + "available": true + }, + { + "text": "Free Lunch and Coffee", + "available": true + }, + { + "text": "Certificate", + "available": false + }, + { + "text": "Easy Access", + "available": false + } + ] + }, + { + "title": "Standard", + "price": "49.00", + "currency": "$", + "priceLabel": "/Person", + "featured": true, + "center": false, + "buttonText": "Buy a ticket", + "buttonUrl": "#", + "features": [ + { + "text": "1 Comfortable Seats", + "available": true + }, + { + "text": "Free Lunch and Coffee", + "available": true + }, + { + "text": "Certificate", + "available": true + }, + { + "text": "Easy Access", + "available": false + } + ] + }, + { + "title": "Platinum", + "price": "99.00", + "currency": "$", + "priceLabel": "/Person", + "featured": false, + "center": true, + "buttonText": "Buy a ticket", + "buttonUrl": "#", + "features": [ + { + "text": "1 Comfortable Seats", + "available": true + }, + { + "text": "Free Lunch and Coffee", + "available": true + }, + { + "text": "Certificate", + "available": true + }, + { + "text": "Easy Access", + "available": true + } + ] + } + ] + }, + "ctaTicket": { + "show": true, + "title": "Get Ticket", + "highlightTitle": "Now!", + "description": "Lorem ipsum dolor sit amet consectetur adipisicing elit", + "buttonText": "Buy ticket", + "buttonUrl": "#", + "image": "images/speakers/speaker-ticket.png", + "imageAlt": "Ticket Speaker" + }, + "sponsors": { + "show": true, + "title": "Our", + "highlightTitle": "Sponsors", + "description": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore dolore", + "groups": [ + { + "title": "Platinum Sponsors", + "sponsors": [ + { + "image": "images/sponsors/pt-spon-two.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/pt-spon-two.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/pt-spon-three.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/pt-spon-four.png", + "alt": "sponsors-logo", + "url": "#" + } + ] + }, + { + "title": "Gold Sponsors", + "sponsors": [ + { + "image": "images/sponsors/gl-spon-one.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/gl-spon-two.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/gl-spon-three.png", + "alt": "sponsors-logo", + "url": "#" + } + ] + } + ], + "buttonText": "Become a sponsor", + "buttonUrl": "#" + }, + "news": { + "show": true, + "title": "Eventre", + "highlightTitle": "News", + "description": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore dolore", + "posts": [ + { + "image": "images/news/post-thumb-one.jpg", + "imageAlt": "post-image", + "day": "20", + "month": "May", + "title": "Elementum purus id ultrices.", + "postUrl": "#", + "author": "Admin", + "authorUrl": "#", + "likes": "350", + "likesUrl": "#", + "comments": "30", + "commentsUrl": "#", + "columnClass": "col-lg-4 col-md-6 col-sm-8 col-10 m-auto" + }, + { + "image": "images/news/post-thumb-two.jpg", + "imageAlt": "post-image", + "day": "20", + "month": "May", + "title": "Elementum purus id ultrices.", + "postUrl": "#", + "author": "Admin", + "authorUrl": "#", + "likes": "350", + "likesUrl": "#", + "comments": "30", + "commentsUrl": "#", + "columnClass": "col-lg-4 col-md-6 col-sm-8 col-10 m-auto" + }, + { + "image": "images/news/post-thumb-three.jpg", + "imageAlt": "post-image", + "day": "20", + "month": "May", + "title": "Elementum purus id ultrices.", + "postUrl": "#", + "author": "Admin", + "authorUrl": "#", + "likes": "350", + "likesUrl": "#", + "comments": "30", + "commentsUrl": "#", + "columnClass": "col-lg-4 col-md-6 m-md-auto col-sm-8 col-10 m-auto" + } + ] + }, + "subscribe": { + "show": true, + "title": "Subscribe to Our", + "highlightTitle": "Newsletter", + "description": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor", + "emailPlaceholder": "Email", + "buttonText": "Subscribe" + }, + "map": { + "show": true, + "embedUrl": "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d199267.57537573267!2d73.7098078914174!3d18.503508757047037!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3bc2bf2e67461101%3A0x828d43bf9d9ee343!2sPune%2C%20Maharashtra!5e1!3m2!1sen!2sin!4v1784028866733!5m2!1sen!2sin", + "venueName": "Docklands Convention", + "address": "1201 Park Street, Fifth Avenue, Dhanmondy, Dhaka.", + "phone": "[88] 657 524 332", + "buttonText": "Get Direction", + "buttonUrl": "#" + }, + "footer": { + "show": true, + "logo": "images/footer-logo.png", + "logoAlt": "logo", + "socialLinks": [ + { + "icon": "fa fa-facebook", + "url": "#" + }, + { + "icon": "fa fa-twitter", + "url": "#" + }, + { + "icon": "fa fa-instagram", + "url": "#" + }, + { + "icon": "fa fa-rss", + "url": "#" + }, + { + "icon": "fa fa-vimeo", + "url": "#" + } + ] + }, + "subfooter": { + "show": true, + "brandName": "Eventre -", + "brandUrl": "#", + "copyrightText": "Eventbuzz © 2026 All Right Reserved", + "topUrl": "#", + "topIcon": "fa fa-angle-up" + } + } +} \ No newline at end of file diff --git a/microsite-v2-templates/eventre/template.html b/microsite-v2-templates/eventre/template.html new file mode 100644 index 0000000..568e952 --- /dev/null +++ b/microsite-v2-templates/eventre/template.html @@ -0,0 +1,1169 @@ + + + + + + + + + + Eventre + + + + + + + + + + + + + + + + + + + + + + + + + + +{{#if_show sections.navbar}} + + + +{{/if_show}} + + + + + + + +{{#if_show sections.banner}} + + + +{{/if_show}} + + + + +{{#if_show sections.about}} + +
+
+
+ +
+
+ {{sections.about.imageAlt}} +
+
+ +
+
+ +

+ {{sections.about.title}} + + {{sections.about.highlightTitle}} + +

+ +
+

+ {{sections.about.descriptionOne}} +

+
+ +
+

+ {{sections.about.descriptionTwo}} +

+
+ + + +
+
+ +
+
+
+ +{{/if_show}} + + + + +{{#if_show sections.speakers}} + +
+
+ +
+
+
+

+ {{sections.speakers.title}} + + {{sections.speakers.highlightTitle}} + +

+ +

{{sections.speakers.description}}

+
+
+
+ +
+ + {{#each sections.speakers.speakers}} + +
+
+ +
+ {{name}} + +
+ +
+ +
+
+ +
+
+ + {{name}} + +
+ +

{{designation}}

+
+ +
+
+ + {{/each}} + +
+ +
+
+ +{{/if_show}} + + + + +{{#if_show sections.schedule}} + +
+
+ +
+
+
+

+ {{sections.schedule.title}} + + {{sections.schedule.highlightTitle}} + +

+ +

{{sections.schedule.description}}

+
+
+
+ +
+
+ +
+ +
+ +
+
+ + {{#each sections.schedule.days}} + +
+
    + +
  • +
    + {{@root.sections.schedule.timeHeading}} +
    + +
    + {{@root.sections.schedule.speakerHeading}} +
    + +
    + {{@root.sections.schedule.subjectHeading}} +
    + +
    + {{@root.sections.schedule.venueHeading}} +
    +
  • + + {{#each sessions}} + +
  • +
    + +
    + + {{time}} +
    + +
    + {{speakerName}} + {{speakerName}} +
    + +
    + {{subject}} +
    + +
    + {{venue}} +
    + +
    +
  • + + {{/each}} + +
+
+ + {{/each}} + +
+
+ +
+
+ +
+
+ +{{/if_show}} + + + + +{{#if_show sections.registration}} + +
+
+
+ +
+
+
+ + {{#each sections.registration.services}} + +
+
+ +
{{text}}
+
+
+ + {{/each}} + +
+
+
+ +
+
+
+ +
+

+ {{sections.registration.title}} + + {{sections.registration.highlightTitle}} + +

+ +

{{sections.registration.description}}

+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + +
+
+ +
+ +
+ +
+ +
+
+
+ +
+
+
+ +{{/if_show}} + + + + + +{{#if_show sections.pricing}} + +
+
+ +
+
+
+ +

+ {{sections.pricing.title}} + + {{sections.pricing.highlightTitle}} + +

+ +

{{sections.pricing.description}}

+ +
+
+
+ +
+ + {{#each sections.pricing.plans}} + +
+ +
+ +
+ +
+
{{title}}
+
+ +
+

+ {{price}}{{currency}} +

+ +

{{priceLabel}}

+
+ +
+ +
+ +
    + + {{#each features}} + +
  • +

    + + {{#if available}} + + + + {{else}} + + + + {{/if}} + + {{text}} + +

    +
  • + + {{/each}} + +
+ +
+ + + +
+ +
+ + {{/each}} + +
+ +
+
+ +{{/if_show}} + + + + + +{{#if_show sections.ctaTicket}} + +
+
+
+ +
+
+ +

+ {{sections.ctaTicket.title}} + + {{sections.ctaTicket.highlightTitle}} + +

+ +

{{sections.ctaTicket.description}}

+ + + {{sections.ctaTicket.buttonText}} + + +
+
+ +
+
+ +
+ {{sections.ctaTicket.imageAlt}} +
+ +
+ +{{/if_show}} + + + + + +{{#if_show sections.sponsors}} + +
+
+ +
+
+
+ +

+ {{sections.sponsors.title}} + + {{sections.sponsors.highlightTitle}} + +

+ +

{{sections.sponsors.description}}

+ +
+
+
+ +
+
+ + {{#each sections.sponsors.groups}} + + + +
+
    + + {{#each sponsors}} + +
  • +
    + + + {{alt}} + + +
    +
  • + + {{/each}} + +
+
+ + {{/each}} + + + +
+
+ +
+
+ +{{/if_show}} + + + + +{{#if_show sections.news}} + +
+
+ +
+
+
+ +

+ {{sections.news.title}} + + {{sections.news.highlightTitle}} + +

+ +

{{sections.news.description}}

+ +
+
+
+ +
+ + {{#each sections.news.posts}} + +
+
+ +
+ + {{imageAlt}} + +
+ +
+ +
+

+ {{day}} + {{month}} +

+
+ +
+

+ + {{title}} + +

+
+ + + +
+
+
+ + {{/each}} + +
+ +
+
+ +{{/if_show}} + + + + +{{#if_show sections.subscribe}} + +
+
+
+ +
+
+ +

+ {{sections.subscribe.title}} + + {{sections.subscribe.highlightTitle}} + +

+ +

{{sections.subscribe.description}}

+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ +{{/if_show}} + + + + +{{#if_show sections.map}} + +
+ + +
+ +

{{sections.map.venueName}}

+ +
    + +
  • + + {{sections.map.address}} +
  • + +
  • + + {{sections.map.phone}} +
  • + +
+ + + {{sections.map.buttonText}} + + +
+ +
+ +{{/if_show}} + + + + +{{#if_show sections.footer}} + +
+
+
+ +
+
+ + + + + +
+
+ +
+
+
+ +{{/if_show}} + + +{{#if_show sections.subfooter}} + + + +{{/if_show}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/microsite-v2-templates/eventre/template.json b/microsite-v2-templates/eventre/template.json new file mode 100644 index 0000000..03015c1 --- /dev/null +++ b/microsite-v2-templates/eventre/template.json @@ -0,0 +1,1099 @@ +{ + "version": "1.0", + "meta": { + "title": "Eventre" + }, + + "sections": [ + { + "id": "theme", + "label": "Theme", + "show": true, + "fields": [ + { + "key": "primaryColor", + "label": "Primary Color", + "type": "color", + "default": "#ff6600" + }, + { + "key": "secondaryColor", + "label": "Secondary Color", + "type": "color", + "default": "#1d1546" + }, + { + "key": "textColor", + "label": "Heading Color", + "type": "color", + "default": "#222222" + }, + { + "key": "bodyTextColor", + "label": "Body Text Color", + "type": "color", + "default": "#848484" + },{ + + "key": "sectionBackground", + "label": "Section Background", + "type": "color", + "default": "#fafafa" + }, + { + "key": "buttonBackground", + "label": "Button Background", + "type": "color", + "default": "#ff6600" + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "color", + "default": "#ffffff" + } + ] +}, + { + "id": "navbar", + "label": "Navbar", + "show": true, + "fields": [ + { + "key": "logo", + "label": "Logo", + "type": "image", + "default": "images/logo.png" + }, + { + "key": "logoAlt", + "label": "Logo Alt Text", + "type": "text", + "default": "logo" + }, + { + "key": "homeLabel", + "label": "Home Label", + "type": "text", + "default": "Home" + }, + { + "key": "homeUrl", + "label": "Home URL", + "type": "text", + "default": "#home" + }, + { + "key": "aboutLabel", + "label": "About Label", + "type": "text", + "default": "About Us" + }, + { + "key": "aboutUrl", + "label": "About URL", + "type": "text", + "default": "#about" + }, + { + "key": "speakersLabel", + "label": "Speakers Label", + "type": "text", + "default": "Speakers" + }, + { + "key": "speakersUrl", + "label": "Speakers URL", + "type": "text", + "default": "#speakers" + }, + { + "key": "scheduleLabel", + "label": "Schedule Label", + "type": "text", + "default": "Schedule" + }, + { + "key": "scheduleUrl", + "label": "Schedule URL", + "type": "text", + "default": "#schedule" + }, + { + "key": "contactLabel", + "label": "Contact Label", + "type": "text", + "default": "Contact" + }, + { + "key": "contactUrl", + "label": "Contact URL", + "type": "text", + "default": "#registration" + }, + { + "key": "sponsorsLabel", + "label": "Sponsors Label", + "type": "text", + "default": "Sponsors" + }, + { + "key": "sponsorsUrl", + "label": "Sponsors URL", + "type": "text", + "default": "#sponsors" + }, + { + "key": "newsLabel", + "label": "News Label", + "type": "text", + "default": "News" + }, + { + "key": "newsUrl", + "label": "News URL", + "type": "text", + "default": "#news" + }, + { + "key": "ticketIcon", + "label": "Ticket Icon", + "type": "image", + "default": "images/icon/ticket.png" + }, + { + "key": "ticketText", + "label": "Ticket Text", + "type": "text", + "default": "Buy Ticket" + }, + { + "key": "ticketUrl", + "label": "Ticket URL", + "type": "text", + "default": "#" + } + ] +}, + { + "id": "banner", + "label": "Banner", + "show": true, + "fields": [ + { + "key": "title", + "label": "Banner Title", + "type": "text", + "default": "Business" + }, + { + "key": "subtitle", + "label": "Banner Subtitle", + "type": "text", + "default": "Conference 2017" + }, + { + "key": "eventDetails", + "label": "Event Date and Location", + "type": "text", + "default": "02-05 July 2017 California" + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "text", + "default": "get ticket now" + }, + { + "key": "buttonUrl", + "label": "Button URL", + "type": "text", + "default": "#" + } + ] + }, + { + "id": "about", + "label": "About", + "show": true, + "fields": [ + { + "key": "image", + "label": "About Image", + "type": "image", + "default": "images/speakers/featured-speaker.jpg" + }, + { + "key": "imageAlt", + "label": "Image Alt Text", + "type": "text", + "default": "Eventre" + }, + { + "key": "title", + "label": "Title", + "type": "text", + "default": "About The" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Eventre" + }, + { + "key": "descriptionOne", + "label": "Description One", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm tempor incididunt ut labore dolore magna aliqua enim ad minim veniam quis nostrud exercitation ullamco." + }, + { + "key": "descriptionTwo", + "label": "Description Two", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmtempor incididunt ut labore et dolore magna aliq enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea." + }, + { + "key": "primaryButtonText", + "label": "Primary Button Text", + "type": "text", + "default": "Buy ticket" + }, + { + "key": "primaryButtonUrl", + "label": "Primary Button URL", + "type": "text", + "default": "#" + }, + { + "key": "secondaryButtonText", + "label": "Secondary Button Text", + "type": "text", + "default": "Read more" + }, + { + "key": "secondaryButtonUrl", + "label": "Secondary Button URL", + "type": "text", + "default": "#" + } + ] + }, + { + "id": "speakers", + "label": "Speakers", + "show": true, + "fields": [ + { + "key": "title", + "label": "Section Title", + "type": "text", + "default": "Who" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Speaking?" + }, + { + "key": "description", + "label": "Section Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore" + }, + { + "key": "speakers", + "label": "Speakers", + "type": "array", + "default": [ + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-one.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-two.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-three.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-four.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-five.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-six.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-five.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + }, + { + "name": "Johnathan Franco", + "designation": "Project Manager", + "image": "images/speakers/speaker-six.jpg", + "profileUrl": "#", + "facebookUrl": "#", + "twitterUrl": "#", + "linkedinUrl": "#", + "pinterestUrl": "#" + } + ] + } + ] + }, + { + "id": "schedule", + "label": "Event Schedule", + "show": true, + "fields": [ + { + "key": "title", + "label": "Section Title", + "type": "text", + "default": "Event" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Schedule" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet, consectetur adipisicing elit sed do eiusm tempor incididunt ut labore" + }, + { + "key": "timeHeading", + "label": "Time Heading", + "type": "text", + "default": "Time" + }, + { + "key": "speakerHeading", + "label": "Speaker Heading", + "type": "text", + "default": "Speaker" + }, + { + "key": "subjectHeading", + "label": "Subject Heading", + "type": "text", + "default": "Subject" + }, + { + "key": "venueHeading", + "label": "Venue Heading", + "type": "text", + "default": "Venue" + }, + { + "key": "days", + "label": "Schedule Days", + "type": "array", + "default": [ + { + "id": "nov20", + "label": "Day-01", + "date": "20 November 2017", + "active": true, + "sessions": [ + { + "time": "9.00 AM", + "speakerName": "Samanta Doe", + "speakerImage": "images/speakers/speaker-thumb-one.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium A" + }, + { + "time": "10.00 AM", + "speakerName": "Zerad Pawel", + "speakerImage": "images/speakers/speaker-thumb-two.jpg", + "subject": "Principle of Wp", + "venue": "Auditorium B" + }, + { + "time": "12.00 AM", + "speakerName": "Henry Mong", + "speakerImage": "images/speakers/speaker-thumb-three.jpg", + "subject": "Wp Requirements", + "venue": "Auditorium C" + }, + { + "time": "2.00 PM", + "speakerName": "Baily Leo", + "speakerImage": "images/speakers/speaker-thumb-four.jpg", + "subject": "Introduction to Wp", + "venue": "Auditorium D" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-five.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + }, + { + "time": "3.00 PM", + "speakerName": "Lee Mun", + "speakerImage": "images/speakers/speaker-thumb-six.jpg", + "subject": "Useful tips for Wp", + "venue": "Auditorium E" + } + ] + }, + { + "id": "nov21", + "label": "Day-02", + "date": "21 November 2017", + "active": false, + "sessions": [] + }, + { + "id": "nov22", + "label": "Day-03", + "date": "22 November 2017", + "active": false, + "sessions": [] + } + ] + } + ] + }, + { + "id": "registration", + "label": "Registration", + "show": true, + "fields": [ + { + "key": "services", + "label": "Event Stats", + "type": "array", + "default": [ + { + "icon": "fa fa-microphone", + "text": "8 Speakers" + }, + { + "icon": "fa fa-flag", + "text": "500 + Seats" + }, + { + "icon": "fa fa-ticket", + "text": "300 tickets" + }, + { + "icon": "fa fa-calendar", + "text": "3 days event" + } + ] + }, + { + "key": "title", + "label": "Registration Title", + "type": "text", + "default": "Register to" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Eventre" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet, consectetur adipisicing elit" + }, + { + "key": "namePlaceholder", + "label": "Name Placeholder", + "type": "text", + "default": "Your Name" + }, + { + "key": "emailPlaceholder", + "label": "Email Placeholder", + "type": "text", + "default": "Email" + }, + { + "key": "phonePlaceholder", + "label": "Phone Placeholder", + "type": "text", + "default": "Phone" + }, + { + "key": "ticketPlaceholder", + "label": "Ticket Placeholder", + "type": "text", + "default": "Ticket Type" + }, + { + "key": "ticketOptions", + "label": "Ticket Options", + "type": "array", + "default": [ + { "value": "1", "label": "1" }, + { "value": "2", "label": "2" }, + { "value": "3", "label": "3" }, + { "value": "4", "label": "4" }, + { "value": "5", "label": "5" } + ] + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "text", + "default": "Register Now" + } + ] + }, + { + "id": "pricing", + "label": "Pricing", + "show": true, + "fields": [ + { + "key": "title", + "label": "Section Title", + "type": "text", + "default": "Get" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "ticket" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore" + }, + { + "key": "plans", + "label": "Pricing Plans", + "type": "array", + "default": [ + { + "title": "Starter", + "price": "39.00", + "currency": "$", + "priceLabel": "/Person", + "featured": false, + "center": false, + "buttonText": "Buy a ticket", + "buttonUrl": "#", + "features": [ + { + "text": "1 Comfortable Seats", + "available": true + }, + { + "text": "Free Lunch and Coffee", + "available": true + }, + { + "text": "Certificate", + "available": false + }, + { + "text": "Easy Access", + "available": false + } + ] + }, + { + "title": "Standard", + "price": "49.00", + "currency": "$", + "priceLabel": "/Person", + "featured": true, + "center": false, + "buttonText": "Buy a ticket", + "buttonUrl": "#", + "features": [ + { + "text": "1 Comfortable Seats", + "available": true + }, + { + "text": "Free Lunch and Coffee", + "available": true + }, + { + "text": "Certificate", + "available": true + }, + { + "text": "Easy Access", + "available": false + } + ] + }, + { + "title": "Platinum", + "price": "99.00", + "currency": "$", + "priceLabel": "/Person", + "featured": false, + "center": true, + "buttonText": "Buy a ticket", + "buttonUrl": "#", + "features": [ + { + "text": "1 Comfortable Seats", + "available": true + }, + { + "text": "Free Lunch and Coffee", + "available": true + }, + { + "text": "Certificate", + "available": true + }, + { + "text": "Easy Access", + "available": true + } + ] + } + ] + } + ] + }, + { + "id": "ctaTicket", + "label": "CTA Ticket", + "show": true, + "fields": [ + { + "key": "title", + "label": "Title", + "type": "text", + "default": "Get Ticket" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Now!" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusmtempor incidi" + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "text", + "default": "Buy ticket" + }, + { + "key": "buttonUrl", + "label": "Button URL", + "type": "text", + "default": "#" + }, + { + "key": "image", + "label": "Speaker Image", + "type": "image", + "default": "images/speakers/speaker-ticket.png" + }, + { + "key": "imageAlt", + "label": "Image Alt Text", + "type": "text", + "default": "Ticket Speaker" + } + ] + }, + { + "id": "sponsors", + "label": "Sponsors", + "show": true, + "fields": [ + { + "key": "title", + "label": "Section Title", + "type": "text", + "default": "Our" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Sponsors" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore dolore" + }, + { + "key": "groups", + "label": "Sponsor Groups", + "type": "array", + "default": [ + { + "title": "Platinum Sponsors", + "sponsors": [ + { + "image": "images/sponsors/pt-spon-two.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/pt-spon-two.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/pt-spon-three.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/pt-spon-four.png", + "alt": "sponsors-logo", + "url": "#" + } + ] + }, + { + "title": "Gold Sponsors", + "sponsors": [ + { + "image": "images/sponsors/gl-spon-one.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/gl-spon-two.png", + "alt": "sponsors-logo", + "url": "#" + }, + { + "image": "images/sponsors/gl-spon-three.png", + "alt": "sponsors-logo", + "url": "#" + } + ] + } + ] + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "text", + "default": "Become a sponsor" + }, + { + "key": "buttonUrl", + "label": "Button URL", + "type": "text", + "default": "#" + } + ] + }, + { + "id": "news", + "label": "News", + "show": true, + "fields": [ + { + "key": "title", + "label": "Section Title", + "type": "text", + "default": "Eventre" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "News" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor incididunt ut labore dolore" + }, + { + "key": "posts", + "label": "News Posts", + "type": "array", + "default": [ + { + "image": "images/news/post-thumb-one.jpg", + "imageAlt": "post-image", + "day": "20", + "month": "May", + "title": "Elementum purus id ultrices.", + "postUrl": "#", + "author": "Admin", + "authorUrl": "#", + "likes": "350", + "likesUrl": "#", + "comments": "30", + "commentsUrl": "#", + "columnClass": "col-lg-4 col-md-6 col-sm-8 col-10 m-auto" + }, + { + "image": "images/news/post-thumb-two.jpg", + "imageAlt": "post-image", + "day": "20", + "month": "May", + "title": "Elementum purus id ultrices.", + "postUrl": "#", + "author": "Admin", + "authorUrl": "#", + "likes": "350", + "likesUrl": "#", + "comments": "30", + "commentsUrl": "#", + "columnClass": "col-lg-4 col-md-6 col-sm-8 col-10 m-auto" + }, + { + "image": "images/news/post-thumb-three.jpg", + "imageAlt": "post-image", + "day": "20", + "month": "May", + "title": "Elementum purus id ultrices.", + "postUrl": "#", + "author": "Admin", + "authorUrl": "#", + "likes": "350", + "likesUrl": "#", + "comments": "30", + "commentsUrl": "#", + "columnClass": "col-lg-4 col-md-6 m-md-auto col-sm-8 col-10 m-auto" + } + ] + } + ] + }, + { + "id": "subscribe", + "label": "Newsletter Subscribe", + "show": true, + "fields": [ + { + "key": "title", + "label": "Section Title", + "type": "text", + "default": "Subscribe to Our" + }, + { + "key": "highlightTitle", + "label": "Highlighted Title", + "type": "text", + "default": "Newsletter" + }, + { + "key": "description", + "label": "Description", + "type": "textarea", + "default": "Lorem ipsum dolor sit amet consectetur adipisicing elit sed do eiusm tempor" + }, + { + "key": "emailPlaceholder", + "label": "Email Placeholder", + "type": "text", + "default": "Email" + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "text", + "default": "Subscribe" + } + ] + }, + { + "id": "map", + "label": "Map & Address", + "show": true, + "fields": [ + { + "key": "embedUrl", + "label": "Google Map Embed URL", + "type": "text", + "default": "https://www.google.com/maps?q=Pune,Maharashtra&output=embed" + }, + { + "key": "venueName", + "label": "Venue Name", + "type": "text", + "default": "Docklands Convention" + }, + { + "key": "address", + "label": "Address", + "type": "textarea", + "default": "1201 Park Street, Fifth Avenue, Dhanmondy, Dhaka." + }, + { + "key": "phone", + "label": "Phone Number", + "type": "text", + "default": "[88] 657 524 332" + }, + { + "key": "buttonText", + "label": "Button Text", + "type": "text", + "default": "Get Direction" + }, + { + "key": "buttonUrl", + "label": "Button URL", + "type": "text", + "default": "#" + } + ] +}, + { + "id": "footer", + "label": "Footer", + "show": true, + "fields": [ + { + "key": "logo", + "label": "Footer Logo", + "type": "image", + "default": "images/footer-logo.png" + }, + { + "key": "logoAlt", + "label": "Logo Alt Text", + "type": "text", + "default": "logo" + }, + { + "key": "socialLinks", + "label": "Social Links", + "type": "array", + "default": [ + { + "icon": "fa fa-facebook", + "url": "#" + }, + { + "icon": "fa fa-twitter", + "url": "#" + }, + { + "icon": "fa fa-instagram", + "url": "#" + }, + { + "icon": "fa fa-rss", + "url": "#" + }, + { + "icon": "fa fa-vimeo", + "url": "#" + } + ] + } + ] + }, + { + "id": "subfooter", + "label": "Subfooter", + "show": true, + "fields": [ + { + "key": "brandName", + "label": "Brand Name", + "type": "text", + "default": "Eventre" + }, + { + "key": "brandUrl", + "label": "Brand URL", + "type": "text", + "default": "#" + }, + { + "key": "copyrightText", + "label": "Copyright Text", + "type": "text", + "default": "© 2017 All Right Reserved" + }, + { + "key": "topUrl", + "label": "Back To Top URL", + "type": "text", + "default": "#" + }, + { + "key": "topIcon", + "label": "Back To Top Icon", + "type": "text", + "default": "fa fa-angle-up" + } + ] + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index e7f26a7..e9f7932 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,13 @@ "backfill:form-submission-files": "node scripts/backfill-form-submission-files.js", "seed:microsite-v2-template": "node scripts/seed-microsite-v2-template.js", "seed:crest-novel-template": "node scripts/seed-crest-novel-template.js", + "seed:global-microsite-v2-templates": "node scripts/seed-global-microsite-v2-templates.js", + "seed:eventify-template": "node scripts/seed-global-microsite-v2-templates.js --slug=eventify", + "seed:eventre-template": "node scripts/seed-global-microsite-v2-templates.js --slug=eventre", "setup:crest-novel-microsite": "node scripts/setup-crest-novel-microsite.js", + "parse:novel-schedule-csv": "node scripts/parse-novel-schedule-csv.js", + "import:novel-schedule-agenda": "node scripts/import-novel-schedule-agenda.js", + "setup:goa-8-9-microsite": "node scripts/setup-goa-8-9-microsite.js", "email-worker": "node src/workers/emailQueueWorker.js", "whatsapp-worker": "node src/workers/whatsappQueueWorker.js", "concierge-ingest-worker": "node ../chatbot/workers/ingest.js", diff --git a/scripts/ensure-participant-soft-delete-index.js b/scripts/ensure-participant-soft-delete-index.js new file mode 100644 index 0000000..1d570c6 --- /dev/null +++ b/scripts/ensure-participant-soft-delete-index.js @@ -0,0 +1,44 @@ +/** + * Ensure soft-delete field + unique email index only among active participants. + * Usage (from backend/): node scripts/ensure-participant-soft-delete-index.js + */ +require('dotenv').config(); +const mongoose = require('mongoose'); +const Participant = require('../src/models/Participant'); + +async function main() { + const uri = process.env.MONGODB_URI || process.env.MONGO_URI; + if (!uri) { + console.error('Set MONGODB_URI or MONGO_URI'); + process.exit(1); + } + await mongoose.connect(uri); + const col = mongoose.connection.collection('participants'); + + const backfill = await col.updateMany( + { deletedAt: { $exists: false } }, + { $set: { deletedAt: null } } + ); + console.log(`Backfilled deletedAt=null on ${backfill.modifiedCount} participants`); + + const indexes = await col.indexes(); + for (const idx of indexes) { + if (idx.name === 'tenantOrganization_1_email_1') { + try { + await col.dropIndex('tenantOrganization_1_email_1'); + console.log('Dropped legacy index tenantOrganization_1_email_1'); + } catch (e) { + console.warn('Could not drop legacy index:', e.message); + } + } + } + + const synced = await Participant.syncIndexes(); + console.log('syncIndexes:', synced); + await mongoose.disconnect(); +} + +main().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/import-novel-schedule-agenda.js b/scripts/import-novel-schedule-agenda.js new file mode 100644 index 0000000..686f230 --- /dev/null +++ b/scripts/import-novel-schedule-agenda.js @@ -0,0 +1,58 @@ +#!/usr/bin/env node +/** + * Import NOVEL schedule CSV into event agenda (Session documents). + * + * Usage: + * node scripts/import-novel-schedule-agenda.js [--csv=path] [--event-id=id] + */ +const path = require('path'); +require('dotenv').config({ path: path.join(__dirname, '..', '.env') }); +const fs = require('fs'); +const mongoose = require('mongoose'); +const { connectDB } = require('../src/config/database'); +const Event = require('../src/models/Event'); +const { parseNovelScheduleCsv } = require('../src/utils/parseNovelScheduleCsv'); +const { importNovelScheduleToAgenda } = require('../src/utils/importNovelScheduleAgenda'); + +const DEFAULT_EVENT_ID = '6a43e05fdc940a0d6e057f7b'; +const DEFAULT_CSV = path.join(__dirname, '..', '..', 'novel2026-goa-7-8-aug.csv'); + +function argValue(name, fallback) { + const hit = process.argv.find((a) => a.startsWith(`--${name}=`)); + return hit ? hit.split('=').slice(1).join('=').trim() : fallback; +} + +async function main() { + const eventId = argValue('event-id', DEFAULT_EVENT_ID); + const csvPath = argValue('csv', DEFAULT_CSV); + + if (!mongoose.Types.ObjectId.isValid(eventId)) { + throw new Error(`Invalid event id: ${eventId}`); + } + if (!fs.existsSync(csvPath)) { + throw new Error(`CSV not found: ${csvPath}`); + } + + await connectDB(); + + const event = await Event.findById(eventId).lean(); + if (!event) throw new Error(`Event not found: ${eventId}`); + + const text = fs.readFileSync(csvPath, 'utf8'); + const { days } = parseNovelScheduleCsv(text, { + dayDates: ['August 7, 2026', 'August 8, 2026'], + }); + + const result = await importNovelScheduleToAgenda(eventId, days); + + console.log(`Deleted ${result.deleted} existing session(s) for event ${eventId}`); + console.log(`Created ${result.created} session(s) for "${event.name}" (track ${result.trackId})`); + console.log(`CSV: ${csvPath}`); + + await mongoose.disconnect(); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/scripts/lib/seedOneMicrositeV2Template.js b/scripts/lib/seedOneMicrositeV2Template.js new file mode 100644 index 0000000..25d8ccf --- /dev/null +++ b/scripts/lib/seedOneMicrositeV2Template.js @@ -0,0 +1,194 @@ +const fs = require('fs'); +const path = require('path'); +const { + uploadTemplateFile, + uploadTemplateAsset, + templateAssetsBaseUrl, +} = require('../../src/utils/s3MicrositeV2'); +const { parseTemplateSchema } = require('../../src/utils/templateSchema'); +require('../../src/models/Organization'); +require('../../src/models/User'); +const MicrositeV2Template = require('../../src/models/MicrositeV2Template'); +const { getGlobalMicrositeV2Template } = require('../../src/config/globalMicrositeV2Templates'); + +const BACKEND_ROOT = path.join(__dirname, '..', '..'); +const TEMPLATES_ROOT = path.join(BACKEND_ROOT, 'microsite-v2-templates'); + +function walkDir(dir, base = dir) { + const files = []; + if (!fs.existsSync(dir)) return files; + for (const name of fs.readdirSync(dir)) { + const full = path.join(dir, name); + const stat = fs.statSync(full); + if (stat.isDirectory()) { + files.push(...walkDir(full, base)); + } else { + files.push({ full, rel: path.relative(base, full).replace(/\\/g, '/') }); + } + } + return files; +} + +function mimeFor(filePath) { + if (filePath.endsWith('.css')) return 'text/css'; + if (filePath.endsWith('.js')) return 'application/javascript'; + if (filePath.endsWith('.woff')) return 'font/woff'; + if (filePath.endsWith('.woff2')) return 'font/woff2'; + if (filePath.endsWith('.ttf')) return 'font/ttf'; + if (filePath.endsWith('.eot')) return 'application/vnd.ms-fontobject'; + if (filePath.endsWith('.png')) return 'image/png'; + if (filePath.endsWith('.jpg') || filePath.endsWith('.jpeg')) return 'image/jpeg'; + if (filePath.endsWith('.svg')) return 'image/svg+xml'; + if (filePath.endsWith('.gif')) return 'image/gif'; + if (filePath.endsWith('.webp')) return 'image/webp'; + return 'application/octet-stream'; +} + +/** IcoMoon exports use filenames like LineIcons.woff?y2l643 — normalize for S3 keys. */ +function normalizeAssetRelPath(rel) { + const base = String(rel).replace(/\\/g, '/'); + const fontsMatch = base.match(/^fonts\/LineIcons\.(woff2?|ttf|eot|svg)\?/i); + if (fontsMatch) { + return `fonts/LineIcons.${fontsMatch[1].toLowerCase()}`; + } + return base; +} + +function svgPlaceholder(label, color) { + const safeLabel = String(label || 'Template').slice(0, 40); + const fill = String(color || '#5c6ac4'); + return Buffer.from( + `${safeLabel}`, + ); +} + +/** + * Upload template files to S3 and upsert MicrositeV2Template row. + * @param {{ slug: string, user: import('mongoose').Document, dbOnly?: boolean }} opts + */ +async function seedOneMicrositeV2Template({ slug, user, dbOnly = false }) { + const def = getGlobalMicrositeV2Template(slug); + if (!def) { + throw new Error(`Unknown global microsite template slug: ${slug}`); + } + + const templateDir = path.join(TEMPLATES_ROOT, def.slug); + const templateAssets = path.join(templateDir, 'assets'); + const htmlPath = path.join(templateDir, 'template.html'); + const jsonPath = path.join(templateDir, 'template.json'); + if (!fs.existsSync(htmlPath) || !fs.existsSync(jsonPath)) { + throw new Error(`Missing template.html or template.json in ${templateDir}`); + } + + const htmlBuf = fs.readFileSync(htmlPath); + const jsonBuf = fs.readFileSync(jsonPath); + const schema = parseTemplateSchema(jsonBuf); + + let htmlS3Key; + let schemaS3Key; + let thumbnailUrl; + let assetsBaseUrl = templateAssetsBaseUrl(def.slug); + + if (!dbOnly && process.env.AWS_BUCKET) { + console.log(`[${def.slug}] Uploading template.html...`); + const htmlUp = await uploadTemplateFile(def.slug, 'template.html', htmlBuf, 'text/html; charset=utf-8'); + htmlS3Key = htmlUp.s3Key; + + console.log(`[${def.slug}] Uploading template.json...`); + const jsonUp = await uploadTemplateFile(def.slug, 'template.json', jsonBuf, 'application/json'); + schemaS3Key = jsonUp.s3Key; + + for (const rel of def.thumbnailCandidates || []) { + const tp = path.join(templateDir, rel); + if (!fs.existsSync(tp)) continue; + const ext = path.extname(tp).slice(1) || 'jpg'; + const thumbUp = await uploadTemplateFile( + def.slug, + `thumbnail.${ext}`, + fs.readFileSync(tp), + `image/${ext === 'jpg' ? 'jpeg' : ext}`, + ); + thumbnailUrl = thumbUp.url; + break; + } + if (!thumbnailUrl) { + const thumbUp = await uploadTemplateFile( + def.slug, + 'thumbnail.svg', + svgPlaceholder(def.placeholderSvgLabel || def.name, def.placeholderSvgColor), + 'image/svg+xml', + ); + thumbnailUrl = thumbUp.url; + } + + const assetRoots = []; + if (fs.existsSync(templateAssets)) assetRoots.push(templateAssets); + for (const externalRel of def.externalAssetRoots || []) { + const externalRoot = path.isAbsolute(externalRel) + ? externalRel + : path.join(BACKEND_ROOT, '..', externalRel); + if (fs.existsSync(externalRoot)) assetRoots.push(externalRoot); + } + + for (const root of assetRoots) { + console.log(`[${def.slug}] Uploading assets from ${root}...`); + for (const { full, rel } of walkDir(root)) { + const normalizedRel = normalizeAssetRelPath(rel); + if (normalizedRel !== rel && fs.existsSync(path.join(root, normalizedRel))) { + continue; + } + await uploadTemplateAsset(def.slug, normalizedRel, fs.readFileSync(full), mimeFor(normalizedRel)); + } + } + + assetsBaseUrl = templateAssetsBaseUrl(def.slug); + console.log(`[${def.slug}] S3 upload complete.`); + } else { + console.log(`[${def.slug}] Skipping S3 upload (--db-only or AWS_BUCKET not set).`); + } + + const existing = await MicrositeV2Template.findOne({ slug: def.slug }).select('_id htmlS3Key schemaS3Key thumbnailUrl').lean(); + const doc = { + slug: def.slug, + name: def.name, + description: def.description, + thumbnailUrl: thumbnailUrl || existing?.thumbnailUrl || '', + htmlS3Key: htmlS3Key || existing?.htmlS3Key || '', + schemaS3Key: schemaS3Key || existing?.schemaS3Key || '', + schema, + assetsBaseUrl, + assetsS3Prefix: `templates/${def.slug}/assets`, + isActive: Boolean((htmlS3Key || existing?.htmlS3Key) && (schemaS3Key || existing?.schemaS3Key)), + version: schema.version || 1, + createdBy: user._id, + }; + + const now = new Date(); + const setFields = { + ...doc, + updatedAt: now, + }; + + await MicrositeV2Template.collection.updateOne( + { slug: def.slug }, + { + $set: setFields, + $setOnInsert: { + allowedOrganizations: [], + visibility: 'public', + createdAt: now, + }, + }, + { upsert: true }, + ); + + const saved = await MicrositeV2Template.findOne({ slug: def.slug }).select('_id slug').lean(); + console.log( + `[${def.slug}] ${existing ? 'Updated' : 'Created'} MicrositeV2Template: ${saved?._id}`, + ); + return saved; +} + +module.exports = { + seedOneMicrositeV2Template, +}; diff --git a/scripts/parse-novel-schedule-csv.js b/scripts/parse-novel-schedule-csv.js new file mode 100644 index 0000000..7369f81 --- /dev/null +++ b/scripts/parse-novel-schedule-csv.js @@ -0,0 +1,35 @@ +#!/usr/bin/env node +/** + * Parse NOVEL schedule CSV to JSON (stdout or --out=file). + * + * Usage: + * node scripts/parse-novel-schedule-csv.js [--csv=path] [--out=path] + */ +const fs = require('fs'); +const path = require('path'); +const { parseNovelScheduleCsv } = require('../src/utils/parseNovelScheduleCsv'); + +function argValue(name, fallback) { + const hit = process.argv.find((a) => a.startsWith(`--${name}=`)); + return hit ? hit.split('=').slice(1).join('=').trim() : fallback; +} + +const defaultCsv = path.join(__dirname, '..', '..', 'novel2026-goa-7-8-aug.csv'); +const csvPath = argValue('csv', defaultCsv); +const outPath = argValue('out', ''); + +if (!fs.existsSync(csvPath)) { + console.error(`CSV not found: ${csvPath}`); + process.exit(1); +} + +const text = fs.readFileSync(csvPath, 'utf8'); +const result = parseNovelScheduleCsv(text); +const json = JSON.stringify(result, null, 2); + +if (outPath) { + fs.writeFileSync(outPath, `${json}\n`); + console.log(`Wrote ${outPath}`); +} else { + process.stdout.write(`${json}\n`); +} diff --git a/scripts/seed-crest-novel-template.js b/scripts/seed-crest-novel-template.js index a971b74..c2d087e 100644 --- a/scripts/seed-crest-novel-template.js +++ b/scripts/seed-crest-novel-template.js @@ -155,19 +155,23 @@ async function main() { name: 'CREST NOVEL', description: 'CREST / NOVEL lung health summit microsite — marketing popup, dual about sections, expert videos, tabbed speakers, schedule, sponsors, contact form, and feedback FAB.', - thumbnailUrl: thumbnailUrl || '', - htmlS3Key: htmlS3Key || '', - schemaS3Key: schemaS3Key || '', + thumbnailUrl: thumbnailUrl || existing?.thumbnailUrl || '', + htmlS3Key: htmlS3Key || existing?.htmlS3Key || '', + schemaS3Key: schemaS3Key || existing?.schemaS3Key || '', schema, assetsBaseUrl, assetsS3Prefix: `templates/${SLUG}/assets`, - isActive: Boolean(htmlS3Key && schemaS3Key), - version: 1, + isActive: Boolean((htmlS3Key || existing?.htmlS3Key) && (schemaS3Key || existing?.schemaS3Key)), + version: schema.version || 1, createdBy: user._id, }; if (existing) { + const preservedOrgs = existing.allowedOrganizations; Object.assign(existing, doc); + if (preservedOrgs && preservedOrgs.length) { + existing.allowedOrganizations = preservedOrgs; + } await existing.save(); console.log(`Updated MicrositeV2Template: ${existing._id}`); } else { diff --git a/scripts/seed-global-microsite-v2-templates.js b/scripts/seed-global-microsite-v2-templates.js new file mode 100644 index 0000000..e1651bf --- /dev/null +++ b/scripts/seed-global-microsite-v2-templates.js @@ -0,0 +1,58 @@ +#!/usr/bin/env node +/** + * Seed all bundled global microsite-v2 templates (or one via --slug=). + * + * Usage: + * node scripts/seed-global-microsite-v2-templates.js [--user-id=] [--db-only] + * node scripts/seed-global-microsite-v2-templates.js --slug=eventify + */ +require('dotenv').config(); +const mongoose = require('mongoose'); +const { connectDB } = require('../src/config/database'); +const User = require('../src/models/User'); +const { GLOBAL_MICROSITE_V2_TEMPLATES } = require('../src/config/globalMicrositeV2Templates'); +const { seedOneMicrositeV2Template } = require('./lib/seedOneMicrositeV2Template'); + +async function findSeedUser(userIdArg) { + if (userIdArg) { + const u = await User.findById(userIdArg); + if (u) return u; + } + const superAdmin = await User.findOne({ role: 'super_admin' }).sort({ createdAt: 1 }); + if (superAdmin) return superAdmin; + throw new Error('No super_admin user found. Pass --user-id='); +} + +async function main() { + const dbOnly = process.argv.includes('--db-only'); + const userIdArg = (process.argv.find((a) => a.startsWith('--user-id=')) || '').split('=')[1]; + const slugArg = (process.argv.find((a) => a.startsWith('--slug=')) || '').split('=')[1]?.trim().toLowerCase(); + + await connectDB(); + const user = await findSeedUser(userIdArg); + console.log(`Using user: ${user.email || user._id}`); + + const targets = slugArg + ? GLOBAL_MICROSITE_V2_TEMPLATES.filter((t) => t.slug === slugArg) + : GLOBAL_MICROSITE_V2_TEMPLATES; + + if (!targets.length) { + throw new Error( + slugArg + ? `Unknown slug "${slugArg}". Available: ${GLOBAL_MICROSITE_V2_TEMPLATES.map((t) => t.slug).join(', ')}` + : 'No templates configured.', + ); + } + + for (const def of targets) { + await seedOneMicrositeV2Template({ slug: def.slug, user, dbOnly }); + } + + await mongoose.disconnect(); + console.log('Done.'); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/scripts/seed-system-email-templates.js b/scripts/seed-system-email-templates.js new file mode 100644 index 0000000..f1b3e04 --- /dev/null +++ b/scripts/seed-system-email-templates.js @@ -0,0 +1,23 @@ +/** + * Seed or refresh platform-wide email templates. + * Run: cd backend && node scripts/seed-system-email-templates.js + */ +const path = require('path'); + +require('dotenv').config({ path: path.join(__dirname, '..', '.env') }); +const mongoose = require('mongoose'); +const { ensureSystemEmailTemplates } = require(path.join(__dirname, '..', 'src', 'utils', 'ensureSystemEmailTemplates')); + +async function main() { + const uri = process.env.MONGODB_URI || process.env.MONGO_URI; + if (!uri) throw new Error('MONGODB_URI not set'); + await mongoose.connect(uri); + const result = await ensureSystemEmailTemplates(); + console.log('System email templates:', result); + await mongoose.disconnect(); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/scripts/setup-goa-7-8-microsite.js b/scripts/setup-goa-7-8-microsite.js index fd4d536..6c024a2 100644 --- a/scripts/setup-goa-7-8-microsite.js +++ b/scripts/setup-goa-7-8-microsite.js @@ -2,9 +2,10 @@ * Align Goa 7–8 Aug microsite with Goa 8–9 Aug format and publish. * * Usage: - * node scripts/setup-goa-7-8-microsite.js [--publish] + * node scripts/setup-goa-7-8-microsite.js [--publish] [--csv=path] */ const path = require('path'); +const fs = require('fs'); require('dotenv').config({ path: path.join(__dirname, '..', '.env') }); const mongoose = require('mongoose'); @@ -12,15 +13,17 @@ const { connectDB } = require('../src/config/database'); const Event = require('../src/models/Event'); const Form = require('../src/models/Form'); const EventStaticMicrosite = require('../src/models/EventStaticMicrosite'); -const MicrositeV2Template = require('../src/models/MicrositeV2Template'); const User = require('../src/models/User'); const { normalizeSubdomain, subdomainAvailability } = require('../src/utils/subdomainAvailability'); const { publishStaticMicrosite } = require('../src/utils/publishStaticMicrosite'); +const { parseNovelScheduleCsv } = require('../src/utils/parseNovelScheduleCsv'); +const { importNovelScheduleToAgenda } = require('../src/utils/importNovelScheduleAgenda'); const SOURCE_SUBDOMAIN = 'novel2026-goa-8-9-aug'; const TARGET_EVENT_ID = '6a43e05fdc940a0d6e057f7b'; const TARGET_SUBDOMAIN = 'novel2026-goa-7-8-aug'; const SOURCE_EVENT_ID = '6a4cb75a7475c040cc6f2dd7'; +const DEFAULT_CSV = path.join(__dirname, '..', '..', 'novel2026-goa-7-8-aug.csv'); const PUBLIC_WEB_BASE = (process.env.PUBLIC_WEB_BASE || 'https://web.eventbuzz.live').replace(/\/$/, ''); const TARGET = { @@ -35,6 +38,11 @@ const TARGET = { mapQuery: 'DoubleTree+by+Hilton+Goa+Panaji,+Chimbel,+Goa', }; +function argValue(name, fallback) { + const hit = process.argv.find((a) => a.startsWith(`--${name}=`)); + return hit ? hit.split('=').slice(1).join('=').trim() : fallback; +} + function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } @@ -79,6 +87,30 @@ async function findPublishUser() { throw new Error('No user found for publish'); } +function loadScheduleFromCsv(csvPath) { + if (!fs.existsSync(csvPath)) { + throw new Error(`Schedule CSV not found: ${csvPath}`); + } + const text = fs.readFileSync(csvPath, 'utf8'); + const { days } = parseNovelScheduleCsv(text, { + dayDates: [TARGET.scheduleDay1, TARGET.scheduleDay2], + }); + return days; +} + +function applyScheduleToConfig(config, days) { + const next = deepClone(config); + const sections = next.sections || {}; + sections.event_schedule = sections.event_schedule || {}; + sections.event_schedule.show = sections.event_schedule.show !== false; + sections.event_schedule.heading = sections.event_schedule.heading || 'Event Schedule'; + sections.event_schedule.subtitle = + sections.event_schedule.subtitle || 'Scientific programme at DoubleTree by Hilton Panjim, Goa.'; + sections.event_schedule.days = days; + next.sections = sections; + return next; +} + function applyTargetOverrides(config, targetEventId, forms, heroBannerUrl) { const next = deepClone(config); next.meta = next.meta || {}; @@ -162,6 +194,7 @@ function applyTargetOverrides(config, targetEventId, forms, heroBannerUrl) { async function main() { const shouldPublish = process.argv.includes('--publish'); + const csvPath = argValue('csv', DEFAULT_CSV); await connectDB(); const targetEvent = await Event.findById(TARGET_EVENT_ID).lean(); @@ -170,6 +203,12 @@ async function main() { const sourceSite = await EventStaticMicrosite.findOne({ subdomain: SOURCE_SUBDOMAIN }).populate('template').lean(); if (!sourceSite) throw new Error(`Source microsite not found: ${SOURCE_SUBDOMAIN}`); + const scheduleDays = loadScheduleFromCsv(csvPath); + const agendaResult = await importNovelScheduleToAgenda(TARGET_EVENT_ID, scheduleDays); + console.log( + `Agenda: deleted ${agendaResult.deleted}, created ${agendaResult.created} session(s) on track ${agendaResult.trackId}`, + ); + const existingTarget = await EventStaticMicrosite.findOne({ event: TARGET_EVENT_ID }); const previousTarget = existingTarget ? deepClone(existingTarget.config) : null; const heroBannerUrl = previousTarget?.sections?.hero?.image?.url || null; @@ -200,6 +239,7 @@ async function main() { ].filter(([from]) => from); let config = replaceAllStrings(sourceSite.config, replacements); + config = applyScheduleToConfig(config, scheduleDays); config = applyTargetOverrides(config, TARGET_EVENT_ID, { registration, feedback, contact }, heroBannerUrl); const user = shouldPublish ? await findPublishUser() : null; @@ -229,6 +269,7 @@ async function main() { console.log(`Event: ${targetEvent.name}`); console.log(`Subdomain: ${subdomain}`); console.log(`Template: ${sourceSite.template?.slug || templateId}`); + console.log(`CSV: ${csvPath}`); console.log(`Reg form: ${registration?._id || '(none)'}`); console.log(`Feedback: ${feedback?._id || '(none)'}`); console.log(`Contact: ${contact?._id || '(none)'}`); diff --git a/scripts/setup-goa-8-9-microsite.js b/scripts/setup-goa-8-9-microsite.js new file mode 100644 index 0000000..66e9b6d --- /dev/null +++ b/scripts/setup-goa-8-9-microsite.js @@ -0,0 +1,242 @@ +/** + * Load novel2026-goa-8-9-aug.csv into microsite + agenda for the 8–9 Aug Goa event. + * + * Usage: + * node scripts/setup-goa-8-9-microsite.js [--publish] [--csv=path] + */ +const path = require('path'); +const fs = require('fs'); + +require('dotenv').config({ path: path.join(__dirname, '..', '.env') }); +const mongoose = require('mongoose'); +const { connectDB } = require('../src/config/database'); +const Event = require('../src/models/Event'); +const Form = require('../src/models/Form'); +const EventStaticMicrosite = require('../src/models/EventStaticMicrosite'); +const User = require('../src/models/User'); +const { normalizeSubdomain, subdomainAvailability } = require('../src/utils/subdomainAvailability'); +const { publishStaticMicrosite } = require('../src/utils/publishStaticMicrosite'); +const { parseNovelScheduleCsv } = require('../src/utils/parseNovelScheduleCsv'); +const { importNovelScheduleToAgenda } = require('../src/utils/importNovelScheduleAgenda'); + +const EVENT_ID = '6a4cb75a7475c040cc6f2dd7'; +const SUBDOMAIN = 'novel2026-goa-8-9-aug'; +const DEFAULT_CSV = path.join(__dirname, '..', '..', 'novel2026-goa-8-9-aug.csv'); +const PUBLIC_WEB_BASE = (process.env.PUBLIC_WEB_BASE || 'https://web.eventbuzz.live').replace(/\/$/, ''); + +const EVENT = { + name: 'NOVEL Lung Health Summit - Goa - 8th & 9th August 2026', + shortPlace: 'Goa', + dateLabel: '8th & 9th August 2026', + dateShort: 'Aug 8–9, 2026', + countdownDate: '2026-08-08', + scheduleDay1: 'August 8, 2026', + scheduleDay2: 'August 9, 2026', + location: 'DoubleTree by Hilton Panjim, Goa', + mapQuery: 'DoubleTree+by+Hilton+Goa+Panaji,+Chimbel,+Goa', +}; + +function argValue(name, fallback) { + const hit = process.argv.find((a) => a.startsWith(`--${name}=`)); + return hit ? hit.split('=').slice(1).join('=').trim() : fallback; +} + +function deepClone(obj) { + return JSON.parse(JSON.stringify(obj)); +} + +async function findForm(eventId, type) { + return Form.findOne({ event: eventId, type, 'settings.isActive': { $ne: false } }) + .sort({ createdAt: 1 }) + .select('_id name') + .lean(); +} + +async function findContactForm(eventId) { + return Form.findOne({ event: eventId, type: 'other', name: /contact/i, 'settings.isActive': { $ne: false } }) + .sort({ createdAt: 1 }) + .select('_id name') + .lean(); +} + +async function findPublishUser() { + const platform = await User.findOne({ platform_admin: 'yes', isActive: { $ne: false } }).sort({ createdAt: 1 }); + if (platform) return platform; + const superAdmin = await User.findOne({ role: 'super_admin' }).sort({ createdAt: 1 }); + if (superAdmin) return superAdmin; + throw new Error('No user found for publish'); +} + +function loadScheduleFromCsv(csvPath) { + if (!fs.existsSync(csvPath)) { + throw new Error(`Schedule CSV not found: ${csvPath}`); + } + const text = fs.readFileSync(csvPath, 'utf8'); + const { days } = parseNovelScheduleCsv(text, { + dayDates: [EVENT.scheduleDay1, EVENT.scheduleDay2], + }); + return days; +} + +function applyScheduleToConfig(config, days) { + const next = deepClone(config); + const sections = next.sections || {}; + sections.event_schedule = sections.event_schedule || {}; + sections.event_schedule.show = sections.event_schedule.show !== false; + sections.event_schedule.heading = sections.event_schedule.heading || 'Event Schedule'; + sections.event_schedule.subtitle = + sections.event_schedule.subtitle || 'Scientific programme at DoubleTree by Hilton Panjim, Goa.'; + sections.event_schedule.days = days; + next.sections = sections; + return next; +} + +function applyEventOverrides(config, eventId, forms, heroBannerUrl) { + const next = deepClone(config); + next.meta = next.meta || {}; + next.meta.title = EVENT.name; + next.meta.eventId = String(eventId); + + const regUrl = forms.registration + ? `${PUBLIC_WEB_BASE}/event/${eventId}/form/${forms.registration._id}` + : `${PUBLIC_WEB_BASE}/event/${eventId}/register`; + const feedbackUrl = forms.feedback + ? `${PUBLIC_WEB_BASE}/event/${eventId}/form/${forms.feedback._id}` + : null; + + const sections = next.sections || {}; + + if (sections.hero) { + sections.hero.event_name = `${EVENT.shortPlace} - ${EVENT.dateLabel}`; + sections.hero.date_venue = EVENT.location; + if (heroBannerUrl && sections.hero.image) { + sections.hero.image.url = heroBannerUrl; + } + if (sections.hero.cta) { + sections.hero.cta.url = regUrl; + sections.hero.cta.target = '_blank'; + } + if (sections.hero.countdown) { + sections.hero.countdown.date = EVENT.countdownDate; + } + } + + if (sections.informationBar?.items) { + for (const item of sections.informationBar.items) { + if (item.label === 'Location') item.value = EVENT.location; + if (item.label === 'Date & Time') { + item.value = EVENT.dateShort; + if (item.calendar) { + item.calendar.title = EVENT.name; + item.calendar.start = EVENT.countdownDate; + item.calendar.end = '2026-08-09'; + item.calendar.location = EVENT.location; + } + } + } + } + + if (sections.map) { + sections.map.embedUrl = `https://maps.google.com/maps?q=${EVENT.mapQuery}&hl=en&z=15&output=embed`; + } + + if (sections.contact && forms.contact) { + sections.contact.show = true; + sections.contact.formId = String(forms.contact._id); + sections.contact.apiBaseUrl = sections.contact.apiBaseUrl || 'https://api.eventbuzz.live/api'; + } + + if (sections.feedback && feedbackUrl) { + sections.feedback.url = feedbackUrl; + } + + if (sections.footer?.links) { + for (const link of sections.footer.links) { + if (link.text && /register/i.test(link.text)) { + link.url = regUrl; + link.target = '_blank'; + } + if (link.text && /feedback/i.test(link.text) && feedbackUrl) { + link.url = feedbackUrl; + link.target = '_blank'; + } + } + } + + next.sections = sections; + return next; +} + +async function main() { + const shouldPublish = process.argv.includes('--publish'); + const csvPath = argValue('csv', DEFAULT_CSV); + await connectDB(); + + const event = await Event.findById(EVENT_ID).lean(); + if (!event) throw new Error(`Event not found: ${EVENT_ID}`); + + const scheduleDays = loadScheduleFromCsv(csvPath); + const agendaResult = await importNovelScheduleToAgenda(EVENT_ID, scheduleDays); + console.log( + `Agenda: deleted ${agendaResult.deleted}, created ${agendaResult.created} session(s) on track ${agendaResult.trackId}`, + ); + + const existingSite = await EventStaticMicrosite.findOne({ event: EVENT_ID }).populate('template'); + if (!existingSite) { + throw new Error(`Microsite not found for event ${EVENT_ID}. Run setup-crest-novel-microsite.js first.`); + } + + const heroBannerUrl = existingSite.config?.sections?.hero?.image?.url || null; + const subdomain = normalizeSubdomain(SUBDOMAIN); + const avail = await subdomainAvailability(subdomain, EVENT_ID, existingSite._id?.toString()); + if (!avail.available) throw new Error(avail.message || 'Subdomain not available'); + + const [registration, feedback, contact] = await Promise.all([ + findForm(EVENT_ID, 'registration'), + findForm(EVENT_ID, 'feedback'), + findContactForm(EVENT_ID), + ]); + + let config = applyScheduleToConfig(existingSite.config, scheduleDays); + config = applyEventOverrides(config, EVENT_ID, { registration, feedback, contact }, heroBannerUrl); + + const user = shouldPublish ? await findPublishUser() : null; + + Object.assign(existingSite, { + subdomain, + config, + updatedBy: user?._id, + }); + existingSite.markModified('config'); + await existingSite.save(); + console.log(`Updated microsite ${existingSite._id}`); + + console.log(`Event: ${event.name}`); + console.log(`Subdomain: ${subdomain}`); + console.log(`Template: ${existingSite.template?.slug || existingSite.template}`); + console.log(`CSV: ${csvPath}`); + console.log(`Reg form: ${registration?._id || '(none)'}`); + console.log(`Feedback: ${feedback?._id || '(none)'}`); + console.log(`Contact: ${contact?._id || '(none)'}`); + + if (shouldPublish) { + const populated = await EventStaticMicrosite.findById(existingSite._id).populate('template'); + const result = await publishStaticMicrosite({ + staticMicrosite: populated, + template: populated.template, + userId: user._id, + }); + Object.assign(populated, result); + await populated.save(); + console.log(`Published: ${result.publicUrl}`); + } else { + console.log('Saved as draft. Re-run with --publish to publish.'); + } + + await mongoose.disconnect(); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/src/app.js b/src/app.js index 6c1247a..829c998 100644 --- a/src/app.js +++ b/src/app.js @@ -295,12 +295,24 @@ const createServer = async () => { if (response.isBoom && response.output) { const statusCode = response.output.statusCode; + const joiDetails = Array.isArray(response.details) + ? response.details + : Array.isArray(response.data) + ? response.data + : []; + const detailMsgs = joiDetails + .map((d) => (d && typeof d === 'object' ? d.message : null)) + .filter(Boolean); + const message = + detailMsgs.length > 0 + ? detailMsgs.slice(0, 3).join('; ') + : response.message; const payload = { success: false, error: { code: response.output.payload.error || 'ERROR', - message: response.message, - details: response.details || [], + message, + details: joiDetails, }, timestamp: new Date().toISOString(), }; @@ -327,6 +339,14 @@ const app = { async initialize() { await connectDB(); + const { ensureSystemEmailTemplates } = require('./utils/ensureSystemEmailTemplates'); + try { + const { created, updated } = await ensureSystemEmailTemplates(); + if (created > 0) console.log(`[startup] seeded ${created} system email template(s)`); + if (updated > 0) console.log(`[startup] updated ${updated} system email template(s)`); + } catch (err) { + console.error('[startup] ensureSystemEmailTemplates failed', err); + } const { warmPlanCache } = require('./config/subscriptionCatalog'); await warmPlanCache(); this._server = await createServer(); diff --git a/src/config/aclModules.js b/src/config/aclModules.js index 460c3bb..994514b 100644 --- a/src/config/aclModules.js +++ b/src/config/aclModules.js @@ -38,6 +38,20 @@ const ACL_MODULE_DEFS = { rowLevel: true, planFeatures: ['feedback_forms_and_surveys', 'registration_forms_with_custom_fields'], }, + web_check_in: { + key: 'web_check_in', + label: 'Web Check-in', + category: 'forms', + rowLevel: false, + planFeatures: [], + }, + attendance: { + key: 'attendance', + label: 'Attendance', + category: 'forms', + rowLevel: false, + planFeatures: [], + }, user_management: { key: 'user_management', label: 'User Management', @@ -77,6 +91,8 @@ const ORDERED_ACL_MODULE_KEYS = [ 'tracks', 'sessions', 'forms', + 'web_check_in', + 'attendance', 'participants', 'agenda_builder', 'multi_track_agenda', @@ -94,7 +110,7 @@ const ORDERED_ACL_MODULE_KEYS = [ 'settings', 'billing', ...COMBINED_PLAN_KEYS.filter((k) => ![ - 'events', 'tracks', 'sessions', 'forms', 'participants', 'agenda_builder', + 'events', 'tracks', 'sessions', 'forms', 'web_check_in', 'attendance', 'participants', 'agenda_builder', 'multi_track_agenda', 'speaker_management', 'content_management', 'email_outreach_campaigns', 'custom_badge_and_print_file_creation', 'custom_template_for_wa_messaging', 'live_polls', 'multiple_quiz_modes', diff --git a/src/config/constants.js b/src/config/constants.js index ff72ffb..48fc090 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -1,7 +1,7 @@ const ROLES = ['super_admin', 'admin', 'moderator', 'viewer']; const EVENT_TYPES = ['conference', 'workshop', 'summit', 'cme', 'webinar']; const EVENT_STATUS = ['draft', 'upcoming', 'live', 'completed']; -const PARTICIPANT_STATUS = ['pending', 'confirmed', 'checked_in', 'cancelled']; +const PARTICIPANT_STATUS = ['pending', 'confirmed', 'checked_in', 'cancelled', 'rejected']; const SESSION_TYPES = ['keynote', 'workshop', 'panel', 'breakout', 'networking']; const SESSION_STATUS = ['scheduled', 'ongoing', 'completed', 'cancelled']; const FORM_TYPES = ['registration', 'feedback', 'survey', 'custom', 'other', 'web-check-in']; diff --git a/src/config/globalMicrositeV2Templates.js b/src/config/globalMicrositeV2Templates.js new file mode 100644 index 0000000..5fe7ccd --- /dev/null +++ b/src/config/globalMicrositeV2Templates.js @@ -0,0 +1,71 @@ +/** + * Bundled microsite-v2 templates shipped in backend/microsite-v2-templates/. + * Seed into MongoDB + S3 via: npm run seed:global-microsite-v2-templates + */ +const GLOBAL_MICROSITE_V2_TEMPLATES = [ + { + slug: 'event-up', + name: 'EventUp Conference', + description: + 'Full EventUp conference microsite — hero, schedule, speakers, sponsors, contact, and more.', + externalAssetRoots: ['microsites/event-up/assets'], + thumbnailCandidates: ['thumbnail.jpg', 'thumbnail.png', 'assets/img/hero.jpg'], + placeholderSvgLabel: 'EventUp', + placeholderSvgColor: '#5c6ac4', + }, + { + slug: 'crest-novel', + name: 'CREST NOVEL', + description: + 'CREST / NOVEL lung health summit microsite — marketing popup, dual about sections, expert videos, tabbed speakers, schedule, sponsors, contact form, and feedback FAB.', + externalAssetRoots: ['microsites/crest-novel/assets'], + thumbnailCandidates: [ + 'thumbnail.jpg', + 'thumbnail.png', + 'assets/img/hero.jpg', + 'assets/img/novel-logo.png', + ], + placeholderSvgLabel: 'CREST NOVEL', + placeholderSvgColor: '#015AAA', + }, + { + slug: 'eventify', + name: 'Eventify', + description: + 'Eventify conference microsite — hero, about, schedule, speakers, pricing, gallery, sponsors, and contact.', + thumbnailCandidates: [ + 'thumbnail.jpg', + 'thumbnail.png', + 'assets/images/header-bg.jpg', + 'assets/images/logo.png', + ], + placeholderSvgLabel: 'Eventify', + placeholderSvgColor: '#2A7B9B', + }, + { + slug: 'eventre', + name: 'Eventre', + description: + 'Eventre conference microsite — banner, schedule, speakers, sponsors, news, gallery, pricing, and registration.', + thumbnailCandidates: [ + 'thumbnail.jpg', + 'thumbnail.png', + 'assets/images/background/homepage-one-banner.jpg', + 'assets/images/logo.png', + ], + placeholderSvgLabel: 'Eventre', + placeholderSvgColor: '#ff6600', + }, +]; + +function getGlobalMicrositeV2Template(slug) { + const normalized = String(slug || '') + .trim() + .toLowerCase(); + return GLOBAL_MICROSITE_V2_TEMPLATES.find((t) => t.slug === normalized) || null; +} + +module.exports = { + GLOBAL_MICROSITE_V2_TEMPLATES, + getGlobalMicrositeV2Template, +}; diff --git a/src/config/systemEmailTemplates.js b/src/config/systemEmailTemplates.js new file mode 100644 index 0000000..4c1812f --- /dev/null +++ b/src/config/systemEmailTemplates.js @@ -0,0 +1,181 @@ +/** + * Built-in emailer templates available to every organisation. + * Editing a system template forks a copy at org level (see designTemplate.controller). + */ +const { buildStaticPreviewHtml } = require('../utils/emailerHtml'); + +const SYSTEM_CONTENT_VERSION = 2; + +function textBlock(id, html) { + return { id, type: 'text', html }; +} + +function ctaForm(id, label, formType) { + return { id, type: 'cta', label, linkKind: 'form', formType }; +} + +function ctaMicrosite(id, label) { + return { id, type: 'cta', label, linkKind: 'microsite' }; +} + +function buildContent({ subjectLine, previewText, blocks, footerText }) { + const content = { + contentVersion: SYSTEM_CONTENT_VERSION, + version: 2, + subjectLine, + previewText, + footerText: footerText || 'You received this email regarding {{event.name}}. Need help? Reply to this email.', + primaryColor: '#0B4DD1', + fontPair: 'Inter + Noto Sans', + headerImageUrl: '{{event.logoUrl}}', + layoutTemplateId: 'e1', + blocks, + }; + content.html = buildStaticPreviewHtml(content); + return content; +} + +function eventDetailsBlock() { + return textBlock( + 'blk-details', + `

Hi {{contact.firstName}},

+
    +
  • Event: {{event.name}}
  • +
  • Starts: {{event.startDate}}
  • +
  • Ends: {{event.endDate}}
  • +
  • Venue: {{event.venue}}
  • +
`, + ); +} + +const SYSTEM_EMAIL_TEMPLATES = [ + { + systemTemplateKey: 'invite_for_event', + name: 'Invite for Event', + category: 'Invitation', + content: buildContent({ + subjectLine: 'You are invited to {{event.name}}', + previewText: 'Join us at {{event.name}} — save your spot today', + blocks: [ + textBlock( + 'blk-headline', + `

You’re invited!

+

Hi {{contact.firstName}},

+

We would be delighted to have you join us at {{event.name}}. Your presence would mean a lot to us.

`, + ), + eventDetailsBlock(), + textBlock('blk-closing', '

Please register at your earliest convenience. We look forward to seeing you there.

'), + ctaForm('blk-cta', 'Register now', 'registration'), + ctaMicrosite('blk-cta-ms', 'View event website'), + ], + }), + }, + { + systemTemplateKey: 'register_success', + name: 'Register Success', + category: 'Registration Confirmation', + content: buildContent({ + subjectLine: 'Registration received — {{event.name}}', + previewText: 'We have received your registration', + blocks: [ + textBlock( + 'blk-headline', + `

Registration received

+

Hi {{contact.firstName}},

+

Thank you for registering for {{event.name}}. We have successfully received your details.

`, + ), + eventDetailsBlock(), + textBlock( + 'blk-next', + '

Our team will review your registration and share a confirmation or next steps shortly. If you have questions, simply reply to this email.

', + ), + ctaMicrosite('blk-cta', 'Visit event page'), + ], + }), + }, + { + systemTemplateKey: 'register_confirmation', + name: 'Register Confirmation', + category: 'Registration Confirmation', + content: buildContent({ + subjectLine: 'Your registration is confirmed — {{event.name}}', + previewText: 'Your spot is confirmed', + blocks: [ + textBlock( + 'blk-headline', + `

You’re confirmed!

+

Hi {{contact.firstName}},

+

Great news — your registration for {{event.name}} is confirmed. Please save this email for your records.

`, + ), + eventDetailsBlock(), + textBlock( + 'blk-note', + '

Add the event to your calendar and check the event page for agenda updates, venue directions, and any materials you may need.

', + ), + ctaMicrosite('blk-cta', 'View event details'), + ], + }), + }, + { + systemTemplateKey: 'rsvp', + name: 'RSVP', + category: 'Invitation', + content: buildContent({ + subjectLine: 'Please RSVP — {{event.name}}', + previewText: 'Let us know if you can attend', + blocks: [ + textBlock( + 'blk-headline', + `

Will you join us?

+

Hi {{contact.firstName}},

+

Please confirm your attendance for {{event.name}}. Your RSVP helps us plan seating, catering, and materials.

`, + ), + eventDetailsBlock(), + ctaForm('blk-cta', 'RSVP now', 'registration'), + ], + }), + }, + { + systemTemplateKey: 'thanks_for_attending', + name: 'Thanks for Attending', + category: 'Post-Event Thank You', + content: buildContent({ + subjectLine: 'Thank you for attending {{event.name}}', + previewText: 'Thanks for being part of {{event.name}}', + blocks: [ + textBlock( + 'blk-headline', + `

Thank you!

+

Hi {{contact.firstName}},

+

Thank you for attending {{event.name}}. We truly appreciate your time and participation.

+

We hope the sessions were valuable and that you connected with peers who share your interests. We would love to welcome you again at our future events.

`, + ), + { id: 'blk-div', type: 'divider' }, + textBlock('blk-signoff', '

With gratitude,
The {{event.name}} team

'), + ], + footerText: 'You attended {{event.name}}. Thank you for being part of our community.', + }), + }, + { + systemTemplateKey: 'feedback', + name: 'Feedback', + category: 'Custom', + content: buildContent({ + subjectLine: 'Share your feedback — {{event.name}}', + previewText: 'Tell us how we did', + blocks: [ + textBlock( + 'blk-headline', + `

We value your feedback

+

Hi {{contact.firstName}},

+

Thank you for being part of {{event.name}}. Your feedback helps us improve content, logistics, and the overall experience.

+

It only takes a few minutes — please share your thoughts using the button below.

`, + ), + ctaForm('blk-cta', 'Give feedback', 'feedback'), + ctaMicrosite('blk-cta-ms', 'Visit event page'), + ], + }), + }, +]; + +module.exports = { SYSTEM_EMAIL_TEMPLATES, SYSTEM_CONTENT_VERSION }; diff --git a/src/config/systemRolePermissions.js b/src/config/systemRolePermissions.js index 50f9b8f..6b5ac36 100644 --- a/src/config/systemRolePermissions.js +++ b/src/config/systemRolePermissions.js @@ -16,18 +16,22 @@ function allPlanModules(actions, scope = 'all') { return keys.map((module) => perm(module, actions, scope)); } +const CORE_EXPLICIT = ['events', 'tracks', 'sessions', 'forms', 'web_check_in', 'attendance', 'participants', 'user_management', 'settings', 'billing']; + const SYSTEM_ROLE_PERMISSIONS = { super_admin: [ perm('events', ['read', 'write', 'delete'], 'all'), perm('tracks', ['read', 'write', 'delete'], 'all'), perm('sessions', ['read', 'write', 'delete'], 'all'), perm('forms', ['read', 'write', 'delete'], 'all'), + perm('web_check_in', ['read', 'write', 'delete'], 'all'), + perm('attendance', ['read', 'write', 'delete'], 'all'), perm('participants', ['read', 'write', 'delete'], 'all'), perm('user_management', ['read', 'write', 'delete'], 'all'), perm('settings', ['read', 'write', 'delete'], 'all'), perm('billing', ['read', 'write'], 'all'), ...allPlanModules(['read', 'write', 'delete'], 'all').filter( - (p) => !['events', 'tracks', 'sessions', 'forms', 'participants', 'user_management', 'settings', 'billing'].includes(p.module), + (p) => !CORE_EXPLICIT.includes(p.module), ), ], admin: [ @@ -35,12 +39,14 @@ const SYSTEM_ROLE_PERMISSIONS = { perm('tracks', ['read', 'write', 'delete'], 'all'), perm('sessions', ['read', 'write', 'delete'], 'all'), perm('forms', ['read', 'write', 'delete'], 'all'), + perm('web_check_in', ['read', 'write', 'delete'], 'all'), + perm('attendance', ['read', 'write', 'delete'], 'all'), perm('participants', ['read', 'write', 'delete'], 'all'), perm('user_management', ['read', 'write'], 'all'), perm('settings', ['read', 'write'], 'all'), perm('billing', ['read', 'write'], 'all'), ...allPlanModules(['read', 'write', 'delete'], 'all').filter( - (p) => !['events', 'tracks', 'sessions', 'forms', 'participants', 'user_management', 'settings', 'billing'].includes(p.module), + (p) => !CORE_EXPLICIT.includes(p.module), ), ], moderator: [ @@ -48,9 +54,11 @@ const SYSTEM_ROLE_PERMISSIONS = { perm('tracks', ['read', 'write'], 'assigned'), perm('sessions', ['read', 'write'], 'assigned'), perm('forms', ['read', 'write'], 'assigned'), + perm('web_check_in', ['read', 'write'], 'assigned'), + perm('attendance', ['read', 'write'], 'assigned'), perm('participants', ['read', 'write'], 'all'), ...allPlanModules(['read', 'write'], 'all').filter( - (p) => !['events', 'tracks', 'sessions', 'forms', 'participants', 'user_management', 'settings', 'billing'].includes(p.module), + (p) => !CORE_EXPLICIT.includes(p.module), ), ], viewer: [ @@ -58,9 +66,11 @@ const SYSTEM_ROLE_PERMISSIONS = { perm('tracks', ['read'], 'assigned'), perm('sessions', ['read'], 'assigned'), perm('forms', ['read'], 'assigned'), + perm('web_check_in', ['read'], 'assigned'), + perm('attendance', ['read'], 'assigned'), perm('participants', ['read'], 'all'), ...allPlanModules(['read'], 'all').filter( - (p) => !['events', 'tracks', 'sessions', 'forms', 'participants', 'user_management', 'settings', 'billing'].includes(p.module), + (p) => !CORE_EXPLICIT.includes(p.module), ), ], }; diff --git a/src/controllers/badgeBatch.controller.js b/src/controllers/badgeBatch.controller.js index 5a83d54..e28e532 100644 --- a/src/controllers/badgeBatch.controller.js +++ b/src/controllers/badgeBatch.controller.js @@ -21,6 +21,21 @@ function resolveOrganizationId(user, payloadOrg) { return oid instanceof mongoose.Types.ObjectId ? oid : new mongoose.Types.ObjectId(String(oid)); } +function normalizeBackgroundImageLayout(layout, imageUrl) { + if (!String(imageUrl || '').trim()) return undefined; + const src = layout && typeof layout === 'object' ? layout : {}; + const clamp = (n, min, max, fallback) => { + const v = Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.min(max, Math.max(min, v)); + }; + const w = clamp(src.w, 10, 500, 100); + const h = clamp(src.h, 10, 500, 100); + const x = clamp(src.x, -400, 400, 0); + const y = clamp(src.y, -400, 400, 0); + return { x, y, w, h }; +} + async function canManageBadges(user) { const orgId = userOrgId(user); try { @@ -99,10 +114,6 @@ const create = async (request, h) => { if (p.includeParticipants && p.participantScope === 'participant_list' && !p.participantListId) { return h.response(error('VALIDATION_ERROR', 'Select a contact list for participants')).code(400); } - if (p.backgroundMode === 'image' && !String(p.backgroundImageUrl || '').trim()) { - return h.response(error('VALIDATION_ERROR', 'Background image URL is required when using image background')).code(400); - } - const event = await Event.findById(p.event).select('organization').lean(); if (!event) return h.response(error('NOT_FOUND', 'Event not found')).code(404); if (String(event.organization) !== orgId.toString()) { @@ -158,8 +169,9 @@ const create = async (request, h) => { includeParticipants: Boolean(p.includeParticipants), participantScope: p.participantScope, participantListId: listOid, - backgroundMode: p.backgroundMode, + backgroundMode: String(p.backgroundImageUrl || '').trim() ? 'image' : 'color', backgroundImageUrl: String(p.backgroundImageUrl || '').trim(), + backgroundImageLayout: normalizeBackgroundImageLayout(p.backgroundImageLayout, p.backgroundImageUrl), backgroundColor: p.backgroundColor || '#0B4DD1', fields: Array.isArray(p.fields) ? p.fields : [], layout: Array.isArray(p.layout) ? p.layout : [], diff --git a/src/controllers/designTemplate.controller.js b/src/controllers/designTemplate.controller.js index 0be3196..842d0d0 100644 --- a/src/controllers/designTemplate.controller.js +++ b/src/controllers/designTemplate.controller.js @@ -3,11 +3,110 @@ const Event = require('../models/Event'); const { success, error } = require('../utils/response'); const { resolveScopedOrganizationId } = require('../utils/tenantListScope'); +function userOrgId(user) { + return user?.organization?._id || user?.organization || null; +} + +function sameId(a, b) { + if (a == null || b == null) return false; + return String(a) === String(b); +} + +function canManageDesignTemplates(user) { + return user?.role === 'super_admin'; +} + +function canManageOrgEmailers(user) { + return ['super_admin', 'admin', 'moderator'].includes(user?.role); +} + +function decorateTemplate(doc, extra = {}) { + const t = typeof doc.toObject === 'function' ? doc.toObject() : { ...doc }; + const isSystem = t.isSystemTemplate === true; + return { + ...t, + isGlobalTemplate: isSystem || Boolean(t.systemTemplateKey), + canDelete: !isSystem, + ...extra, + }; +} + +async function mergeEmailerList(organizationId) { + const [systemRows, orgRows] = await Promise.all([ + DesignTemplate.find({ isSystemTemplate: true, type: 'emailer' }).sort({ name: 1 }).lean(), + DesignTemplate.find({ + organization: organizationId, + type: 'emailer', + isSystemTemplate: { $ne: true }, + }) + .sort({ updatedAt: -1 }) + .lean(), + ]); + + const overridesByKey = new Map(); + const customOrg = []; + for (const row of orgRows) { + if (row.systemTemplateKey) overridesByKey.set(row.systemTemplateKey, row); + else customOrg.push(row); + } + + const merged = systemRows.map((sys) => { + const override = overridesByKey.get(sys.systemTemplateKey); + if (override) { + overridesByKey.delete(sys.systemTemplateKey); + return decorateTemplate(override, { isOrgOverride: true, globalTemplateKey: sys.systemTemplateKey }); + } + return decorateTemplate(sys, { isOrgOverride: false }); + }); + + for (const row of customOrg) merged.push(decorateTemplate(row)); + for (const row of overridesByKey.values()) { + merged.push(decorateTemplate(row, { isOrgOverride: true })); + } + + return merged; +} + +function sanitizeTemplatePayload(payload = {}) { + const allowed = ['name', 'type', 'category', 'thumbnail', 'content', 'variables', 'settings', 'associatedEvent']; + const out = {}; + for (const key of allowed) { + if (payload[key] !== undefined) out[key] = payload[key]; + } + return out; +} + +function canReadTemplate(user, template) { + if (user.role === 'super_admin') return true; + if (template.isSystemTemplate) return true; + return sameId(template.organization, userOrgId(user)); +} + +function canWriteTemplate(user, template) { + if (template.isSystemTemplate) return canManageOrgEmailers(user); + if (user.role === 'super_admin') return true; + return sameId(template.organization, userOrgId(user)) && canManageOrgEmailers(user); +} + const list = async (request, h) => { const user = request.auth.credentials.user; const scoped = resolveScopedOrganizationId(user, request.query.organization); if (scoped.error) return h.response(error(scoped.error.code, scoped.error.message)).code(400); - const filter = { organization: scoped.organizationId }; + + if (request.query.type === 'emailer') { + const templates = await mergeEmailerList(scoped.organizationId); + const total = templates.length; + const { page = 1, limit = 20 } = request.query; + const pageNum = Math.max(1, parseInt(page, 10) || 1); + const limitNum = Math.max(1, parseInt(limit, 10) || 20); + const skip = (pageNum - 1) * limitNum; + const pageRows = templates.slice(skip, skip + limitNum); + return h + .response(success({ templates: pageRows, total, page: pageNum, limit: limitNum })) + .header('X-Total-Count', total); + } + + const filter = { organization: scoped.organizationId, isSystemTemplate: { $ne: true } }; if (request.query.type) filter.type = request.query.type; const { page = 1, limit = 20 } = request.query; const skip = (parseInt(page, 10) - 1) * parseInt(limit, 10); @@ -15,55 +114,141 @@ const list = async (request, h) => { DesignTemplate.find(filter).skip(skip).limit(parseInt(limit, 10)).lean(), DesignTemplate.countDocuments(filter), ]); - return h.response(success({ templates, total, page: parseInt(page, 10), limit: parseInt(limit, 10) })) + return h + .response(success({ templates: templates.map((t) => decorateTemplate(t)), total, page: parseInt(page, 10), limit: parseInt(limit, 10) })) .header('X-Total-Count', total); }; const create = async (request, h) => { const user = request.auth.credentials.user; - if (user.role !== 'super_admin') return h.response(error('FORBIDDEN', 'Only super_admin can create design templates')).code(403); - const orgId = request.payload.organization || (user.organization?._id || user.organization); + const payload = sanitizeTemplatePayload(request.payload); + const isEmailer = payload.type === 'emailer'; + + if (!isEmailer && !canManageDesignTemplates(user)) { + return h.response(error('FORBIDDEN', 'Only super_admin can create design templates')).code(403); + } + if (isEmailer && !canManageOrgEmailers(user)) { + return h.response(error('FORBIDDEN', 'You do not have permission to create emailers')).code(403); + } + + const scoped = resolveScopedOrganizationId(user, request.payload.organization); + if (scoped.error) return h.response(error(scoped.error.code, scoped.error.message)).code(400); + const orgId = scoped.organizationId; if (!orgId) return h.response(error('VALIDATION_ERROR', 'Organization required')).code(400); + const template = await DesignTemplate.create({ - ...request.payload, + ...payload, organization: orgId, createdBy: user._id, + isSystemTemplate: false, }); - return h.response(success(template, 'Template created', 201)).code(201); + return h.response(success(decorateTemplate(template), 'Template created', 201)).code(201); }; const get = async (request, h) => { const template = await DesignTemplate.findById(request.params.id).populate('organization createdBy'); if (!template) return h.response(error('NOT_FOUND', 'Template not found')).code(404); const user = request.auth.credentials.user; - if (user.role !== 'super_admin' && template.organization?.toString() !== (user.organization?._id || user.organization)?.toString()) { + if (!canReadTemplate(user, template)) { return h.response(error('FORBIDDEN', 'Access denied')).code(403); } - return h.response(success(template)); + return h.response(success(decorateTemplate(template))); }; +async function forkSystemEmailerToOrg(systemTemplate, orgId, user, payload) { + const existing = await DesignTemplate.findOne({ + organization: orgId, + type: 'emailer', + systemTemplateKey: systemTemplate.systemTemplateKey, + isSystemTemplate: false, + }); + if (existing) { + Object.assign(existing, sanitizeTemplatePayload(payload)); + await existing.save(); + return existing; + } + return DesignTemplate.create({ + ...sanitizeTemplatePayload(payload), + name: payload.name || systemTemplate.name, + type: 'emailer', + category: payload.category ?? systemTemplate.category, + organization: orgId, + createdBy: user._id, + isSystemTemplate: false, + systemTemplateKey: systemTemplate.systemTemplateKey, + derivedFromTemplate: systemTemplate._id, + settings: { isPublic: false, isActive: true, canDuplicate: true }, + }); +} + const update = async (request, h) => { const user = request.auth.credentials.user; - if (user.role !== 'super_admin') return h.response(error('FORBIDDEN', 'Only super_admin can update design templates')).code(403); const template = await DesignTemplate.findById(request.params.id); if (!template) return h.response(error('NOT_FOUND', 'Template not found')).code(404); - Object.assign(template, request.payload); + + if (template.type === 'emailer') { + if (template.isSystemTemplate) { + if (user.role === 'super_admin') { + Object.assign(template, sanitizeTemplatePayload(request.payload)); + await template.save(); + return h.response(success(decorateTemplate(template))); + } + if (!canManageOrgEmailers(user)) { + return h.response(error('FORBIDDEN', 'You do not have permission to customize emailers')).code(403); + } + const scoped = resolveScopedOrganizationId(user, request.payload.organization); + if (scoped.error) return h.response(error(scoped.error.code, scoped.error.message)).code(400); + const orgId = scoped.organizationId; + if (!orgId) return h.response(error('VALIDATION_ERROR', 'Organization required')).code(400); + const forked = await forkSystemEmailerToOrg(template, orgId, user, request.payload); + return h.response(success(decorateTemplate(forked, { isOrgOverride: true }), 'Organization copy saved', 201)).code(201); + } + + if (!canWriteTemplate(user, template)) { + return h.response(error('FORBIDDEN', 'Access denied')).code(403); + } + Object.assign(template, sanitizeTemplatePayload(request.payload)); + await template.save(); + return h.response(success(decorateTemplate(template))); + } + + if (!canManageDesignTemplates(user)) { + return h.response(error('FORBIDDEN', 'Only super_admin can update design templates')).code(403); + } + Object.assign(template, sanitizeTemplatePayload(request.payload)); await template.save(); - return h.response(success(template)); + return h.response(success(decorateTemplate(template))); }; const remove = async (request, h) => { const user = request.auth.credentials.user; - if (user.role !== 'super_admin') return h.response(error('FORBIDDEN', 'Only super_admin can delete design templates')).code(403); const template = await DesignTemplate.findById(request.params.id); if (!template) return h.response(error('NOT_FOUND', 'Template not found')).code(404); + + if (template.isSystemTemplate) { + return h.response(error('FORBIDDEN', 'System templates cannot be deleted')).code(403); + } + + if (template.type === 'emailer') { + if (!canWriteTemplate(user, template)) { + return h.response(error('FORBIDDEN', 'Access denied')).code(403); + } + await template.deleteOne(); + return h.response(success(null, 'Template deleted')).code(200); + } + + if (!canManageDesignTemplates(user)) { + return h.response(error('FORBIDDEN', 'Only super_admin can delete design templates')).code(403); + } await template.deleteOne(); return h.response(success(null, 'Template deleted')).code(200); }; const duplicate = async (request, h) => { const user = request.auth.credentials.user; - if (user.role !== 'super_admin') return h.response(error('FORBIDDEN', 'Only super_admin can duplicate design templates')).code(403); + if (!canManageDesignTemplates(user)) { + return h.response(error('FORBIDDEN', 'Only super_admin can duplicate design templates')).code(403); + } const template = await DesignTemplate.findById(request.params.id); if (!template) return h.response(error('NOT_FOUND', 'Template not found')).code(404); const doc = template.toObject(); @@ -71,8 +256,11 @@ const duplicate = async (request, h) => { delete doc.createdAt; delete doc.updatedAt; doc.name = `${doc.name} (Copy)`; + doc.isSystemTemplate = false; + doc.systemTemplateKey = undefined; + doc.derivedFromTemplate = undefined; const created = await DesignTemplate.create(doc); - return h.response(success(created, 'Template duplicated', 201)).code(201); + return h.response(success(decorateTemplate(created), 'Template duplicated', 201)).code(201); }; const useForEvent = async (request, h) => { @@ -81,12 +269,16 @@ const useForEvent = async (request, h) => { if (!template) return h.response(error('NOT_FOUND', 'Template not found')).code(404); const event = await Event.findById(eventId); if (!event) return h.response(error('NOT_FOUND', 'Event not found')).code(404); + const user = request.auth.credentials.user; + if (!canReadTemplate(user, template)) { + return h.response(error('FORBIDDEN', 'Access denied')).code(403); + } if (!template.usedBy) template.usedBy = []; - if (!template.usedBy.some(e => e.toString() === eventId)) { + if (!template.usedBy.some((e) => e.toString() === eventId)) { template.usedBy.push(event._id); await template.save(); } - return h.response(success({ template, event }, 'Template applied to event')); + return h.response(success({ template: decorateTemplate(template), event }, 'Template applied to event')); }; module.exports = { list, create, get, update, remove, duplicate, useForEvent }; diff --git a/src/controllers/event.controller.js b/src/controllers/event.controller.js index 4ce6358..1a7e43a 100644 --- a/src/controllers/event.controller.js +++ b/src/controllers/event.controller.js @@ -217,6 +217,10 @@ async function attachActivityStats(organizationId, eventsLean) { const QuizPoll = require('../models/QuizPoll'); const QuizPollResponse = require('../models/QuizPollResponse'); const Participant = require('../models/Participant'); + const Session = require('../models/Session'); + const Form = require('../models/Form'); + const { computeFormRatingsSummariesBatch } = require('../utils/eventRatingsSummary'); + const { ALL_BUILTIN_RATINGS_NAMES } = require('../utils/visitorBuiltinForms'); const orgOid = toOrgObjectId(organizationId); const eventIds = eventsLean.map((e) => e._id); @@ -224,7 +228,7 @@ async function attachActivityStats(organizationId, eventsLean) { $or: [{ deletedAt: null }, { deletedAt: { $exists: false } }], }; - const [qAgg, pAgg, qpAgg, respAgg] = await Promise.all([ + const [qAgg, pAgg, qpAgg, respAgg, sessions] = await Promise.all([ Question.aggregate([ { $match: { event: { $in: eventIds } } }, { $group: { _id: '$event', count: { $sum: 1 } } }, @@ -250,6 +254,10 @@ async function attachActivityStats(organizationId, eventsLean) { }, { $group: { _id: '$qp.event', count: { $sum: 1 } } }, ]), + Session.find({ event: { $in: eventIds } }) + .select('event audienceRatingsForm startTime') + .sort({ startTime: 1 }) + .lean(), ]); const toMap = (agg) => @@ -262,15 +270,57 @@ async function attachActivityStats(organizationId, eventsLean) { const qpm = toMap(qpAgg); const rm = toMap(respAgg); - return eventsLean.map((ev) => ({ - ...ev, - activityStats: { - questionCount: qm[String(ev._id)] || 0, - participantCount: pm[String(ev._id)] || 0, - quizPollCount: qpm[String(ev._id)] || 0, - responseCount: rm[String(ev._id)] || 0, - }, - })); + const primarySessionByEvent = new Map(); + for (const session of sessions) { + const eid = String(session.event); + if (!primarySessionByEvent.has(eid)) primarySessionByEvent.set(eid, session); + } + + const eventsNeedingBuiltin = []; + const sessionRatingPairs = []; + for (const [eid, session] of primarySessionByEvent) { + if (session.audienceRatingsForm) { + sessionRatingPairs.push({ eventId: eid, formId: String(session.audienceRatingsForm) }); + } else { + eventsNeedingBuiltin.push(eid); + } + } + + if (eventsNeedingBuiltin.length) { + const builtinForms = await Form.find({ + event: { $in: eventsNeedingBuiltin.map((id) => new mongoose.Types.ObjectId(id)) }, + type: 'feedback', + name: { $in: ALL_BUILTIN_RATINGS_NAMES }, + }) + .select('_id event') + .lean(); + const builtinByEvent = new Map(builtinForms.map((f) => [String(f.event), String(f._id)])); + for (const eid of eventsNeedingBuiltin) { + const formId = builtinByEvent.get(eid); + if (formId) sessionRatingPairs.push({ eventId: eid, formId }); + } + } + + const sessionRatingByEvent = await computeFormRatingsSummariesBatch(sessionRatingPairs); + + return eventsLean.map((ev) => { + const eid = String(ev._id); + const meta = ev.metadata && typeof ev.metadata === 'object' ? ev.metadata : {}; + const sessionRating = sessionRatingByEvent.get(eid) || { average: 0, count: 0 }; + return { + ...ev, + activityStats: { + questionCount: qm[eid] || 0, + participantCount: pm[eid] || 0, + quizPollCount: qpm[eid] || 0, + responseCount: rm[eid] || 0, + eventRatingAverage: meta.rating ?? 0, + eventRatingCount: meta.ratingCount ?? 0, + sessionRatingAverage: sessionRating.average, + sessionRatingCount: sessionRating.count, + }, + }; + }); } async function persistEventWithSideEffects(user, orgId, rest, metaIn) { @@ -525,6 +575,12 @@ const get = async (request, h) => { if (!(await canAccessEvent(user, orgId, event._id, 'read'))) { return h.response(error('FORBIDDEN', 'Access denied')).code(403); } + const enrich = request.query.enrich === '1' || request.query.enrich === 'true'; + if (enrich && event.recordKind === 'activity') { + const orgForStats = event.organization?._id || event.organization; + const [enriched] = await attachActivityStats(orgForStats, [event.toObject()]); + return h.response(success(enriched)); + } return h.response(success(event)); }; @@ -662,10 +718,11 @@ const emailerLinkTargets = async (request, h) => { } const base = (process.env.MICROSITE_PUBLIC_BASE_URL || 'https://web.eventbuzz.live').replace(/\/$/, ''); const accessFilter = await buildFormAccessFilter(user, orgId); - const formsRaw = await Form.find({ event: event._id, ...accessFilter }).select('_id name').sort({ name: 1 }).lean(); + const formsRaw = await Form.find({ event: event._id, ...accessFilter }).select('_id name type').sort({ name: 1 }).lean(); const forms = formsRaw.map((f) => ({ id: String(f._id), name: f.name || 'Form', + type: f.type || 'custom', href: registrationUrlForForm(event, event.website, f._id) || '', })); const mss = await EventMicrosite.find({ event: event._id }).select('name publishFolder').sort({ name: 1 }).lean(); diff --git a/src/controllers/form.controller.js b/src/controllers/form.controller.js index 954c28d..6daf8e4 100644 --- a/src/controllers/form.controller.js +++ b/src/controllers/form.controller.js @@ -12,13 +12,16 @@ const { buildPublicEventPayload, buildPublicFormSettings, resolveEventForPublicForm, + settingMessage: formSettingMessage, } = require('../utils/formPublicHelpers'); const { verifyCaptchaChallenge } = require('../utils/publicCaptcha'); -const { getMembership } = require('../utils/participantMembership'); +const { getMembership, addMembershipTags } = require('../utils/participantMembership'); const { publicRegistrationFields } = require('../utils/registrationFormFields'); const { processFormSubmissionFileUploads } = require('../utils/formSubmissionFiles'); const { buildSubmissionReplyEmail } = require('../utils/formReplyMail'); const { sendOrgMail } = require('../utils/mail'); +const { sendRegistrationConfirmationEmail } = require('../utils/registrationConfirmationMail'); +const { phoneLast10Digits } = require('../utils/phone'); const { assertModulePermission, buildFormAccessFilter, @@ -41,14 +44,24 @@ function eventRegistrationStatus(event) { return 'confirmed'; } -async function assertCanRegisterForEvent(event) { +async function assertCanRegisterForEvent(event, formSettings) { const settings = event.settings || {}; if (settings.registrationOpen === false) { - throwRegError('Registration is closed for this event', 'REGISTRATION_CLOSED'); + throwRegError( + formSettingMessage(formSettings, 'registrationClosedMessage', 'Registration is closed for this event'), + 'REGISTRATION_CLOSED', + ); } const deadline = settings.registrationDeadline; if (deadline && new Date(deadline).getTime() <= Date.now()) { - throwRegError('Registration deadline has passed', 'REGISTRATION_CLOSED'); + throwRegError( + formSettingMessage( + formSettings, + 'registrationDeadlineMessage', + formSettingMessage(formSettings, 'registrationClosedMessage', 'Registration deadline has passed'), + ), + 'REGISTRATION_CLOSED', + ); } const max = settings.maxParticipants; if (max && max > 0) { @@ -56,7 +69,10 @@ async function assertCanRegisterForEvent(event) { eventMemberships: { $elemMatch: { event: event._id } }, }); if (count >= max) { - throwRegError('This event has reached maximum participants', 'REGISTRATION_FULL'); + throwRegError( + formSettingMessage(formSettings, 'registrationFullMessage', 'This event has reached maximum participants'), + 'REGISTRATION_FULL', + ); } } } @@ -71,7 +87,7 @@ async function ensureEventMembershipForRegistrationForm(form, participant) { const eventId = event._id; if (getMembership(participant, eventId)) return; - await assertCanRegisterForEvent(event); + await assertCanRegisterForEvent(event, form.settings); participant.eventMemberships = participant.eventMemberships || []; participant.eventMemberships.push({ event: eventId, @@ -98,6 +114,34 @@ function fieldDataKey(f) { return String(f?.name || f?.label || '').trim(); } +/** Collect tag strings from a submitted field value (string or string[]). */ +function tagsFromSubmittedValue(val) { + if (val == null) return []; + if (Array.isArray(val)) { + return val + .flatMap((v) => tagsFromSubmittedValue(v)) + .map((t) => String(t).trim()) + .filter(Boolean); + } + if (typeof val === 'object') return []; + const s = String(val).trim(); + return s ? [s] : []; +} + +function collectConvertToTagValues(form, dataObj) { + const selectableTypes = new Set(['select', 'radio', 'checkboxes', 'checkbox']); + const out = []; + for (const f of form.fields || []) { + if (!f || f.convertToTag !== true) continue; + if (f.type === 'section') continue; + if (!selectableTypes.has(String(f.type || ''))) continue; + const key = fieldDataKey(f); + if (!key) continue; + out.push(...tagsFromSubmittedValue(dataObj[key])); + } + return out; +} + function csvColumnsFromFormFields(fields) { const cols = []; for (const f of fields || []) { @@ -168,6 +212,46 @@ async function upsertParticipantFromRegistrationForm(form, tenantOrganization, d updates[map] = map === 'email' ? String(val).trim().toLowerCase() : String(val).trim(); } + const { ev: resolvedEvent } = await resolveEventForPublicForm(form); + const eventOid = resolvedEvent?._id || null; + const allowDupEmail = form.settings?.allowDuplicateEmail !== false; + const allowDupPhone = form.settings?.allowDuplicatePhone !== false; + + if (eventOid && !allowDupEmail) { + const existingByEmail = await Participant.findOne({ tenantOrganization: orgOid, email }).lean(); + if (existingByEmail && getMembership(existingByEmail, eventOid)) { + throwRegValidation( + formSettingMessage(form, 'duplicateEmailMessage', 'This email is already registered for this event.'), + 'DUPLICATE_EMAIL', + ); + } + } + + if (eventOid && !allowDupPhone) { + const phoneKey = phoneLast10Digits(updates.phone); + if (phoneKey.length >= 10) { + const candidates = await Participant.find({ + tenantOrganization: orgOid, + phone: { $exists: true, $nin: [null, ''] }, + eventMemberships: { $elemMatch: { event: eventOid } }, + }) + .select('_id email phone') + .lean(); + const clash = candidates.find((c) => { + const other = phoneLast10Digits(c.phone); + if (other.length < 10 || other !== phoneKey) return false; + // Same email is handled by allowDuplicateEmail (upsert / email duplicate). + return String(c.email || '').toLowerCase() !== email; + }); + if (clash) { + throwRegValidation( + formSettingMessage(form, 'duplicatePhoneMessage', 'This phone number is already registered for this event.'), + 'DUPLICATE_PHONE', + ); + } + } + } + let p = await Participant.findOne({ tenantOrganization: orgOid, email }); if (!p) { p = await Participant.create({ @@ -197,14 +281,6 @@ async function upsertParticipantFromRegistrationForm(form, tenantOrganization, d await p.save(); } - const tagList = (form.settings?.onSubmitAddTags || []) - .map((t) => String(t).trim()) - .filter(Boolean); - if (tagList.length) { - p.tags = [...new Set([...(p.tags || []).map(String), ...tagList])]; - await p.save(); - } - const listId = form.settings?.onSubmitParticipantListId; if (listId && mongoose.Types.ObjectId.isValid(String(listId))) { const list = await ParticipantList.findById(listId).lean(); @@ -215,6 +291,17 @@ async function upsertParticipantFromRegistrationForm(form, tenantOrganization, d await ensureEventMembershipForRegistrationForm(form, p); + const tagList = [ + ...(form.settings?.onSubmitAddTags || []).map((t) => String(t).trim()).filter(Boolean), + ...collectConvertToTagValues(form, dataObj), + ]; + if (tagList.length) { + const eventOid = await resolveSubmissionEventId(form); + if (eventOid && addMembershipTags(p, eventOid, tagList)) { + await p.save(); + } + } + return p._id; } @@ -286,6 +373,25 @@ const listByOrganization = async (request, h) => { return h.response(success({ forms: formsWithCount })); }; +/** Avoid CastError when ObjectId settings fields are "" or invalid. */ +function sanitizeFormSettings(settings) { + if (!settings || typeof settings !== 'object') return settings; + const next = { ...settings }; + const listId = next.onSubmitParticipantListId; + if (listId == null || listId === '') { + delete next.onSubmitParticipantListId; + } else if (!mongoose.Types.ObjectId.isValid(String(listId))) { + delete next.onSubmitParticipantListId; + } + const tplId = next.confirmationEmailTemplateId; + if (tplId == null || tplId === '') { + next.confirmationEmailTemplateId = null; + } else if (!mongoose.Types.ObjectId.isValid(String(tplId))) { + next.confirmationEmailTemplateId = null; + } + return next; +} + const create = async (request, h) => { const { eventId } = request.params; const event = await Event.findById(eventId); @@ -293,17 +399,25 @@ const create = async (request, h) => { const user = request.auth.credentials.user; const orgId = userOrgId(user); await assertModulePermission(user, orgId, 'forms', 'write'); - if (!(await canAccessEvent(user, orgId, eventId, 'write'))) { + // Linking a form only requires event visibility, not event write. + if (!(await canAccessEvent(user, orgId, eventId, 'read'))) { return h.response(error('FORBIDDEN', 'Access denied')).code(403); } - const form = await Form.create({ - ...request.payload, - event: eventId, - tenantOrganization: event.organization, - createdBy: user._id, - defaultVisibility: request.payload.defaultVisibility || 'org', - }); - return h.response(success(form, 'Form created', 201)).code(201); + try { + const { settings, ...rest } = request.payload || {}; + const form = await Form.create({ + ...rest, + settings: sanitizeFormSettings(settings), + event: eventId, + tenantOrganization: event.organization, + createdBy: user._id, + defaultVisibility: request.payload.defaultVisibility || 'org', + }); + return h.response(success(form, 'Form created', 201)).code(201); + } catch (err) { + const msg = err?.message || 'Failed to create form'; + return h.response(error('VALIDATION_ERROR', msg)).code(400); + } }; /** Create form at organization scope (optional event link). */ @@ -331,19 +445,26 @@ const createByOrganization = async (request, h) => { return h.response(error('FORBIDDEN', 'Event does not belong to your organization')).code(403); } await assertModulePermission(user, toid, 'forms', 'write'); - if (!(await canAccessEvent(user, toid, body.event, 'write'))) { + // Linking a form only requires event visibility, not event write. + if (!(await canAccessEvent(user, toid, body.event, 'read'))) { return h.response(error('FORBIDDEN', 'Access denied to this event')).code(403); } - const { event: _e, tenantOrganization: _t, ...rest } = body; - const form = await Form.create({ - ...rest, - tenantOrganization: toid, - event: body.event, - createdBy: user._id, - defaultVisibility: body.defaultVisibility || 'org', - }); - return h.response(success(form, 'Form created', 201)).code(201); + const { event: _e, tenantOrganization: _t, settings, ...rest } = body; + try { + const form = await Form.create({ + ...rest, + settings: sanitizeFormSettings(settings), + tenantOrganization: toid, + event: body.event, + createdBy: user._id, + defaultVisibility: body.defaultVisibility || 'org', + }); + return h.response(success(form, 'Form created', 201)).code(201); + } catch (err) { + const msg = err?.message || 'Failed to create form'; + return h.response(error('VALIDATION_ERROR', msg)).code(400); + } }; const get = async (request, h) => { @@ -364,8 +485,17 @@ const update = async (request, h) => { if (!allowed) return h.response(error('FORBIDDEN', 'Access denied')).code(403); const payload = { ...request.payload }; delete payload.tenantOrganization; - const { event: eventId, ...rest } = payload; + const { event: eventId, settings, ...rest } = payload; Object.assign(form, rest); + if (settings !== undefined) { + form.settings = sanitizeFormSettings({ + ...(form.settings && typeof form.settings.toObject === 'function' + ? form.settings.toObject() + : form.settings || {}), + ...settings, + }); + form.markModified('settings'); + } if (eventId !== undefined && eventId !== null) { if (!mongoose.Types.ObjectId.isValid(String(eventId))) { return h.response(error('VALIDATION_ERROR', 'Invalid event')).code(400); @@ -377,7 +507,12 @@ const update = async (request, h) => { } form.event = eventId; } - await form.save(); + try { + await form.save(); + } catch (err) { + const msg = err?.message || 'Failed to update form'; + return h.response(error('VALIDATION_ERROR', msg)).code(400); + } const updated = await Form.findById(form._id).populate('event', 'name'); return h.response(success(updated)); }; @@ -398,8 +533,22 @@ const submit = async (request, h) => { const { formId } = request.params; const form = await Form.findById(formId).lean(); if (!form) return h.response(error('NOT_FOUND', 'Form not found')).code(404); - if (!form.settings?.isActive) return h.response(error('VALIDATION_ERROR', 'Form is not accepting submissions')).code(400); + if (!form.settings?.isActive) { + return h + .response( + error( + 'VALIDATION_ERROR', + formSettingMessage(form, 'formClosedMessage', 'Form is not accepting submissions'), + ), + ) + .code(400); + } const user = request.auth?.credentials?.user; + const captchaFailedMsg = formSettingMessage( + form, + 'captchaFailedMessage', + 'Captcha verification failed. Please try again.', + ); if (!user) { if (request.payload._gotcha) { @@ -410,10 +559,10 @@ const submit = async (request, h) => { if (captchaToken) { const captchaOk = verifyCaptchaChallenge(captchaToken, request.payload.captchaAnswer); if (!captchaOk) { - return h.response(error('VALIDATION_ERROR', 'Captcha verification failed. Please try again.')).code(400); + return h.response(error('VALIDATION_ERROR', captchaFailedMsg)).code(400); } } else if (process.env.PUBLIC_FORM_CAPTCHA_REQUIRED === 'true') { - return h.response(error('VALIDATION_ERROR', 'Captcha verification failed. Please try again.')).code(400); + return h.response(error('VALIDATION_ERROR', captchaFailedMsg)).code(400); } } @@ -449,7 +598,9 @@ const submit = async (request, h) => { err.code === 'REGISTRATION_REQUIRED' || err.code === 'FORM_FIELD_CONFIG' || err.code === 'REGISTRATION_CLOSED' || - err.code === 'REGISTRATION_FULL' + err.code === 'REGISTRATION_FULL' || + err.code === 'DUPLICATE_EMAIL' || + err.code === 'DUPLICATE_PHONE' ) { const statusCode = err.code === 'REGISTRATION_CLOSED' || err.code === 'REGISTRATION_FULL' ? 403 : 400; @@ -478,6 +629,16 @@ const submit = async (request, h) => { }); } + if (form.type === 'registration' && participantId) { + void sendRegistrationConfirmationEmail({ + form, + participantId, + eventId: submissionEventId, + }).catch((err) => { + console.error('[registrationConfirmation] unexpected error', err?.message || err); + }); + } + return h.response(success(submission, 'Submission received', 201)).code(201); }; @@ -651,7 +812,14 @@ const getPublicForm = async (request, h) => { const form = await Form.findById(request.params.formId).lean(); if (!form) return h.response(error('NOT_FOUND', 'Form not found')).code(404); if (!form.settings?.isActive) { - return h.response(error('VALIDATION_ERROR', 'This form is not accepting responses.')).code(400); + return h + .response( + error( + 'VALIDATION_ERROR', + formSettingMessage(form, 'formClosedMessage', 'This form is not accepting responses.'), + ), + ) + .code(400); } const { ev: resolvedEvent, micrositeLogo } = await resolveEventForPublicForm(form); diff --git a/src/controllers/media.controller.js b/src/controllers/media.controller.js index ba93656..1363a77 100644 --- a/src/controllers/media.controller.js +++ b/src/controllers/media.controller.js @@ -42,6 +42,14 @@ function normalizeVisibility(v) { return 'private'; } +/** S3 paths may use the sentinel `portfolio`; Mongo `eventId` must be a valid ObjectId or omitted. */ +function contentEventIdForDocument(raw) { + const s = String(raw || '').trim(); + if (!s || s === 'portfolio') return undefined; + if (!mongoose.Types.ObjectId.isValid(s)) return undefined; + return new mongoose.Types.ObjectId(s); +} + /** * Hapi route payload.output only allows data|stream|file. With output:'data', binary file parts are often * a raw Buffer on payload.file (see @hapi/subtext internals.part). Some clients may send { _data } or { payload }. @@ -127,7 +135,8 @@ const upload = async (request, h) => { const extracted = extractUploadFile(payload); // Required by your storage scheme: eventbuzz////... - const eventId = payload.eventId || payload.event_id || payload.event || ''; + const eventIdRaw = payload.eventId || payload.event_id || payload.event || ''; + const eventId = eventIdRaw || 'event'; const module = payload.module || payload.collectionName || 'general'; const isLibraryUpload = String(module) === LIBRARY_MODULE; @@ -184,7 +193,7 @@ const upload = async (request, h) => { const baseDoc = { organization: orgId, - eventId: eventId || undefined, + eventId: contentEventIdForDocument(eventIdRaw), name: payload.name || extracted?.filename || 'Untitled', description, visibility, diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index e2c709e..8483752 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -306,7 +306,18 @@ const testEmailSettings = async (request, h) => { if (!r.ok && r.skipped) { return h.response(error('VALIDATION_ERROR', 'No SMTP available — enable organisation SMTP or set MAIL_HOST on the server')).code(400); } - if (!r.ok) return h.response(error('SEND_FAILED', r.error || 'Send failed')).code(502); + if (!r.ok) { + const raw = String(r.error || 'Send failed'); + let message = raw; + if (/535\s*5\.7\.3|Authentication unsuccessful/i.test(raw)) { + message = + 'SMTP login rejected by the mail server (535 Authentication unsuccessful). ' + + 'For Microsoft 365 / Outlook: use host smtp.office365.com, port 587, SSL/TLS off; ' + + 'username must be the full mailbox email; enable Authenticated SMTP for that user in Microsoft 365 admin; ' + + 'if MFA is on, use an App Password (or OAuth — basic password auth is often blocked by Security Defaults).'; + } + return h.response(error('SEND_FAILED', message)).code(502); + } return h.response(success({ ok: true })); }; diff --git a/src/controllers/participant.controller.js b/src/controllers/participant.controller.js index 18b6b2c..5edf173 100644 --- a/src/controllers/participant.controller.js +++ b/src/controllers/participant.controller.js @@ -4,7 +4,7 @@ const Event = require('../models/Event'); const ParticipantList = require('../models/ParticipantList'); const { success, error } = require('../utils/response'); const { parseParticipantCsv, splitTags, escapeCsvField } = require('../utils/csvParticipant'); -const { getMembership, flattenParticipantForEvent, baseQueryForEvent } = require('../utils/participantMembership'); +const { getMembership, flattenParticipantForEvent, baseQueryForEvent, addMembershipTags, removeMembershipTags, removeTagsEverywhere, setMembershipTags, normalizeTagList } = require('../utils/participantMembership'); const { resolveScopedOrganizationId } = require('../utils/tenantListScope'); const { assertModulePermission, userOrgId } = require('../services/acl.service'); const { canAccessEvent } = require('../services/eventScope.service'); @@ -62,6 +62,25 @@ function listAllTenantOnlyMatch(user, queryOrganization, payloadOrganization) { return { tenantMatch: { tenantOrganization: scoped.organizationId } }; } +/** Active participants (Mongo `{ deletedAt: null }` also matches missing field). */ +function activeParticipantsMatch() { + return { deletedAt: null }; +} + +function deletedParticipantsMatch() { + return { deletedAt: { $type: 'date' } }; +} + +async function softDeleteParticipant(participant) { + participant.deletedAt = new Date(); + await participant.save(); +} + +async function assertParticipantsDelete(user) { + const orgId = userOrgId(user); + await assertModulePermission(user, orgId, 'participants', 'delete'); +} + function listAllCommonStages(query, options = {}) { const { skipSort = false } = options; const { q, tag } = query; @@ -161,6 +180,7 @@ function listAllProjectStages() { organization: 1, designation: 1, notes: 1, + deletedAt: 1, registrationDate: '$_primary.registrationDate', status: '$_primary.status', checkedIn: '$_primary.checkedIn', @@ -186,7 +206,7 @@ function eventParticipantPreStages(eventId, orgId, query = {}) { const { status, designation, q, tag } = query; const eid = new mongoose.Types.ObjectId(String(eventId)); const stages = [ - { $match: { tenantOrganization: orgId } }, + { $match: { tenantOrganization: orgId, ...activeParticipantsMatch() } }, { $unwind: '$eventMemberships' }, { $match: { 'eventMemberships.event': eid } }, ]; @@ -240,7 +260,7 @@ const listDistinctTags = async (request, h) => { const { tenantMatch } = r; const rows = await Participant.aggregate([ - { $match: tenantMatch }, + { $match: { ...tenantMatch, ...activeParticipantsMatch() } }, { $addFields: { _allTags: { @@ -274,7 +294,7 @@ const listMatchingIds = async (request, h) => { const { q, tag } = request.query; const stages = [ - { $match: tenantMatch }, + { $match: { ...tenantMatch, ...activeParticipantsMatch() } }, ...listAllCommonStages({ q, tag }, { skipSort: true }), { $project: { _id: 1 } }, { $limit: BULK_MAX + 1 }, @@ -336,7 +356,7 @@ const bulkParticipants = async (request, h) => { if (r.error) return h.response(error(r.error.code, r.error.message)).code(400); const { tenantMatch } = r; const stages = [ - { $match: tenantMatch }, + { $match: { ...tenantMatch, ...activeParticipantsMatch() } }, ...listAllCommonStages({ q, tag: filterTag }, { skipSort: true }), { $project: { _id: 1 } }, { $limit: BULK_MAX + 1 }, @@ -370,23 +390,41 @@ const bulkParticipants = async (request, h) => { } if (action === 'delete') { - await Participant.deleteMany({ _id: { $in: oids } }); + try { + await assertParticipantsDelete(user); + } catch (e) { + return h.response(error('FORBIDDEN', e.message || 'Access denied')).code(403); + } + const now = new Date(); + await Participant.updateMany({ _id: { $in: oids } }, { $set: { deletedAt: now } }); return h.response(success({ deleted: participants.length })); } if (action === 'add_tags' || action === 'remove_tags') { const tagList = (tagPayload || []).map((t) => String(t).trim()).filter(Boolean); if (!tagList.length) return h.response(error('VALIDATION_ERROR', 'tags required')).code(400); - const removeSet = new Set(tagList); + const scopeEventId = + bulkEventId && mongoose.Types.ObjectId.isValid(String(bulkEventId)) ? String(bulkEventId) : null; + if (scopeEventId) { + const access = await assertEventAccess(scopeEventId, user, 'write'); + if (access.error) return access.error(h); + } + let updated = 0; for (const p of participants) { - if (action === 'add_tags') { + if (scopeEventId) { + if (!getMembership(p, scopeEventId)) continue; + if (action === 'add_tags') addMembershipTags(p, scopeEventId, tagList); + else removeMembershipTags(p, scopeEventId, tagList); + } else if (action === 'add_tags') { p.tags = [...new Set([...(p.tags || []), ...tagList])]; } else { - p.tags = (p.tags || []).filter((t) => !removeSet.has(t)); + // Global UI shows root ∪ all membership tags — remove everywhere so the tag disappears. + removeTagsEverywhere(p, tagList); } await p.save(); + updated += 1; } - return h.response(success({ updated: participants.length })); + return h.response(success({ updated })); } if (action === 'assign_events') { @@ -436,6 +474,11 @@ const bulkParticipants = async (request, h) => { } if (action === 'remove_from_event') { + try { + await assertParticipantsDelete(user); + } catch (e) { + return h.response(error('FORBIDDEN', e.message || 'Access denied')).code(403); + } if (!bulkEventId || !mongoose.Types.ObjectId.isValid(String(bulkEventId))) { return h.response(error('VALIDATION_ERROR', 'eventId required')).code(400); } @@ -446,7 +489,7 @@ const bulkParticipants = async (request, h) => { if (!getMembership(p, bulkEventId)) continue; p.eventMemberships = p.eventMemberships.filter((m) => String(m.event) !== String(bulkEventId)); if (p.eventMemberships.length === 0) { - await p.deleteOne(); + await softDeleteParticipant(p); } else { await p.save(); } @@ -464,12 +507,15 @@ const listAll = async (request, h) => { if (r.error) return h.response(error(r.error.code, r.error.message)).code(400); const { tenantMatch } = r; - const { page = 1, limit = 20, q, tag } = request.query; + const { page = 1, limit = 20, q, tag, deleted } = request.query; const limitNum = Math.min(Math.max(parseInt(limit, 10) || 20, 1), 100); const pageNum = Math.max(parseInt(page, 10) || 1, 1); const skip = (pageNum - 1) * limitNum; - const preFacet = [{ $match: tenantMatch }, ...listAllCommonStages({ q, tag })]; + const showDeleted = deleted === true || deleted === 'true' || deleted === '1'; + const deletedMatch = showDeleted ? deletedParticipantsMatch() : activeParticipantsMatch(); + + const preFacet = [{ $match: { ...tenantMatch, ...deletedMatch } }, ...listAllCommonStages({ q, tag })]; const facet = await Participant.aggregate([ ...preFacet, { @@ -602,12 +648,13 @@ const create = async (request, h) => { const orgId = event.organization; const payload = { ...request.payload }; - const tags = Array.isArray(payload.tags) ? payload.tags : []; + const tags = normalizeTagList(Array.isArray(payload.tags) ? payload.tags : []); delete payload.tags; const existing = await Participant.findOne({ tenantOrganization: orgId, email: String(payload.email || '').trim().toLowerCase(), + ...activeParticipantsMatch(), }); if (existing) { @@ -618,25 +665,49 @@ const create = async (request, h) => { event: eventId, status: 'pending', registrationDate: new Date(), + tags: tags.length ? tags : [], }); Object.assign(existing, payload); - if (tags.length) { - existing.tags = [...new Set([...(existing.tags || []), ...tags])]; - } await existing.save(); const flat = flattenParticipantForEvent(existing.toObject(), eventId); return h.response(success(flat, 'Participant added', 201)).code(201); } + // Soft-deleted person with same email: restore and add event membership + const softDeleted = await Participant.findOne({ + tenantOrganization: orgId, + email: String(payload.email || '').trim().toLowerCase(), + ...deletedParticipantsMatch(), + }); + if (softDeleted) { + softDeleted.deletedAt = null; + if (!getMembership(softDeleted, eventId)) { + softDeleted.eventMemberships.push({ + event: eventId, + status: 'pending', + registrationDate: new Date(), + tags: tags.length ? tags : [], + }); + } else if (tags.length) { + addMembershipTags(softDeleted, eventId, tags); + } + Object.assign(softDeleted, payload); + await softDeleted.save(); + const flat = flattenParticipantForEvent(softDeleted.toObject(), eventId); + return h.response(success(flat, 'Participant restored and added', 201)).code(201); + } + const doc = await Participant.create({ ...payload, tenantOrganization: orgId, - tags, + tags: [], + deletedAt: null, eventMemberships: [ { event: eventId, status: 'pending', registrationDate: new Date(), + tags: tags.length ? tags : [], }, ], }); @@ -684,7 +755,15 @@ const update = async (request, h) => { } if (tags !== undefined) { - participant.tags = Array.isArray(tags) ? tags : []; + const scopedEventId = eventId && mongoose.Types.ObjectId.isValid(String(eventId)) ? String(eventId) : null; + if (scopedEventId) { + if (!getMembership(participant, scopedEventId)) { + return h.response(error('NOT_FOUND', 'No membership for this event')).code(404); + } + setMembershipTags(participant, scopedEventId, Array.isArray(tags) ? tags : []); + } else { + participant.tags = Array.isArray(tags) ? tags : []; + } } await participant.save(); @@ -699,21 +778,66 @@ const remove = async (request, h) => { if (!assertParticipantOrgAccess(participant, user)) { return h.response(error('FORBIDDEN', 'Access denied')).code(403); } + try { + await assertParticipantsDelete(user); + } catch (e) { + return h.response(error('FORBIDDEN', e.message || 'Access denied')).code(403); + } + if (participant.deletedAt) { + return h.response(error('BAD_REQUEST', 'Participant is already deleted')).code(400); + } const eventId = request.query.event_id; if (eventId) { participant.eventMemberships = participant.eventMemberships.filter((m) => String(m.event) !== String(eventId)); if (participant.eventMemberships.length === 0) { - await participant.deleteOne(); + await softDeleteParticipant(participant); } else { await participant.save(); } } else { - await participant.deleteOne(); + await softDeleteParticipant(participant); } return h.response(success(null, 'Participant removed')).code(200); }; +const restore = async (request, h) => { + const participant = await Participant.findById(request.params.id); + if (!participant) return h.response(error('NOT_FOUND', 'Participant not found')).code(404); + const user = request.auth.credentials.user; + if (!assertParticipantOrgAccess(participant, user)) { + return h.response(error('FORBIDDEN', 'Access denied')).code(403); + } + try { + await assertParticipantsDelete(user); + } catch (e) { + return h.response(error('FORBIDDEN', e.message || 'Access denied')).code(403); + } + if (!participant.deletedAt) { + return h.response(error('BAD_REQUEST', 'Participant is not deleted')).code(400); + } + + // Block restore if an active participant already uses this email in the tenant + const email = String(participant.email || '').trim().toLowerCase(); + if (email) { + const clash = await Participant.findOne({ + _id: { $ne: participant._id }, + tenantOrganization: participant.tenantOrganization, + email, + ...activeParticipantsMatch(), + }).select('_id').lean(); + if (clash) { + return h + .response(error('CONFLICT', 'An active participant with this email already exists. Resolve the duplicate before restoring.')) + .code(409); + } + } + + participant.deletedAt = null; + await participant.save(); + return h.response(success(participant.toObject(), 'Participant restored')); +}; + const checkIn = async (request, h) => { const participant = await Participant.findById(request.params.id); if (!participant) return h.response(error('NOT_FOUND', 'Participant not found')).code(404); @@ -736,6 +860,41 @@ const checkIn = async (request, h) => { return h.response(success(flat, 'Checked in')); }; +async function setMembershipStatusFromPending(request, h, nextStatus, okMessage) { + const participant = await Participant.findById(request.params.id); + if (!participant) return h.response(error('NOT_FOUND', 'Participant not found')).code(404); + const user = request.auth.credentials.user; + if (!assertParticipantOrgAccess(participant, user)) { + return h.response(error('FORBIDDEN', 'Access denied')).code(403); + } + + const orgId = userOrgId(user); + try { + await assertModulePermission(user, orgId, 'participants', 'write'); + } catch (e) { + return h.response(error('FORBIDDEN', e.message || 'Access denied')).code(403); + } + + const eventId = request.query.event_id; + if (!eventId) return h.response(error('BAD_REQUEST', 'event_id is required')).code(400); + const m = getMembership(participant, eventId); + if (!m) return h.response(error('BAD_REQUEST', 'Participant is not registered for this event')).code(400); + if (m.status !== 'pending') { + return h.response(error('BAD_REQUEST', 'Only pending registrations can be updated')).code(400); + } + + m.status = nextStatus; + participant.markModified('eventMemberships'); + await participant.save(); + + const flat = flattenParticipantForEvent(participant.toObject(), eventId); + return h.response(success(flat, okMessage)); +} + +const confirm = async (request, h) => setMembershipStatusFromPending(request, h, 'confirmed', 'Confirmed'); + +const reject = async (request, h) => setMembershipStatusFromPending(request, h, 'rejected', 'Rejected'); + const exportCsv = async (request, h) => { const { eventId } = request.params; const user = request.auth.credentials.user; @@ -744,6 +903,7 @@ const exportCsv = async (request, h) => { const raw = await Participant.find({ tenantOrganization: r.event.organization, + ...activeParticipantsMatch(), ...baseQueryForEvent(eventId), }) .sort({ updatedAt: -1 }) @@ -766,10 +926,20 @@ const exportCsv = async (request, h) => { }).filter(Boolean); const csv = `\uFEFF${[headerLine, ...dataLines].join('\n')}`; + const safeName = String(eventName || 'Event') + .replace(/[\\/:*?"<>|]+/g, '-') + .replace(/\s+/g, ' ') + .trim() + .slice(0, 80) || 'Event'; + const downloadName = `${safeName} - Participants.csv`; + const asciiFallback = downloadName.replace(/[^\x20-\x7E]/g, '_'); return h .response(csv) .type('text/csv; charset=utf-8') - .header('Content-Disposition', 'attachment; filename="participants-export.csv"') + .header( + 'Content-Disposition', + `attachment; filename="${asciiFallback.replace(/"/g, '')}"; filename*=UTF-8''${encodeURIComponent(downloadName)}` + ) .code(200); }; @@ -827,10 +997,8 @@ const importCsv = async (request, h) => { event: eventId, status: 'pending', registrationDate: new Date(), + tags: tags.length ? tags : [], }); - if (tags.length) { - p.tags = [...new Set([...(p.tags || []), ...tags])]; - } await p.save(); created += 1; } else { @@ -843,12 +1011,13 @@ const importCsv = async (request, h) => { organization, designation, notes, - tags: tags.length ? tags : [], + tags: [], eventMemberships: [ { event: eventId, status: 'pending', registrationDate: new Date(), + tags: tags.length ? tags : [], }, ], }); @@ -883,7 +1052,7 @@ const exportAllCsv = async (request, h) => { const { q, tag } = request.query; - const stages = [{ $match: tenantMatch }, ...listAllCommonStages({ q, tag }), ...listAllProjectStages()]; + const stages = [{ $match: { ...tenantMatch, ...activeParticipantsMatch() } }, ...listAllCommonStages({ q, tag }), ...listAllProjectStages()]; const rows = await Participant.aggregate(stages); const headerLine = EXPORT_HEADERS_FIXED.join(','); const dataLines = rows.map((flat) => @@ -1080,7 +1249,10 @@ module.exports = { get, update, remove, + restore, checkIn, + confirm, + reject, exportCsv, importCsv, exportAllCsv, diff --git a/src/controllers/platformAdmin.controller.js b/src/controllers/platformAdmin.controller.js index 8a65a64..12f693e 100644 --- a/src/controllers/platformAdmin.controller.js +++ b/src/controllers/platformAdmin.controller.js @@ -93,10 +93,69 @@ function escapeRegex(s) { return String(s).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } -function serializeOrgDoc(org, userCount) { +function serializePrimaryAdmin(user) { + if (!user) return null; + return { + _id: user._id != null ? String(user._id) : user._id, + firstName: user.firstName || '', + lastName: user.lastName || '', + email: user.email || '', + phone: user.phone || '', + role: user.role || '', + }; +} + +/** + * Resolve the primary org admin (super_admin) for each organization id. + * Prefers OrganizationUserMap, then falls back to User.organization. + */ +async function loadPrimaryAdminsByOrgIds(orgIds) { + const byOrg = new Map(); + if (!orgIds.length) return byOrg; + + const maps = await OrganizationUserMap.find({ + organization: { $in: orgIds }, + role: 'super_admin', + }) + .populate('user', 'firstName lastName email phone role') + .sort({ createdAt: 1 }) + .lean(); + + for (const m of maps) { + const oid = String(m.organization); + if (byOrg.has(oid) || !m.user) continue; + byOrg.set(oid, serializePrimaryAdmin(m.user)); + } + + const missing = orgIds.filter((id) => !byOrg.has(String(id))); + if (missing.length) { + const users = await User.find({ + organization: { $in: missing }, + role: 'super_admin', + }) + .select('firstName lastName email phone role organization') + .sort({ createdAt: 1 }) + .lean(); + for (const u of users) { + const oid = String(u.organization); + if (byOrg.has(oid)) continue; + byOrg.set(oid, serializePrimaryAdmin(u)); + } + } + + return byOrg; +} + +async function loadPrimaryAdminForOrg(orgId) { + const map = await loadPrimaryAdminsByOrgIds([orgId]); + return map.get(String(orgId)) || null; +} + +function serializeOrgDoc(org, userCount, primaryAdmin = null) { const o = typeof org.toObject === 'function' ? org.toObject() : { ...org }; o._id = o._id != null ? String(o._id) : o._id; o.userCount = userCount; + o.primaryAdmin = primaryAdmin || null; return o; } @@ -107,18 +166,27 @@ async function listOrganizations(request, h) { const q = {}; if (search) { const rx = new RegExp(escapeRegex(search), 'i'); - q.$or = [{ name: rx }, { email: rx }]; + const matchingAdmins = await User.find({ + role: 'super_admin', + $or: [{ email: rx }, { firstName: rx }, { lastName: rx }, { phone: rx }], + }) + .select('organization') + .lean(); + const adminOrgIds = matchingAdmins.map((u) => u.organization).filter(Boolean); + q.$or = [{ name: rx }, { email: rx }, ...(adminOrgIds.length ? [{ _id: { $in: adminOrgIds } }] : [])]; } const skip = (page - 1) * limit; const [orgs, total] = await Promise.all([ Organization.find(q).sort({ createdAt: -1 }).skip(skip).limit(limit).lean(), Organization.countDocuments(q), ]); - const organizations = await Promise.all( - orgs.map(async (org) => { - const userCount = await User.countDocuments({ organization: org._id }); - return serializeOrgDoc(org, userCount); - }), + const orgIds = orgs.map((org) => org._id); + const [counts, primaryByOrg] = await Promise.all([ + Promise.all(orgIds.map((id) => User.countDocuments({ organization: id }))), + loadPrimaryAdminsByOrgIds(orgIds), + ]); + const organizations = orgs.map((org, i) => + serializeOrgDoc(org, counts[i], primaryByOrg.get(String(org._id)) || null), ); return h.response(success({ organizations, total, page, limit })).code(200); } @@ -173,7 +241,8 @@ async function createOrganization(request, h) { }); const userCount = await User.countDocuments({ organization: org._id }); - const organization = serializeOrgDoc(await Organization.findById(org._id).lean(), userCount); + const primaryAdmin = serializePrimaryAdmin(user); + const organization = serializeOrgDoc(await Organization.findById(org._id).lean(), userCount, primaryAdmin); const adminOut = user.toObject(); delete adminOut.password; @@ -190,8 +259,11 @@ async function createOrganization(request, h) { async function getOrganization(request, h) { const org = await Organization.findById(request.params.id).lean(); if (!org) return h.response(error('NOT_FOUND', 'Organization not found')).code(404); - const userCount = await User.countDocuments({ organization: org._id }); - return h.response(success({ organization: serializeOrgDoc(org, userCount) })).code(200); + const [userCount, primaryAdmin] = await Promise.all([ + User.countDocuments({ organization: org._id }), + loadPrimaryAdminForOrg(org._id), + ]); + return h.response(success({ organization: serializeOrgDoc(org, userCount, primaryAdmin) })).code(200); } async function patchOrganizationSubscription(request, h) { @@ -209,8 +281,11 @@ async function patchOrganizationSubscription(request, h) { org.subscription = sub; org.markModified('subscription'); await org.save(); - const userCount = await User.countDocuments({ organization: org._id }); - return h.response(success({ organization: serializeOrgDoc(org, userCount) })).code(200); + const [userCount, primaryAdmin] = await Promise.all([ + User.countDocuments({ organization: org._id }), + loadPrimaryAdminForOrg(org._id), + ]); + return h.response(success({ organization: serializeOrgDoc(org, userCount, primaryAdmin) })).code(200); } async function listPermissions(request, h) { diff --git a/src/controllers/publicMicrosite.controller.js b/src/controllers/publicMicrosite.controller.js index bc4d379..9f2f068 100644 --- a/src/controllers/publicMicrosite.controller.js +++ b/src/controllers/publicMicrosite.controller.js @@ -10,6 +10,7 @@ const { buildPublicEventPayload, buildPublicFormSettings, resolveEventForPublicForm, + settingMessage, } = require('../utils/formPublicHelpers'); function publicEventSummary(event) { @@ -40,9 +41,22 @@ function publicEventSummary(event) { }; } +function publicThemeBag(theme) { + if (!theme || typeof theme !== 'object') return null; + const mode = theme.theme != null ? String(theme.theme).trim().toLowerCase() : ''; + const color = theme.color != null ? String(theme.color).trim().toLowerCase() : ''; + const font = theme.font != null ? String(theme.font).trim() : ''; + if (!mode && !color && !font) return null; + return { + theme: mode || 'simple', + color: color || 'blue', + font: font || 'Open Sans', + }; +} + function publicWebsiteBag(website) { const w = website || {}; - return { + const out = { enabled: w.enabled !== false, title: w.title || '', description: w.description || '', @@ -55,6 +69,9 @@ function publicWebsiteBag(website) { layoutTemplate: w.layoutTemplate || 'conference', seoDescription: w.seoDescription || '', }; + const theme = publicThemeBag(w.theme); + if (theme) out.theme = theme; + return out; } async function resolveRegistrationFormId(event) { @@ -161,7 +178,14 @@ async function getPublicEventForm(request, h) { if (!event) return h.response(error('NOT_FOUND', 'Event not found')).code(404); if (!form) return h.response(error('NOT_FOUND', 'Form not found')).code(404); if (!form.settings?.isActive) { - return h.response(error('VALIDATION_ERROR', 'This form is not accepting responses.')).code(400); + return h + .response( + error( + 'VALIDATION_ERROR', + settingMessage(form, 'formClosedMessage', 'This form is not accepting responses.'), + ), + ) + .code(400); } if (!(await formBelongsToEvent(form, event, eventId))) { return h.response(error('FORBIDDEN', 'Form is not available for this event')).code(403); diff --git a/src/controllers/publicQuizPoll.controller.js b/src/controllers/publicQuizPoll.controller.js index 82fab10..84c6965 100644 --- a/src/controllers/publicQuizPoll.controller.js +++ b/src/controllers/publicQuizPoll.controller.js @@ -2,6 +2,11 @@ const QuizPoll = require('../models/QuizPoll'); const QuizPollResponse = require('../models/QuizPollResponse'); const { success, error } = require('../utils/response'); const { buildQuestionPresentationStats } = require('../utils/quizPollResultsSummary'); +const { + applyPublish, + applyClose, + applySetLiveQuestion, +} = require('../utils/quizPollLiveControls'); function presentationPublicBase() { return (process.env.EVENTBUZZ_PUBLIC_URL || 'http://localhost:5174').replace(/\/$/, ''); @@ -22,6 +27,32 @@ function mapQuestionForPresentation(q) { }; } +function mapSettingsForPresentation(settings) { + const s = settings || {}; + return { + displayMode: s.displayMode != null ? String(s.displayMode) : undefined, + isLive: Boolean(s.isLive), + liveQuestionId: + s.liveQuestionId != null && String(s.liveQuestionId).trim() !== '' + ? String(s.liveQuestionId).trim() + : null, + showCorrectAnswer: Boolean(s.showCorrectAnswer), + showResults: s.showResults !== false, + }; +} + +function mapPresentationPayload(quizPoll) { + return { + _id: String(quizPoll._id), + eventId: quizPoll.event != null ? String(quizPoll.event) : '', + sessionId: quizPoll.session != null ? String(quizPoll.session) : '', + title: quizPoll.title != null ? quizPoll.title : '', + type: quizPoll.type != null ? quizPoll.type : 'poll', + settings: mapSettingsForPresentation(quizPoll.settings), + questions: (quizPoll.questions || []).map(mapQuestionForPresentation), + }; +} + async function loadQuizPollByPresentationToken(token) { const t = String(token || '').trim(); if (!t) return null; @@ -31,30 +62,25 @@ async function loadQuizPollByPresentationToken(token) { }).lean(); } +async function loadQuizPollDocByPresentationToken(token) { + const t = String(token || '').trim(); + if (!t) return null; + return QuizPoll.findOne({ + 'settings.presentationToken': t, + deletedAt: null, + }); +} + +function respondLiveControl(h, result) { + if (!result.ok) return h.response(error(result.code, result.message)).code(result.status); + return h.response(success(mapPresentationPayload(result.item), result.message)); +} + /** GET /api/public/quiz-polls/present/{token} */ async function getPresentation(request, h) { const quizPoll = await loadQuizPollByPresentationToken(request.params.token); if (!quizPoll) return h.response(error('NOT_FOUND', 'Presentation not found')).code(404); - - const settings = quizPoll.settings || {}; - return h.response( - success({ - _id: String(quizPoll._id), - eventId: quizPoll.event != null ? String(quizPoll.event) : '', - sessionId: quizPoll.session != null ? String(quizPoll.session) : '', - title: quizPoll.title != null ? quizPoll.title : '', - type: quizPoll.type != null ? quizPoll.type : 'poll', - settings: { - displayMode: settings.displayMode != null ? String(settings.displayMode) : undefined, - liveQuestionId: - settings.liveQuestionId != null && String(settings.liveQuestionId).trim() !== '' - ? String(settings.liveQuestionId).trim() - : null, - showResults: settings.showResults !== false, - }, - questions: (quizPoll.questions || []).map(mapQuestionForPresentation), - }), - ); + return h.response(success(mapPresentationPayload(quizPoll))); } /** GET /api/public/quiz-polls/present/{token}/questions/{questionIndex}/stats */ @@ -78,8 +104,79 @@ async function getQuestionStats(request, h) { return h.response(success(stats)); } +/** POST /api/public/quiz-polls/present/{token}/publish */ +async function publishPresentation(request, h) { + const item = await loadQuizPollDocByPresentationToken(request.params.token); + if (!item) return h.response(error('NOT_FOUND', 'Presentation not found')).code(404); + return respondLiveControl(h, await applyPublish(item)); +} + +/** POST /api/public/quiz-polls/present/{token}/close */ +async function closePresentation(request, h) { + const item = await loadQuizPollDocByPresentationToken(request.params.token); + if (!item) return h.response(error('NOT_FOUND', 'Presentation not found')).code(404); + return respondLiveControl(h, await applyClose(item)); +} + +/** POST /api/public/quiz-polls/present/{token}/live-question */ +async function setPresentationLiveQuestion(request, h) { + const item = await loadQuizPollDocByPresentationToken(request.params.token); + if (!item) return h.response(error('NOT_FOUND', 'Presentation not found')).code(404); + return respondLiveControl(h, await applySetLiveQuestion(item, request.payload?.questionId)); +} + +/** + * GET /api/public/quiz-polls/present/{token}/session-activities + * Sibling quizzes/polls on the same session (token is the capability gate). + */ +async function getSessionActivities(request, h) { + const current = await loadQuizPollByPresentationToken(request.params.token); + if (!current) return h.response(error('NOT_FOUND', 'Presentation not found')).code(404); + + const sessionId = current.session != null ? String(current.session) : ''; + if (!sessionId) { + return h.response(success({ sessionId: null, activities: [] })); + } + + const siblings = await QuizPoll.find({ + session: current.session, + deletedAt: null, + }).sort({ title: 1 }); + + const base = presentationPublicBase(); + const activities = []; + for (const item of siblings) { + item.settings = item.settings || {}; + if (!item.settings.presentationToken || String(item.settings.presentationToken).trim() === '') { + item.settings.presentationToken = QuizPoll.generatePresentationToken(); + await item.save(); + } + const token = String(item.settings.presentationToken).trim(); + const settings = item.settings || {}; + activities.push({ + _id: String(item._id), + title: item.title != null ? String(item.title) : '', + type: item.type != null ? String(item.type) : 'poll', + presentationToken: token, + presentationUrl: `${base}/quiz-present/${encodeURIComponent(token)}`, + isLive: Boolean(settings.isLive), + displayMode: settings.displayMode != null ? String(settings.displayMode) : undefined, + liveQuestionId: + settings.liveQuestionId != null && String(settings.liveQuestionId).trim() !== '' + ? String(settings.liveQuestionId).trim() + : null, + }); + } + + return h.response(success({ sessionId, activities })); +} + module.exports = { getPresentation, getQuestionStats, + publishPresentation, + closePresentation, + setPresentationLiveQuestion, + getSessionActivities, presentationPublicBase, }; diff --git a/src/controllers/quizPoll.controller.js b/src/controllers/quizPoll.controller.js index 093a89e..5609f74 100644 --- a/src/controllers/quizPoll.controller.js +++ b/src/controllers/quizPoll.controller.js @@ -3,26 +3,17 @@ const QuizPollResponse = require('../models/QuizPollResponse'); const Event = require('../models/Event'); const { success, error } = require('../utils/response'); const { syncQuizPollToFirebase } = require('../utils/quizPollFirebaseSync'); +const { + displayModeOf, + applyPublish, + applyClose, + applySetLiveQuestion, +} = require('../utils/quizPollLiveControls'); function presentationPublicBase() { return (process.env.EVENTBUZZ_PUBLIC_URL || 'http://localhost:5174').replace(/\/$/, ''); } -function displayModeOf(item) { - return String(item?.settings?.displayMode || '').trim(); -} - -function questionIdString(q) { - if (!q || q._id == null) return ''; - return String(q._id); -} - -function findQuestionById(item, questionId) { - if (!questionId) return null; - const target = String(questionId).trim(); - return (item.questions || []).find((q) => questionIdString(q) === target) || null; -} - async function assertQuizPollAccess(request, h, item) { const event = await Event.findById(item.event); if (!event) return h.response(error('NOT_FOUND', 'Event not found')).code(404); @@ -103,21 +94,9 @@ const publish = async (request, h) => { if (!item) return h.response(error('NOT_FOUND', 'Quiz/Poll not found')).code(404); const denied = await assertQuizPollAccess(request, h, item); if (denied) return denied; - if (displayModeOf(item) === 'quiz_master') { - return h - .response( - error( - 'VALIDATION_ERROR', - 'Quiz Master mode uses per-question live control. Use POST /quiz-polls/{id}/live-question instead.', - ), - ) - .code(400); - } - item.settings = item.settings || {}; - item.settings.isLive = true; - await item.save(); - await syncQuizPollToFirebase(item); - return h.response(success(item, 'Published')); + const result = await applyPublish(item); + if (!result.ok) return h.response(error(result.code, result.message)).code(result.status); + return h.response(success(result.item, result.message)); }; const close = async (request, h) => { @@ -125,13 +104,8 @@ const close = async (request, h) => { if (!item) return h.response(error('NOT_FOUND', 'Quiz/Poll not found')).code(404); const denied = await assertQuizPollAccess(request, h, item); if (denied) return denied; - item.settings = item.settings || {}; - item.settings.isLive = false; - item.settings.liveQuestionId = null; - item.settings.showCorrectAnswer = false; - await item.save(); - await syncQuizPollToFirebase(item); - return h.response(success(item, 'Closed')); + const result = await applyClose(item); + return h.response(success(result.item, result.message)); }; const setLiveQuestion = async (request, h) => { @@ -139,37 +113,9 @@ const setLiveQuestion = async (request, h) => { if (!item) return h.response(error('NOT_FOUND', 'Quiz/Poll not found')).code(404); const denied = await assertQuizPollAccess(request, h, item); if (denied) return denied; - if (displayModeOf(item) !== 'quiz_master') { - return h - .response(error('VALIDATION_ERROR', 'Per-question live control is only available in Quiz Master mode')) - .code(400); - } - - const rawQuestionId = request.payload?.questionId; - item.settings = item.settings || {}; - - if (rawQuestionId == null || String(rawQuestionId).trim() === '') { - item.settings.liveQuestionId = null; - item.settings.showCorrectAnswer = false; - await item.save(); - await syncQuizPollToFirebase(item); - return h.response(success(item, 'Live question cleared')); - } - - const question = findQuestionById(item, rawQuestionId); - if (!question) { - return h.response(error('NOT_FOUND', 'Question not found on this quiz')).code(404); - } - - const nextLiveId = questionIdString(question); - if (item.settings.liveQuestionId !== nextLiveId) { - item.settings.showCorrectAnswer = false; - } - item.settings.liveQuestionId = nextLiveId; - item.settings.isLive = true; - await item.save(); - await syncQuizPollToFirebase(item); - return h.response(success(item, 'Question is now live')); + const result = await applySetLiveQuestion(item, request.payload?.questionId); + if (!result.ok) return h.response(error(result.code, result.message)).code(result.status); + return h.response(success(result.item, result.message)); }; const setShowCorrect = async (request, h) => { diff --git a/src/controllers/websiteSettings.controller.js b/src/controllers/websiteSettings.controller.js index 9175c2a..ba185c4 100644 --- a/src/controllers/websiteSettings.controller.js +++ b/src/controllers/websiteSettings.controller.js @@ -72,6 +72,23 @@ const update = async (request, h) => { if (payload.layoutTemplate !== undefined) { event.website.layoutTemplate = 'conference'; } + if (payload.theme !== undefined) { + if (payload.theme == null) { + event.set('website.theme', undefined); + } else { + const t = payload.theme || {}; + const mode = String(t.theme || 'simple').trim().toLowerCase(); + const color = String(t.color || (mode === 'gradient' ? 'green' : 'blue')).trim().toLowerCase(); + const font = String(t.font || 'Open Sans').trim(); + event.set('website.theme', { + theme: mode === 'gradient' ? 'gradient' : 'simple', + color, + font, + }); + } + event.markModified('website'); + event.markModified('website.theme'); + } if (payload.micrositeSections !== undefined) { const ok = new Set(WEBSITE_SECTION_TYPES); event.website.micrositeSections = Array.isArray(payload.micrositeSections) @@ -79,7 +96,8 @@ const update = async (request, h) => { : []; } await event.save(); - return h.response(success(event.website)); + const website = event.toObject ? event.toObject().website : event.website; + return h.response(success(website || {})); }; const publishMicrosite = async (request, h) => { diff --git a/src/models/BadgeBatch.js b/src/models/BadgeBatch.js index a07f35c..3f2790e 100644 --- a/src/models/BadgeBatch.js +++ b/src/models/BadgeBatch.js @@ -49,8 +49,14 @@ const badgeConfigSchema = new mongoose.Schema( includeParticipants: { type: Boolean, default: false }, participantScope: { type: String, enum: ['all', 'participant_list'], default: 'all' }, participantListId: { type: mongoose.Schema.Types.ObjectId, ref: 'ParticipantList' }, - backgroundMode: { type: String, enum: ['image', 'color'], required: true }, + backgroundMode: { type: String, enum: ['image', 'color'], default: 'color' }, backgroundImageUrl: { type: String, default: '' }, + backgroundImageLayout: { + x: { type: Number, default: 0 }, + y: { type: Number, default: 0 }, + w: { type: Number, default: 100 }, + h: { type: Number, default: 100 }, + }, backgroundColor: { type: String, default: '#0B4DD1' }, fields: [{ type: String }], layout: [badgeLayoutElementSchema], diff --git a/src/models/DesignTemplate.js b/src/models/DesignTemplate.js index 7272883..bf3fe07 100644 --- a/src/models/DesignTemplate.js +++ b/src/models/DesignTemplate.js @@ -12,7 +12,9 @@ const designTemplateSchema = new mongoose.Schema( organization: { type: mongoose.Schema.Types.ObjectId, ref: 'Organization', - required: true, + required: function requiredOrg() { + return !this.isSystemTemplate; + }, }, name: { type: String, required: true }, type: { @@ -39,11 +41,28 @@ const designTemplateSchema = new mongoose.Schema( createdBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', - required: true, + required: function requiredCreator() { + return !this.isSystemTemplate; + }, + }, + /** Platform-wide emailer; visible to all orgs, not deletable by org users. */ + isSystemTemplate: { type: Boolean, default: false }, + /** Stable key for built-in templates (e.g. invite_for_event). */ + systemTemplateKey: { type: String, trim: true }, + /** Org copy forked from a system template. */ + derivedFromTemplate: { + type: mongoose.Schema.Types.ObjectId, + ref: 'DesignTemplate', + required: false, }, }, { timestamps: true } ); designTemplateSchema.index({ organization: 1, type: 1 }); +designTemplateSchema.index( + { systemTemplateKey: 1 }, + { unique: true, partialFilterExpression: { isSystemTemplate: true } }, +); +designTemplateSchema.index({ organization: 1, systemTemplateKey: 1 }); module.exports = mongoose.model('DesignTemplate', designTemplateSchema); diff --git a/src/models/Event.js b/src/models/Event.js index 20a3f17..e5f436d 100644 --- a/src/models/Event.js +++ b/src/models/Event.js @@ -91,6 +91,15 @@ const eventSchema = new mongoose.Schema( accentColor: String, /** Label from CreateMicrositePanel FONT_PAIRS, e.g. "Inter + Noto Sans" */ fontPair: String, + /** + * Luma-style website theme presets for the SPA microsite (`/event/:id`). + * theme: simple | gradient; color depends on theme; font is a single family name. + */ + theme: { + theme: { type: String, trim: true }, + color: { type: String, trim: true }, + font: { type: String, trim: true }, + }, /** Fallback for register_links CTAs when no registrationFormId / template */ registrationUrl: String, /** Registration Form _id; link built with MICROSITE_REGISTRATION_URL_TEMPLATE */ diff --git a/src/models/Form.js b/src/models/Form.js index 8a2414b..bc01895 100644 --- a/src/models/Form.js +++ b/src/models/Form.js @@ -22,6 +22,8 @@ const formFieldSchema = new mongoose.Schema({ mapsTo: String, customMapsKey: String, isFixed: { type: Boolean, default: false }, + /** Registration: submitted value(s) are added as participant tags. */ + convertToTag: { type: Boolean, default: false }, }); const formSchema = new mongoose.Schema( @@ -61,11 +63,38 @@ const formSchema = new mongoose.Schema( allowAnonymous: { type: Boolean, default: false }, paymentEnabled: { type: Boolean, default: false }, paymentAmount: String, - sendConfirmationEmail: { type: Boolean, default: true }, + /** Registration: send emailer template after successful submit. Default off. */ + sendConfirmationEmail: { type: Boolean, default: false }, + /** DesignTemplate (emailer) used when sendConfirmationEmail is true. */ + confirmationEmailTemplateId: { + type: mongoose.Schema.Types.ObjectId, + ref: 'DesignTemplate', + default: null, + }, /** Registration: tags applied to participant after each submission. */ onSubmitAddTags: { type: [String], default: [] }, /** Registration: fixed participant list to add submitter to. */ onSubmitParticipantListId: { type: mongoose.Schema.Types.ObjectId, ref: 'ParticipantList' }, + /** + * Registration: when false, reject if this email already has event membership + * (comparison is case-insensitive). + */ + allowDuplicateEmail: { type: Boolean, default: true }, + /** Registration: when false, reject if last-10 phone digits already registered + * for the event (ignores spaces, +, country code). + */ + allowDuplicatePhone: { type: Boolean, default: true }, + /** + * Configurable respondent-facing messages (empty → app falls back to defaults). + */ + formClosedMessage: String, + submitErrorMessage: String, + captchaFailedMessage: String, + registrationClosedMessage: String, + registrationDeadlineMessage: String, + registrationFullMessage: String, + duplicateEmailMessage: String, + duplicatePhoneMessage: String, /** Public form event header visibility (all default to shown). */ eventHeader: { showLogo: { type: Boolean, default: true }, diff --git a/src/models/Participant.js b/src/models/Participant.js index 258a752..c241f6f 100644 --- a/src/models/Participant.js +++ b/src/models/Participant.js @@ -9,14 +9,14 @@ const eventMembershipSchema = new mongoose.Schema( }, status: { type: String, - enum: ['pending', 'confirmed', 'checked_in', 'cancelled'], + enum: ['pending', 'confirmed', 'checked_in', 'cancelled', 'rejected'], default: 'pending', }, checkedIn: { type: Boolean, default: false }, checkedInAt: Date, guestToken: { type: String, trim: true }, registrationDate: { type: Date, default: Date.now }, - /** @deprecated Prefer root-level `Participant.tags`. Loaded for legacy rows only. */ + /** Event-scoped labels (registration / event UI). Shown on global person + this event only. */ tags: [String], }, { _id: false } @@ -52,20 +52,25 @@ const participantSchema = new mongoose.Schema( }, notes: String, emailVerified: { type: Boolean, default: false }, - /** Admin labels (VIP, Speaker, …) — organization-wide on the person, not per-event. */ + /** Org-global labels (VIP, …) — visible on every event list for this person. */ tags: { type: [String], default: [] }, eventMemberships: { type: [eventMembershipSchema], default: [] }, + /** Soft-delete timestamp; null = active. Lists exclude soft-deleted by default. */ + deletedAt: { type: Date, default: null }, }, { timestamps: true } ); participantSchema.index({ tenantOrganization: 1, status: 1 }); +participantSchema.index({ tenantOrganization: 1, deletedAt: 1 }); participantSchema.index( { tenantOrganization: 1, email: 1 }, { unique: true, + name: 'tenantOrganization_1_email_1_active', partialFilterExpression: { email: { $exists: true, $type: 'string', $gt: '' }, + deletedAt: null, }, } ); diff --git a/src/models/Session.js b/src/models/Session.js index c9381d4..adba4cf 100644 --- a/src/models/Session.js +++ b/src/models/Session.js @@ -56,6 +56,15 @@ const sessionSchema = new mongoose.Schema( audienceFeedbackForm: { type: mongoose.Schema.Types.ObjectId, ref: 'Form' }, /** Optional Form (type feedback) for custom ratings flow; null = default EventBuzz ratings UI */ audienceRatingsForm: { type: mongoose.Schema.Types.ObjectId, ref: 'Form' }, + /** Nested session topics (type, duration, title, role) for hierarchical programmes */ + topics: [ + { + type: { type: String, default: '' }, + duration: { type: String, default: '' }, + title: { type: String, default: '' }, + role: { type: String, default: '' }, + }, + ], }, { timestamps: true } ); diff --git a/src/routes/attendance.routes.js b/src/routes/attendance.routes.js index cfd140f..f59e523 100644 --- a/src/routes/attendance.routes.js +++ b/src/routes/attendance.routes.js @@ -1,5 +1,6 @@ const Joi = require('joi'); const controller = require('../controllers/attendance.controller'); +const { requirePermissionPre } = require('../services/acl.service'); const settingsSchema = Joi.object({ allowDuplicateCheckIn: Joi.boolean(), @@ -24,35 +25,71 @@ const checkInPayload = Joi.object({ }); module.exports = [ - { method: 'GET', path: '/api/events/{eventId}/attendances', options: { handler: controller.list } }, + { + method: 'GET', + path: '/api/events/{eventId}/attendances', + options: { pre: [{ method: requirePermissionPre('attendance', 'read') }], handler: controller.list }, + }, { method: 'POST', path: '/api/events/{eventId}/attendances', - options: { validate: { payload: createPayload }, handler: controller.create }, + options: { + validate: { payload: createPayload }, + pre: [{ method: requirePermissionPre('attendance', 'write') }], + handler: controller.create, + }, + }, + { + method: 'GET', + path: '/api/events/{eventId}/attendances/{id}', + options: { pre: [{ method: requirePermissionPre('attendance', 'read') }], handler: controller.get }, }, - { method: 'GET', path: '/api/events/{eventId}/attendances/{id}', options: { handler: controller.get } }, { method: 'PUT', path: '/api/events/{eventId}/attendances/{id}', - options: { validate: { payload: updatePayload }, handler: controller.update }, + options: { + validate: { payload: updatePayload }, + pre: [{ method: requirePermissionPre('attendance', 'write') }], + handler: controller.update, + }, + }, + { + method: 'DELETE', + path: '/api/events/{eventId}/attendances/{id}', + options: { pre: [{ method: requirePermissionPre('attendance', 'delete') }], handler: controller.remove }, }, - { method: 'DELETE', path: '/api/events/{eventId}/attendances/{id}', options: { handler: controller.remove } }, { method: 'POST', path: '/api/events/{eventId}/attendances/{id}/regenerate-token', - options: { handler: controller.regenerateToken }, + options: { pre: [{ method: requirePermissionPre('attendance', 'write') }], handler: controller.regenerateToken }, + }, + { + method: 'GET', + path: '/api/events/{eventId}/attendances/{id}/check-ins', + options: { pre: [{ method: requirePermissionPre('attendance', 'read') }], handler: controller.listCheckIns }, + }, + { + method: 'GET', + path: '/api/events/{eventId}/attendances/{id}/search-participants', + options: { pre: [{ method: requirePermissionPre('attendance', 'read') }], handler: controller.searchParticipants }, }, - { method: 'GET', path: '/api/events/{eventId}/attendances/{id}/check-ins', options: { handler: controller.listCheckIns } }, - { method: 'GET', path: '/api/events/{eventId}/attendances/{id}/search-participants', options: { handler: controller.searchParticipants } }, { method: 'GET', path: '/api/events/{eventId}/attendances/{id}/participants/{participantId}', - options: { handler: controller.getParticipantPreview }, + options: { pre: [{ method: requirePermissionPre('attendance', 'read') }], handler: controller.getParticipantPreview }, }, { method: 'POST', path: '/api/events/{eventId}/attendances/{id}/check-in', - options: { validate: { payload: checkInPayload }, handler: controller.checkIn }, + options: { + validate: { payload: checkInPayload }, + pre: [{ method: requirePermissionPre('attendance', 'write') }], + handler: controller.checkIn, + }, + }, + { + method: 'GET', + path: '/api/events/{eventId}/attendances/{id}/export', + options: { pre: [{ method: requirePermissionPre('attendance', 'read') }], handler: controller.exportCsv }, }, - { method: 'GET', path: '/api/events/{eventId}/attendances/{id}/export', options: { handler: controller.exportCsv } }, ]; diff --git a/src/routes/badgeBatch.routes.js b/src/routes/badgeBatch.routes.js index 1ec5e8d..031d9c3 100644 --- a/src/routes/badgeBatch.routes.js +++ b/src/routes/badgeBatch.routes.js @@ -36,8 +36,14 @@ const createPayload = Joi.object({ includeParticipants: Joi.boolean().default(false), participantScope: Joi.string().valid('all', 'participant_list').default('all'), participantListId: Joi.string().hex().length(24).allow(null, ''), - backgroundMode: Joi.string().valid('image', 'color').required(), + backgroundMode: Joi.string().valid('image', 'color').default('color'), backgroundImageUrl: Joi.string().allow(''), + backgroundImageLayout: Joi.object({ + x: Joi.number().min(-400).max(400).default(0), + y: Joi.number().min(-400).max(400).default(0), + w: Joi.number().min(10).max(500).default(100), + h: Joi.number().min(10).max(500).default(100), + }), backgroundColor: Joi.string().pattern(/^#[0-9A-Fa-f]{6}$/).default('#0B4DD1'), fields: Joi.array().items(Joi.string().valid(...FIELD_IDS)).default([]), layout: Joi.array().items(layoutElementSchema), diff --git a/src/routes/form.routes.js b/src/routes/form.routes.js index 34d8bf5..e29a251 100644 --- a/src/routes/form.routes.js +++ b/src/routes/form.routes.js @@ -19,6 +19,7 @@ const fieldSchema = Joi.object({ mapsTo: Joi.string().valid(...FORM_FIELD_MAPS_TO).allow('', null), customMapsKey: Joi.string().allow('', null), isFixed: Joi.boolean(), + convertToTag: Joi.boolean(), }).options({ stripUnknown: true }); const eventHeaderSchema = Joi.object({ @@ -42,8 +43,20 @@ const settingsSchema = Joi.object({ paymentEnabled: Joi.boolean(), paymentAmount: Joi.alternatives().try(Joi.string(), Joi.number()).allow('', null), sendConfirmationEmail: Joi.boolean(), + confirmationEmailTemplateId: Joi.string().hex().length(24).allow(null).empty(''), onSubmitAddTags: Joi.array().items(Joi.string()), - onSubmitParticipantListId: Joi.string().allow(null, ''), + /** Empty string must become null — mongoose ObjectId rejects "". */ + onSubmitParticipantListId: Joi.string().hex().length(24).allow(null).empty(''), + allowDuplicateEmail: Joi.boolean(), + allowDuplicatePhone: Joi.boolean(), + formClosedMessage: Joi.string().allow('', null), + submitErrorMessage: Joi.string().allow('', null), + captchaFailedMessage: Joi.string().allow('', null), + registrationClosedMessage: Joi.string().allow('', null), + registrationDeadlineMessage: Joi.string().allow('', null), + registrationFullMessage: Joi.string().allow('', null), + duplicateEmailMessage: Joi.string().allow('', null), + duplicatePhoneMessage: Joi.string().allow('', null), eventHeader: eventHeaderSchema, }).options({ stripUnknown: true }); diff --git a/src/routes/participant.routes.js b/src/routes/participant.routes.js index 738c221..45d3684 100644 --- a/src/routes/participant.routes.js +++ b/src/routes/participant.routes.js @@ -79,5 +79,8 @@ module.exports = [ { method: 'GET', path: '/api/participants/{id}', options: { handler: controller.get } }, { method: 'PUT', path: '/api/participants/{id}', options: { validate: { payload: participantUpdatePayload }, handler: controller.update } }, { method: 'DELETE', path: '/api/participants/{id}', options: { handler: controller.remove } }, + { method: 'POST', path: '/api/participants/{id}/restore', options: { handler: controller.restore } }, { method: 'POST', path: '/api/participants/{id}/check-in', options: { handler: controller.checkIn } }, + { method: 'POST', path: '/api/participants/{id}/confirm', options: { handler: controller.confirm } }, + { method: 'POST', path: '/api/participants/{id}/reject', options: { handler: controller.reject } }, ]; diff --git a/src/routes/publicQuizPoll.routes.js b/src/routes/publicQuizPoll.routes.js index 8f0392c..998d6c5 100644 --- a/src/routes/publicQuizPoll.routes.js +++ b/src/routes/publicQuizPoll.routes.js @@ -1,5 +1,10 @@ +const Joi = require('joi'); const controller = require('../controllers/publicQuizPoll.controller'); +const liveQuestionPayload = Joi.object({ + questionId: Joi.string().allow(null, ''), +}); + module.exports = [ { method: 'GET', @@ -11,4 +16,28 @@ module.exports = [ path: '/api/public/quiz-polls/present/{token}/questions/{questionIndex}/stats', options: { auth: false, handler: controller.getQuestionStats }, }, + { + method: 'GET', + path: '/api/public/quiz-polls/present/{token}/session-activities', + options: { auth: false, handler: controller.getSessionActivities }, + }, + { + method: 'POST', + path: '/api/public/quiz-polls/present/{token}/publish', + options: { auth: false, handler: controller.publishPresentation }, + }, + { + method: 'POST', + path: '/api/public/quiz-polls/present/{token}/close', + options: { auth: false, handler: controller.closePresentation }, + }, + { + method: 'POST', + path: '/api/public/quiz-polls/present/{token}/live-question', + options: { + auth: false, + validate: { payload: liveQuestionPayload }, + handler: controller.setPresentationLiveQuestion, + }, + }, ]; diff --git a/src/routes/session.routes.js b/src/routes/session.routes.js index 4e502a6..123ccc0 100644 --- a/src/routes/session.routes.js +++ b/src/routes/session.routes.js @@ -37,6 +37,14 @@ const sessionPayload = Joi.object({ audienceRatingsForm: Joi.string().hex().length(24).allow(null, ''), enableQnA: Joi.boolean(), enableQnP: Joi.boolean(), + topics: Joi.array().items( + Joi.object({ + type: Joi.string().allow('', null), + duration: Joi.string().allow('', null), + title: Joi.string().allow('', null), + role: Joi.string().allow('', null), + }), + ), }); module.exports = [ diff --git a/src/routes/websiteSettings.routes.js b/src/routes/websiteSettings.routes.js index 9e40ee5..e50cf30 100644 --- a/src/routes/websiteSettings.routes.js +++ b/src/routes/websiteSettings.routes.js @@ -24,6 +24,11 @@ const websiteSettingsPayload = Joi.object({ registrationUrl: Joi.string().max(2048).allow('', null), registrationFormId: optionalMongoId, micrositeHtml: Joi.string().allow('').max(2000000), + theme: Joi.object({ + theme: Joi.string().valid('simple', 'gradient').required(), + color: Joi.string().max(32).required(), + font: Joi.string().max(64).allow('', null), + }).allow(null), }); module.exports = [ diff --git a/src/services/acl.service.js b/src/services/acl.service.js index 4e8aea5..8ef0160 100644 --- a/src/services/acl.service.js +++ b/src/services/acl.service.js @@ -208,9 +208,8 @@ async function getFormGrantIds(userId, organizationId, action = 'read') { .select('resourceId actions') .lean(); - const implied = ACTION_IMPLIES[action] || [action]; return grants - .filter((g) => (g.actions || []).some((a) => implied.includes(a))) + .filter((g) => actionsInclude(g.actions || [], action)) .map((g) => g.resourceId); } diff --git a/src/services/acl.service.test.js b/src/services/acl.service.test.js index 7608c04..02b4cbf 100644 --- a/src/services/acl.service.test.js +++ b/src/services/acl.service.test.js @@ -32,6 +32,28 @@ describe('acl.service', () => { expect(canModuleFromResolved(resolved, 'participants', 'write')).toBe(false); }); + test('read-only module does not grant write', () => { + const resolved = { + isOrgSuperAdmin: false, + modules: { forms: ['read'] }, + scopes: {}, + }; + expect(canModuleFromResolved(resolved, 'forms', 'read')).toBe(true); + expect(canModuleFromResolved(resolved, 'forms', 'write')).toBe(false); + expect(canModuleFromResolved(resolved, 'forms', 'delete')).toBe(false); + }); + + test('delete implies write and read', () => { + const resolved = { + isOrgSuperAdmin: false, + modules: { forms: ['delete'] }, + scopes: {}, + }; + expect(canModuleFromResolved(resolved, 'forms', 'read')).toBe(true); + expect(canModuleFromResolved(resolved, 'forms', 'write')).toBe(true); + expect(canModuleFromResolved(resolved, 'forms', 'delete')).toBe(true); + }); + test('assertPermissionsSubset blocks escalation', () => { const caller = { isOrgSuperAdmin: false, @@ -48,6 +70,8 @@ describe('acl.service', () => { const modules = perms.map((p) => p.module); expect(modules).toContain('events'); expect(modules).toContain('forms'); + expect(modules).toContain('participants'); + expect(modules).toContain('attendance'); expect(modules).toContain('tracks'); expect(modules).toContain('sessions'); } diff --git a/src/services/eventAnalytics.service.js b/src/services/eventAnalytics.service.js index ab16afe..4042fae 100644 --- a/src/services/eventAnalytics.service.js +++ b/src/services/eventAnalytics.service.js @@ -172,11 +172,19 @@ async function buildPollSummaries(eid) { } async function buildParticipantBreakdown(participantBase, statusCounts) { + // Union root (org-global) tags with this event membership's tags — same as event list. const tagAgg = await Participant.aggregate([ ...participantBase, - { $match: { tags: { $exists: true, $ne: [] } } }, - { $unwind: '$tags' }, - { $group: { _id: '$tags', count: { $sum: 1 } } }, + { + $addFields: { + _displayTags: { + $setUnion: [{ $ifNull: ['$tags', []] }, { $ifNull: ['$eventMemberships.tags', []] }], + }, + }, + }, + { $match: { _displayTags: { $exists: true, $ne: [] } } }, + { $unwind: '$_displayTags' }, + { $group: { _id: '$_displayTags', count: { $sum: 1 } } }, { $sort: { count: -1 } }, { $limit: 12 }, ]); diff --git a/src/utils/badgeRender.js b/src/utils/badgeRender.js index d995241..fabb947 100644 --- a/src/utils/badgeRender.js +++ b/src/utils/badgeRender.js @@ -302,28 +302,47 @@ function imageUrlForLayoutElement(el, config) { } async function drawBadgeBackground(ctx, config, widthPx, heightPx) { - if (config.backgroundMode === 'image' && config.backgroundImageUrl) { - const buf = await fetchImageBuffer(config.backgroundImageUrl); - if (buf) { - try { - const img = await loadImage(buf); - const scale = Math.max(widthPx / img.width, heightPx / img.height); - const dw = img.width * scale; - const dh = img.height * scale; - const dx = (widthPx - dw) / 2; - const dy = (heightPx - dh) / 2; - ctx.drawImage(img, dx, dy, dw, dh); - return; - } catch { - /* fall through */ - } - } - ctx.fillStyle = '#f1f5f9'; - ctx.fillRect(0, 0, widthPx, heightPx); - return; - } ctx.fillStyle = config.backgroundColor || '#0B4DD1'; ctx.fillRect(0, 0, widthPx, heightPx); + + const url = String(config.backgroundImageUrl || '').trim(); + if (!url) return; + + const buf = await fetchImageBuffer(url); + if (!buf) return; + + try { + const img = await loadImage(buf); + const layout = config.backgroundImageLayout; + const hasLayout = + layout && + typeof layout === 'object' && + Number.isFinite(Number(layout.w)) && + Number.isFinite(Number(layout.h)); + + if (!hasLayout) { + const scale = Math.max(widthPx / img.width, heightPx / img.height); + const dw = img.width * scale; + const dh = img.height * scale; + const dx = (widthPx - dw) / 2; + const dy = (heightPx - dh) / 2; + ctx.drawImage(img, dx, dy, dw, dh); + return; + } + + const boxX = (Number(layout.x) / 100) * widthPx; + const boxY = (Number(layout.y) / 100) * heightPx; + const boxW = (Number(layout.w) / 100) * widthPx; + const boxH = (Number(layout.h) / 100) * heightPx; + const scale = Math.max(boxW / img.width, boxH / img.height); + const dw = img.width * scale; + const dh = img.height * scale; + const dx = boxX + (boxW - dw) / 2; + const dy = boxY + (boxH - dh) / 2; + ctx.drawImage(img, dx, dy, dw, dh); + } catch { + /* skip broken image */ + } } function textForLayoutElement(el, row, config, customMap) { diff --git a/src/utils/campaignMerge.js b/src/utils/campaignMerge.js index af57f55..21fe7a5 100644 --- a/src/utils/campaignMerge.js +++ b/src/utils/campaignMerge.js @@ -13,6 +13,10 @@ const PLACEHOLDER_HELP = { '{{event.endDate}}': 'Event end (localized string)', '{{event.venue}}': 'Location / venue', '{{event.virtualLink}}': 'Virtual link', + '{{event.logoUrl}}': 'Event or microsite logo URL', + '{{event.registrationUrl}}': 'Registration form URL', + '{{event.feedbackUrl}}': 'Feedback form URL', + '{{event.micrositeUrl}}': 'Published microsite URL', }; function formatDate(d) { diff --git a/src/utils/campaignRecipients.js b/src/utils/campaignRecipients.js index c423de9..77aadca 100644 --- a/src/utils/campaignRecipients.js +++ b/src/utils/campaignRecipients.js @@ -8,21 +8,47 @@ const { normalizeWhatsAppTo } = require('./phone'); const BATCH = 500; +const PARTICIPANT_STATUSES = new Set(['pending', 'confirmed', 'checked_in', 'cancelled', 'rejected']); + +/** + * @param {unknown} filters — Map or plain object from campaign.recipients.filters + * @returns {string|string[]|null} + */ +function readStatusFilter(filters) { + if (filters == null) return null; + let raw; + if (typeof filters.get === 'function') raw = filters.get('status'); + else if (typeof filters === 'object') raw = filters.status; + if (raw == null || raw === '') return null; + if (Array.isArray(raw)) { + const list = raw.map((s) => String(s)).filter((s) => PARTICIPANT_STATUSES.has(s)); + return list.length ? list : null; + } + const s = String(raw); + return PARTICIPANT_STATUSES.has(s) ? s : null; +} + /** * Participants registered for event with non-empty email. * @param {import('mongoose').Types.ObjectId} tenantOrganization * @param {import('mongoose').Types.ObjectId|string} eventId + * @param {{ status?: string|string[] }|Map|null} [filters] */ -async function resolveAllForEvent(tenantOrganization, eventId) { +async function resolveAllForEvent(tenantOrganization, eventId, filters) { const eid = new mongoose.Types.ObjectId(String(eventId)); const toid = tenantOrganization instanceof mongoose.Types.ObjectId ? tenantOrganization : new mongoose.Types.ObjectId(String(tenantOrganization)); + const statusFilter = readStatusFilter(filters); + const elemMatch = { event: eid }; + if (statusFilter) { + elemMatch.status = Array.isArray(statusFilter) ? { $in: statusFilter } : statusFilter; + } const match = { tenantOrganization: toid, email: { $exists: true, $nin: [null, ''] }, - eventMemberships: { $elemMatch: { event: eid } }, + eventMemberships: { $elemMatch: elemMatch }, }; const out = []; let skip = 0; @@ -127,6 +153,14 @@ async function resolveRecipientsForCampaign(campaign, tenantOrganization, allowe const rows = await resolveAllForEvent(tenantOrganization, eventId); return { rows }; } + if (type === 'filtered') { + const statusFilter = readStatusFilter(rec.filters); + if (!statusFilter) { + return { error: { code: 'VALIDATION_ERROR', message: 'Select a participant status for filtered recipients' } }; + } + const rows = await resolveAllForEvent(tenantOrganization, eventId, rec.filters); + return { rows }; + } if (type === 'custom' && Array.isArray(rec.customList) && rec.customList.length) { const ids = rec.customList.map((id) => String(id)); const rows = await resolveCustomList(ids, eventId, tenantOrganization); @@ -140,16 +174,21 @@ async function resolveRecipientsForCampaign(campaign, tenantOrganization, allowe // ─── WhatsApp: require normalized phone, dedupe by phone (digits) ─── -async function resolveAllForEventWhatsApp(tenantOrganization, eventId) { +async function resolveAllForEventWhatsApp(tenantOrganization, eventId, filters) { const eid = new mongoose.Types.ObjectId(String(eventId)); const toid = tenantOrganization instanceof mongoose.Types.ObjectId ? tenantOrganization : new mongoose.Types.ObjectId(String(tenantOrganization)); + const statusFilter = readStatusFilter(filters); + const elemMatch = { event: eid }; + if (statusFilter) { + elemMatch.status = Array.isArray(statusFilter) ? { $in: statusFilter } : statusFilter; + } const match = { tenantOrganization: toid, phone: { $exists: true, $nin: [null, ''] }, - eventMemberships: { $elemMatch: { event: eid } }, + eventMemberships: { $elemMatch: elemMatch }, }; const out = []; let skip = 0; @@ -244,6 +283,14 @@ async function resolveRecipientsForWhatsAppCampaign(campaign, tenantOrganization const rows = await resolveAllForEventWhatsApp(tenantOrganization, eventId); return { rows: dedupeWhatsappRows(rows) }; } + if (type === 'filtered') { + const statusFilter = readStatusFilter(rec.filters); + if (!statusFilter) { + return { error: { code: 'VALIDATION_ERROR', message: 'Select a participant status for filtered recipients' } }; + } + const rows = await resolveAllForEventWhatsApp(tenantOrganization, eventId, rec.filters); + return { rows: dedupeWhatsappRows(rows) }; + } if (type === 'custom' && Array.isArray(rec.customList) && rec.customList.length) { const ids = rec.customList.map((id) => String(id)); const rows = await resolveCustomListWhatsApp(ids, eventId, tenantOrganization); diff --git a/src/utils/emailerHtml.js b/src/utils/emailerHtml.js index be05f1a..18368c8 100644 --- a/src/utils/emailerHtml.js +++ b/src/utils/emailerHtml.js @@ -1,6 +1,7 @@ const Form = require('../models/Form'); const EventMicrosite = require('../models/EventMicrosite'); const { registrationUrlForForm } = require('./micrositeBuild'); +const { mergeText, buildVars } = require('./campaignMerge'); const FONT_STACK = { 'Inter + Noto Sans': "system-ui, -apple-system, 'Segoe UI', sans-serif", @@ -16,6 +17,28 @@ const LAYOUT_ACCENTS = { e4: '#D97706', }; +const SAMPLE_PREVIEW_VARS = { + contact: { + firstName: 'Jane', + lastName: 'Doe', + name: 'Jane Doe', + email: 'jane@example.com', + organization: 'Acme Inc.', + phone: '+91 98765 43210', + }, + event: { + name: 'Annual Summit 2026', + startDate: '15 Mar 2026, 9:00 am', + endDate: '17 Mar 2026, 6:00 pm', + venue: 'Grand Hall, Mumbai', + virtualLink: 'https://meet.example.com/room/abc', + logoUrl: '', + registrationUrl: 'https://web.eventbuzz.live/event/sample/form/register', + feedbackUrl: 'https://web.eventbuzz.live/event/sample/form/feedback', + micrositeUrl: 'https://web.eventbuzz.live/sample-event/', + }, +}; + function escapeHtml(s) { return String(s || '') .replace(/&/g, '&') @@ -28,87 +51,134 @@ function micrositePublicBase() { return (process.env.MICROSITE_PUBLIC_BASE_URL || 'https://web.eventbuzz.live').replace(/\/$/, ''); } +function eventLogoFromDoc(event, targets) { + const site = event?.website?.logo && String(event.website.logo).trim(); + if (site) return site; + return targets?.eventLogo && String(targets.eventLogo).trim() ? String(targets.eventLogo).trim() : ''; +} + +function resolveHeaderImageUrl(raw, event, targets) { + const s = String(raw || '').trim(); + if (!s) return ''; + if (/\{\{\s*event\.logoUrl\s*\}\}/i.test(s)) { + return eventLogoFromDoc(event, targets); + } + return s; +} + /** * @param {object} event — lean Event */ async function buildEmailerLinkTargets(event) { - const formsRaw = await Form.find({ event: event._id }).select('_id name').sort({ name: 1 }).lean(); + const formsRaw = await Form.find({ event: event._id }).select('_id name type').sort({ name: 1 }).lean(); const forms = formsRaw.map((f) => ({ id: String(f._id), + name: f.name || 'Form', + type: f.type || 'custom', href: registrationUrlForForm(event, event.website, f._id) || '', })); - const mss = await EventMicrosite.find({ event: event._id }).select('name publishFolder').sort({ name: 1 }).lean(); + const mss = await EventMicrosite.find({ event: event._id }).select('name publishFolder logo').sort({ name: 1 }).lean(); const microsites = mss .filter((m) => m.publishFolder && String(m.publishFolder).trim()) .map((m) => { const folder = String(m.publishFolder).trim().toLowerCase(); return { id: String(m._id), + name: m.name || folder || 'Microsite', href: `${micrositePublicBase()}/${folder}/`, }; }); - return { forms, microsites }; + const msLogo = mss.map((m) => m.logo).find((l) => l && String(l).trim()); + const registrationForm = forms.find((f) => f.type === 'registration'); + const feedbackForm = forms.find((f) => f.type === 'feedback'); + return { + forms, + microsites, + eventLogo: msLogo ? String(msLogo).trim() : '', + registrationForm, + feedbackForm, + }; } /** * @param {object} block — CTA block from emailer content.blocks - * @param {{ forms: { id: string, href: string }[], microsites: { id: string, href: string }[] }} targets + * @param {ReturnType extends Promise ? T : never} targets */ function resolveCtaHref(block, targets) { const linkKind = block.linkKind || 'custom'; if (linkKind === 'custom') return String(block.customUrl || '').trim() || '#'; if (linkKind === 'form') { - const f = targets.forms.find((x) => x.id === String(block.formId || '')); - return (f?.href && String(f.href).trim()) || '#'; + if (block.formId) { + const f = targets.forms.find((x) => x.id === String(block.formId || '')); + if (f?.href && String(f.href).trim()) return String(f.href).trim(); + } + const formType = String(block.formType || '').trim(); + if (formType) { + const f = targets.forms.find((x) => x.type === formType); + if (f?.href && String(f.href).trim()) return String(f.href).trim(); + } + if (targets.registrationForm?.href) return targets.registrationForm.href; + return '#'; } if (linkKind === 'microsite') { - const m = targets.microsites.find((x) => x.id === String(block.micrositeId || '')); - return (m?.href && String(m.href).trim()) || '#'; + if (block.micrositeId) { + const m = targets.microsites.find((x) => x.id === String(block.micrositeId || '')); + if (m?.href && String(m.href).trim()) return String(m.href).trim(); + } + const first = targets.microsites[0]; + return (first?.href && String(first.href).trim()) || '#'; } return '#'; } -/** - * Rebuild email HTML from stored block JSON so CTA hrefs reflect current event/form URLs at send time. - * @param {object} content — design template content object - * @param {object} event — lean Event - */ -async function buildEmailerHtmlFromContent(content, event) { - const blocks = Array.isArray(content?.blocks) ? content.blocks : []; - if (!blocks.length) return typeof content?.html === 'string' ? content.html : ''; +function enrichMergeVars(vars, targets) { + const out = { + contact: { ...vars.contact }, + event: { + ...vars.event, + logoUrl: vars.event.logoUrl || targets?.eventLogo || SAMPLE_PREVIEW_VARS.event.logoUrl, + registrationUrl: + vars.event.registrationUrl + || targets?.registrationForm?.href + || SAMPLE_PREVIEW_VARS.event.registrationUrl, + feedbackUrl: + vars.event.feedbackUrl || targets?.feedbackForm?.href || SAMPLE_PREVIEW_VARS.event.feedbackUrl, + micrositeUrl: + vars.event.micrositeUrl || targets?.microsites?.[0]?.href || SAMPLE_PREVIEW_VARS.event.micrositeUrl, + }, + }; + return out; +} - const targets = await buildEmailerLinkTargets(event); +function renderEmailerHtml(content, { targets, mergeVars, headerImgOverride }) { + const blocks = Array.isArray(content?.blocks) ? content.blocks : []; const layoutId = String(content.layoutTemplateId || content.templateId || 'e1'); const accent = String(content.primaryColor || '').trim() || LAYOUT_ACCENTS[layoutId] || '#0B4DD1'; const font = FONT_STACK[content.fontPair] || FONT_STACK['Inter + Noto Sans']; - const headerImg = String(content.headerImageUrl || '').trim(); - const footerText = String(content.footerText || '© EventBuzz'); - const previewText = String(content.previewText || '').trim(); + const headerImg = headerImgOverride != null + ? String(headerImgOverride).trim() + : String(content.headerImageUrl || '').trim(); + const footerText = mergeText(String(content.footerText || '© EventBuzz'), mergeVars); + const previewText = mergeText(String(content.previewText || '').trim(), mergeVars); const blocksHtml = blocks .map((blk) => { if (blk.type === 'text') { - const inner = typeof blk.html === 'string' && blk.html.trim() ? blk.html : ''; + const inner = typeof blk.html === 'string' && blk.html.trim() ? mergeText(blk.html, mergeVars) : ''; return `
${inner}
`; } if (blk.type === 'image' && blk.src && String(blk.src).trim()) { - return `

`; + const src = mergeText(String(blk.src).trim(), mergeVars); + if (!src) return ''; + return `

`; } if (blk.type === 'cta') { const rawUrl = resolveCtaHref(blk, targets); - if (!rawUrl || rawUrl === '#') { - console.warn('[emailerHtml] CTA has no URL', { - label: blk.label, - linkKind: blk.linkKind, - formId: blk.formId, - micrositeId: blk.micrositeId, - }); - } const url = escapeHtml(rawUrl); - const label = escapeHtml(blk.label || 'Register'); + const label = escapeHtml(mergeText(blk.label || 'Register', mergeVars)); return `

${label}

`; } - if (blk.type === 'divider') return `
`; + if (blk.type === 'divider') return '
'; return ''; }) .join('\n'); @@ -117,13 +187,17 @@ async function buildEmailerHtmlFromContent(content, event) { ? `
${escapeHtml(previewText)}
` : ''; + const headerRow = headerImg + ? `` + : ''; + return ` ${preHidden}
-${headerImg ? `` : ''} +${headerRow} @@ -136,8 +210,45 @@ ${previewText ? `

${escap `; } +/** + * Rebuild email HTML from stored block JSON so CTA hrefs reflect current event/form URLs at send time. + * @param {object} content — design template content object + * @param {object} event — lean Event + * @param {object|null} [participant] — lean Participant for {{contact.*}} merge + */ +async function buildEmailerHtmlFromContent(content, event, participant = null) { + const blocks = Array.isArray(content?.blocks) ? content.blocks : []; + if (!blocks.length) return typeof content?.html === 'string' ? content.html : ''; + + const targets = await buildEmailerLinkTargets(event); + const baseVars = buildVars(participant, event); + const mergeVars = enrichMergeVars(baseVars, targets); + mergeVars.event.logoUrl = eventLogoFromDoc(event, targets); + const headerImg = resolveHeaderImageUrl(content.headerImageUrl, event, targets); + return renderEmailerHtml(content, { targets, mergeVars, headerImgOverride: headerImg }); +} + +/** Static preview HTML with sample merge values (for template catalog / stored snapshot). */ +function buildStaticPreviewHtml(content) { + const targets = { + forms: [], + microsites: [{ id: 'sample', name: 'Event microsite', href: SAMPLE_PREVIEW_VARS.event.micrositeUrl }], + eventLogo: '', + registrationForm: { id: 'reg', href: SAMPLE_PREVIEW_VARS.event.registrationUrl, type: 'registration' }, + feedbackForm: { id: 'fb', href: SAMPLE_PREVIEW_VARS.event.feedbackUrl, type: 'feedback' }, + }; + const mergeVars = enrichMergeVars( + { contact: SAMPLE_PREVIEW_VARS.contact, event: { ...SAMPLE_PREVIEW_VARS.event, logoUrl: '' } }, + targets, + ); + return renderEmailerHtml(content, { targets, mergeVars, headerImgOverride: '' }); +} + module.exports = { + SAMPLE_PREVIEW_VARS, buildEmailerLinkTargets, buildEmailerHtmlFromContent, + buildStaticPreviewHtml, resolveCtaHref, + renderEmailerHtml, }; diff --git a/src/utils/ensureOrgRoles.js b/src/utils/ensureOrgRoles.js index c44660a..cbcb7f8 100644 --- a/src/utils/ensureOrgRoles.js +++ b/src/utils/ensureOrgRoles.js @@ -21,6 +21,10 @@ async function ensureSystemRolesForOrg(orgId) { isSystem: true, permissions: SYSTEM_ROLE_PERMISSIONS[systemKey] || [], }); + } else { + role.permissions = SYSTEM_ROLE_PERMISSIONS[systemKey] || []; + role.name = SYSTEM_ROLE_LABELS[systemKey] || systemKey; + await role.save(); } rolesByKey[systemKey] = role; } diff --git a/src/utils/ensureSystemEmailTemplates.js b/src/utils/ensureSystemEmailTemplates.js new file mode 100644 index 0000000..f6adc19 --- /dev/null +++ b/src/utils/ensureSystemEmailTemplates.js @@ -0,0 +1,47 @@ +const DesignTemplate = require('../models/DesignTemplate'); +const { SYSTEM_EMAIL_TEMPLATES, SYSTEM_CONTENT_VERSION } = require('../config/systemEmailTemplates'); + +async function ensureSystemEmailTemplates() { + let created = 0; + let updated = 0; + for (const def of SYSTEM_EMAIL_TEMPLATES) { + const existing = await DesignTemplate.findOne({ + isSystemTemplate: true, + systemTemplateKey: def.systemTemplateKey, + type: 'emailer', + }); + if (!existing) { + await DesignTemplate.create({ + name: def.name, + type: 'emailer', + category: def.category, + content: def.content, + isSystemTemplate: true, + systemTemplateKey: def.systemTemplateKey, + settings: { isPublic: true, isActive: true, canDuplicate: false }, + }); + created += 1; + continue; + } + let changed = false; + if (existing.name !== def.name) { + existing.name = def.name; + changed = true; + } + if (existing.category !== def.category) { + existing.category = def.category; + changed = true; + } + const currentVersion = Number(existing.content?.contentVersion || 0); + if (currentVersion < SYSTEM_CONTENT_VERSION) { + existing.content = def.content; + existing.markModified('content'); + changed = true; + } + if (changed) await existing.save(); + if (changed) updated += 1; + } + return { created, updated }; +} + +module.exports = { ensureSystemEmailTemplates }; diff --git a/src/utils/eventRatingsSummary.js b/src/utils/eventRatingsSummary.js index 9ec8286..cbcc08a 100644 --- a/src/utils/eventRatingsSummary.js +++ b/src/utils/eventRatingsSummary.js @@ -94,8 +94,89 @@ async function computeEventRatingsSummary(eventId) { }; } +function averageFromSubmissionScores(submissions, ratingLabels) { + if (!ratingLabels?.length) return { average: 0, count: 0 }; + const submissionAverages = []; + for (const sub of submissions) { + const data = submissionDataToObject(sub.data); + const scores = []; + for (const label of ratingLabels) { + const v = parseStarValue(data[label]); + if (v != null) scores.push(v); + } + if (scores.length) { + submissionAverages.push(scores.reduce((a, b) => a + b, 0) / scores.length); + } + } + if (!submissionAverages.length) return { average: 0, count: 0 }; + const average = submissionAverages.reduce((a, b) => a + b, 0) / submissionAverages.length; + return { + average: Math.round(average * 10) / 10, + count: submissionAverages.length, + }; +} + +/** + * Batch star-rating summaries for specific forms scoped to an event. + * @param {{ eventId: string, formId: string }[]} pairs + * @returns {Promise>} keyed by eventId + */ +async function computeFormRatingsSummariesBatch(pairs) { + const result = new Map(); + if (!pairs?.length) return result; + + const formIds = [ + ...new Set( + pairs + .map((p) => p.formId) + .filter((id) => id && mongoose.Types.ObjectId.isValid(String(id))), + ), + ].map((id) => new mongoose.Types.ObjectId(String(id))); + + if (!formIds.length) return result; + + const forms = await Form.find({ _id: { $in: formIds } }) + .select('_id fields') + .lean(); + + const labelsByFormId = new Map(); + for (const form of forms) { + const labels = (form.fields || []) + .filter(isStarRatingField) + .map((f) => String(f.label || '').trim()) + .filter(Boolean); + if (labels.length) labelsByFormId.set(String(form._id), labels); + } + + const validFormIds = [...labelsByFormId.keys()].map((id) => new mongoose.Types.ObjectId(id)); + if (!validFormIds.length) return result; + + const submissions = await FormSubmission.find({ form: { $in: validFormIds } }) + .select('form data event') + .lean(); + + for (const { eventId, formId } of pairs) { + const eid = String(eventId); + const fid = String(formId); + const labels = labelsByFormId.get(fid); + if (!labels?.length) { + result.set(eid, { average: 0, count: 0 }); + continue; + } + const scoped = submissions.filter( + (sub) => + String(sub.form) === fid && + (!sub.event || String(sub.event) === eid), + ); + result.set(eid, averageFromSubmissionScores(scoped, labels)); + } + + return result; +} + module.exports = { computeEventRatingsSummary, + computeFormRatingsSummariesBatch, isStarRatingField, parseStarValue, }; diff --git a/src/utils/formPublicHelpers.js b/src/utils/formPublicHelpers.js index 8b92844..19c394c 100644 --- a/src/utils/formPublicHelpers.js +++ b/src/utils/formPublicHelpers.js @@ -60,13 +60,32 @@ function normalizeEventHeaderDisplay(raw) { } /** Safe public form settings returned by unauthenticated form endpoints. */ +function settingMessage(formOrSettings, key, fallback) { + const s = formOrSettings?.settings || formOrSettings || {}; + const raw = s[key]; + if (typeof raw === 'string' && raw.trim()) return raw.trim(); + return fallback; +} + function buildPublicFormSettings(formSettings) { const s = formSettings || {}; + const msg = (key) => { + const v = s[key]; + return typeof v === 'string' && v.trim() ? v.trim() : undefined; + }; return { - thankYouMessage: s.thankYouMessage, + thankYouMessage: msg('thankYouMessage') || s.thankYouMessage, showThankYou: s.showThankYou !== false, collectEmail: !!s.collectEmail, allowAnonymous: !!s.allowAnonymous, + formClosedMessage: msg('formClosedMessage'), + submitErrorMessage: msg('submitErrorMessage'), + captchaFailedMessage: msg('captchaFailedMessage'), + registrationClosedMessage: msg('registrationClosedMessage'), + registrationDeadlineMessage: msg('registrationDeadlineMessage'), + registrationFullMessage: msg('registrationFullMessage'), + duplicateEmailMessage: msg('duplicateEmailMessage'), + duplicatePhoneMessage: msg('duplicatePhoneMessage'), eventHeader: normalizeEventHeaderDisplay(s.eventHeader), }; } @@ -104,4 +123,5 @@ module.exports = { buildPublicFormSettings, normalizeEventHeaderDisplay, resolveEventForPublicForm, + settingMessage, }; diff --git a/src/utils/handlebarsRender.js b/src/utils/handlebarsRender.js index 7d31b7a..6f523d8 100644 --- a/src/utils/handlebarsRender.js +++ b/src/utils/handlebarsRender.js @@ -34,6 +34,15 @@ function registerHelpers() { return p ? `${b}/${p}` : b; }); + Handlebars.registerHelper('assetVersionUrl', (base, path, version) => { + const b = String(base || '').replace(/\/+$/, ''); + const p = String(path || '').replace(/^\/+/, ''); + const url = p ? `${b}/${p}` : b; + if (version == null || version === '') return url; + const sep = url.includes('?') ? '&' : '?'; + return `${url}${sep}v=${encodeURIComponent(String(version))}`; + }); + Handlebars.registerHelper('resolveAsset', (base, path) => { const p = String(path || ''); if (!p) return ''; @@ -98,6 +107,7 @@ function buildRenderContext({ template, config, eventId, subdomain }) { eventId: eventId ? String(eventId) : '', subdomain: subdomain || '', templateSlug: template.slug || '', + templateVersion: template.version || template.schema?.version || 1, }; } diff --git a/src/utils/importNovelScheduleAgenda.js b/src/utils/importNovelScheduleAgenda.js new file mode 100644 index 0000000..f428eac --- /dev/null +++ b/src/utils/importNovelScheduleAgenda.js @@ -0,0 +1,109 @@ +const Session = require('../models/Session'); +const Track = require('../models/Track'); +const { eventBuzzCodeFor } = require('./eventBuzzCode'); +const { + parseSessionTimeRange, + mapTopicTypeToSessionType, + topicsToDescription, +} = require('./parseNovelScheduleCsv'); + +const DAY_DATE_KEYS = ['2026-08-07', '2026-08-08']; +const DEFAULT_TRACK_NAME = 'Main programme'; + +/** + * Resolve the default agenda track for imported sessions. + * Prefers an existing "Main programme" track; otherwise first track; creates one if none exist. + * + * @param {string} eventId + * @returns {Promise} + */ +async function resolveDefaultTrackId(eventId) { + const main = await Track.findOne({ + event: eventId, + name: { $regex: /^Main programme$/i }, + }) + .sort({ sortOrder: 1 }) + .select('_id name') + .lean(); + if (main) return main._id; + + const first = await Track.findOne({ event: eventId }).sort({ sortOrder: 1, name: 1 }).select('_id').lean(); + if (first) return first._id; + + const created = await Track.create({ + event: eventId, + name: DEFAULT_TRACK_NAME, + sortOrder: 0, + }); + return created._id; +} + +/** insertMany skips Mongoose save hooks; assign joinCode so agenda QR buttons work. */ +async function assignJoinCodes(sessionDocs) { + await Promise.all( + sessionDocs.map(async (doc) => { + const id = doc._id?.toString(); + if (!id) return; + const joinCode = eventBuzzCodeFor(id, 'session'); + if (doc.joinCode === joinCode) return; + doc.joinCode = joinCode; + await Session.updateOne({ _id: doc._id }, { $set: { joinCode } }); + }), + ); +} + +/** + * Replace event agenda sessions from parsed NOVEL schedule days. + * + * @param {string} eventId + * @param {Array<{ label: string, date: string, sessions: object[] }>} days + * @returns {Promise<{ deleted: number, created: number, trackId: string }>} + */ +async function importNovelScheduleToAgenda(eventId, days) { + const trackId = await resolveDefaultTrackId(eventId); + const deletedResult = await Session.deleteMany({ event: eventId }); + + const payloads = []; + (days || []).forEach((day, dayIndex) => { + const dateKey = DAY_DATE_KEYS[dayIndex] || DAY_DATE_KEYS[0]; + (day.sessions || []).forEach((session) => { + const range = parseSessionTimeRange(session.time, dateKey, dayIndex); + if (!range) return; + + const topics = (session.topics || []).map((tp) => ({ + type: tp.type || '', + duration: tp.duration || '', + title: tp.title || '', + role: tp.role || '', + })); + const firstType = topics.find((t) => t.type)?.type || ''; + + payloads.push({ + event: eventId, + track: trackId, + title: session.name || session.time || 'Session', + type: mapTopicTypeToSessionType(firstType), + startTime: range.startTime, + endTime: range.endTime, + topics, + description: topicsToDescription(topics), + status: 'scheduled', + }); + }); + }); + + let createdCount = 0; + if (payloads.length) { + const created = await Session.insertMany(payloads); + await assignJoinCodes(created); + createdCount = created.length; + } + + return { + deleted: deletedResult.deletedCount || 0, + created: createdCount, + trackId: String(trackId), + }; +} + +module.exports = { importNovelScheduleToAgenda, resolveDefaultTrackId, DEFAULT_TRACK_NAME }; diff --git a/src/utils/mail.js b/src/utils/mail.js index 975ac59..7e2351f 100644 --- a/src/utils/mail.js +++ b/src/utils/mail.js @@ -70,6 +70,33 @@ function orgFromAddress(org) { return getMailFrom(); } +/** + * Build nodemailer transport options for org SMTP. + * Port 465 = implicit TLS (secure:true). Port 587/25/2525 = plain then STARTTLS (secure:false). + * Mismatching these causes: tls_validate_record_header:wrong version number. + * @param {{ host?: string, port?: number, secure?: boolean, user?: string, passwordEnc?: string }} s + */ +function buildOrgSmtpTransportOptions(s) { + const port = Number(s.port) || 587; + let secure = Boolean(s.secure); + if (port === 465) secure = true; + else if (port === 587 || port === 25 || port === 2525) secure = false; + + const pass = s.passwordEnc ? decrypt(s.passwordEnc) : ''; + /** @type {import('nodemailer').TransportOptions} */ + const opts = { + host: s.host, + port, + secure, + auth: s.user ? { user: s.user, pass: pass || '' } : undefined, + }; + // Submission ports advertise STARTTLS; require it so mail is not sent in cleartext. + if (!secure && (port === 587 || port === 25 || port === 2525)) { + opts.requireTLS = true; + } + return opts; +} + /** * @param {import('mongoose').Types.ObjectId|string} orgId * @returns {Promise} @@ -86,14 +113,7 @@ async function getTransporterForOrganization(orgId) { orgTransportCache.set(key, d); return d; } - const port = s.port || 587; - const pass = s.passwordEnc ? decrypt(s.passwordEnc) : ''; - const t = nodemailer.createTransport({ - host: s.host, - port, - secure: Boolean(s.secure), - auth: s.user ? { user: s.user, pass: pass || '' } : undefined, - }); + const t = nodemailer.createTransport(buildOrgSmtpTransportOptions(s)); orgTransportCache.set(key, t); return t; } @@ -346,6 +366,7 @@ module.exports = { getDefaultTransporter, getTransporter, getTransporterForOrganization, + buildOrgSmtpTransportOptions, orgFromAddress, sendOrgMail, clearOrgTransportCache, diff --git a/src/utils/parseNovelScheduleCsv.js b/src/utils/parseNovelScheduleCsv.js new file mode 100644 index 0000000..20dd62d --- /dev/null +++ b/src/utils/parseNovelScheduleCsv.js @@ -0,0 +1,286 @@ +/** + * Parse NOVEL summit schedule CSV into days → sessions → topics. + * + * Column mapping: + * Theme Time → session.time + * Theme Name → session.name + * Mode → topic.type + * Topic Time → topic.duration + * Title → topic.title + * Role → topic.role + */ + +function trim(val) { + return String(val == null ? '' : val).trim(); +} + +function parseCsvLine(line) { + const cells = []; + let cur = ''; + let inQuotes = false; + for (let i = 0; i < line.length; i++) { + const ch = line[i]; + if (ch === '"') { + if (inQuotes && line[i + 1] === '"') { + cur += '"'; + i++; + } else { + inQuotes = !inQuotes; + } + } else if (ch === ',' && !inQuotes) { + cells.push(cur); + cur = ''; + } else { + cur += ch; + } + } + cells.push(cur); + return cells.map(trim); +} + +function isDayRow(themeTime, themeName) { + const t = trim(themeTime); + return /^Day\s+\d+$/i.test(t) && !trim(themeName); +} + +function dayLabelFromRow(themeTime) { + const m = trim(themeTime).match(/^Day\s+(\d+)$/i); + if (!m) return ''; + return `Day ${String(parseInt(m[1], 10)).padStart(2, '0')}`; +} + +function hasTopicData(mode, topicTime, title, role) { + return !!(trim(mode) || trim(topicTime) || trim(title) || trim(role)); +} + +function inferScheduleAmPm(hour, dayIndex) { + if (dayIndex === 0 && hour >= 1 && hour <= 6) return 'PM'; + if (dayIndex >= 1) { + if (hour >= 9 && hour <= 11) return 'AM'; + if (hour === 12) return 'PM'; + } + if (hour >= 1 && hour <= 6) return 'PM'; + if (hour >= 7 && hour <= 11) return 'AM'; + if (hour === 12) return 'PM'; + return 'AM'; +} + +function formatClockPart(part, dayIndex) { + const trimmed = trim(part); + const match = trimmed.match(/^(\d{1,2})\s*:\s*(\d{2})\s*(am|pm|a\.m|p\.m)?\.?$/i); + if (!match) return trimmed; + + const hour = parseInt(match[1], 10); + const minute = parseInt(match[2], 10); + const explicit = match[3] ? match[3].replace(/\./g, '').toLowerCase() : ''; + const suffix = explicit === 'am' || explicit === 'pm' + ? explicit.toUpperCase() + : inferScheduleAmPm(hour, dayIndex); + const hour12 = suffix === 'AM' + ? (hour === 12 ? 12 : hour) + : (hour >= 1 && hour <= 6 ? hour : (hour === 12 ? 12 : (hour > 12 ? hour - 12 : hour))); + + return `${hour12}:${String(minute).padStart(2, '0')} ${suffix}`; +} + +/** + * Format a session time range for display with AM/PM. + * Day 1 (index 0): bare hours 1–6 → PM. Day 2+: 9–11 → AM, 12 → PM. + */ +function formatScheduleTimeDisplay(timeStr, dayIndex = 0) { + const raw = trim(timeStr); + if (!raw) return ''; + if (/\b(am|pm|a\.m|p\.m)\b/i.test(raw)) return raw; + + const separator = /\s+to\s+/i.test(raw) ? ' to ' : ' - '; + const parts = raw.split(/\s+to\s+|\s*-\s*/i).map(trim).filter(Boolean); + if (parts.length < 2) return raw; + + return formatClockPart(parts[0], dayIndex) + separator + formatClockPart(parts[1], dayIndex); +} + +function hasNewSession(themeTime, themeName) { + return !!(trim(themeTime) || trim(themeName)) && !isDayRow(themeTime, themeName); +} + +/** + * @param {string} text Raw CSV file contents + * @param {{ dayDates?: string[] }} [opts] Optional date labels per day index + * @returns {{ days: Array<{ label: string, date: string, sessions: object[] }> }} + */ +function parseNovelScheduleCsv(text, opts = {}) { + const defaultDates = opts.dayDates || ['August 7, 2026', 'August 8, 2026']; + const lines = String(text || '') + .replace(/^\uFEFF/, '') + .split(/\r?\n/) + .filter((l) => l.trim()); + + if (lines.length < 2) { + return { days: [] }; + } + + const days = []; + let currentDay = null; + let currentDayIndex = 0; + let currentSession = null; + let topicCtx = { type: '', duration: '', title: '' }; + + const ensureDay = (label) => { + let day = days.find((d) => d.label === label); + if (!day) { + const idx = days.length; + day = { + label, + date: defaultDates[idx] || '', + sessions: [], + }; + days.push(day); + } + currentDay = day; + currentDayIndex = days.indexOf(day); + return day; + }; + + const startSession = (time, name) => { + if (!currentDay) { + ensureDay('Day 01'); + } + const rawTime = trim(time); + currentSession = { + time: rawTime ? formatScheduleTimeDisplay(rawTime, currentDayIndex) : '', + name: trim(name), + topics: [], + }; + currentDay.sessions.push(currentSession); + topicCtx = { type: '', duration: '', title: '' }; + }; + + const appendTopic = (mode, topicTime, title, role) => { + if (!currentSession) return; + + const modeVal = trim(mode); + const timeVal = trim(topicTime); + const titleVal = trim(title); + const roleVal = trim(role); + + const startsNewTopic = !!(modeVal || timeVal || titleVal); + const isRoleOnly = !startsNewTopic && !!roleVal; + + if (isRoleOnly && currentSession.topics.length) { + const last = currentSession.topics[currentSession.topics.length - 1]; + last.role = last.role ? `${last.role}, ${roleVal}` : roleVal; + return; + } + + if (!startsNewTopic && !roleVal) return; + + if (modeVal) topicCtx.type = modeVal; + if (timeVal) topicCtx.duration = timeVal; + if (titleVal) topicCtx.title = titleVal; + + currentSession.topics.push({ + type: topicCtx.type || modeVal, + duration: topicCtx.duration || timeVal, + title: topicCtx.title || titleVal, + role: roleVal, + }); + }; + + for (let i = 1; i < lines.length; i++) { + const cells = parseCsvLine(lines[i]); + while (cells.length < 6) cells.push(''); + + const [themeTime, themeName, mode, topicTime, title, role] = cells; + + if (isDayRow(themeTime, themeName)) { + ensureDay(dayLabelFromRow(themeTime)); + currentSession = null; + topicCtx = { type: '', duration: '', title: '' }; + continue; + } + + if (hasNewSession(themeTime, themeName)) { + if (!currentDay) ensureDay('Day 01'); + startSession(themeTime, themeName); + } + + if (hasTopicData(mode, topicTime, title, role)) { + if (!currentSession) { + startSession('', ''); + } + appendTopic(mode, topicTime, title, role); + } + } + + return { days }; +} + +/** + * Parse a session time range string against a calendar day (YYYY-MM-DD). + * Day 1 (index 0): hours 1–6 without am/pm → PM. Day 2+: 9–11 → AM, 12 → noon. + * + * @returns {{ startTime: Date, endTime: Date } | null} + */ +function parseSessionTimeRange(timeStr, dateKey, dayIndex = 0) { + const raw = trim(timeStr); + if (!raw) return null; + + const parts = raw.split(/\s+to\s+|\s*-\s*/i).map(trim).filter(Boolean); + if (parts.length < 2) return null; + + const parseClock = (part) => { + const m = part.match(/(\d{1,2})\s*:\s*(\d{2})/); + if (!m) return null; + let h = parseInt(m[1], 10); + const min = parseInt(m[2], 10); + const lower = part.toLowerCase(); + if (lower.includes('pm') || lower.includes('p.m')) { + if (h < 12) h += 12; + } else if (lower.includes('am') || lower.includes('a.m')) { + if (h === 12) h = 0; + } else if (dayIndex === 0 && h >= 1 && h <= 6) { + h += 12; + } + return { h, min }; + }; + + const startClock = parseClock(parts[0]); + const endClock = parseClock(parts[1]); + if (!startClock || !endClock) return null; + + const [y, mo, d] = dateKey.split('-').map((n) => parseInt(n, 10)); + const startTime = new Date(y, mo - 1, d, startClock.h, startClock.min, 0, 0); + const endTime = new Date(y, mo - 1, d, endClock.h, endClock.min, 0, 0); + if (endTime <= startTime) return null; + return { startTime, endTime }; +} + +/** Map first topic type to Session.type enum value. */ +function mapTopicTypeToSessionType(topicType) { + const t = trim(topicType).toLowerCase(); + if (!t) return 'panel'; + if (t.includes('keynote')) return 'keynote'; + if (t.includes('workshop') || t.includes('talk') || t.includes('lecture')) return 'workshop'; + if (t.includes('panel') || t.includes('discussion') || t.includes('intro')) return 'panel'; + if (t.includes('break') || t.includes('network')) return 'networking'; + if (t.includes('case')) return 'breakout'; + return 'panel'; +} + +function topicsToDescription(topics) { + if (!Array.isArray(topics) || !topics.length) return ''; + return topics + .map((tp) => { + const bits = [tp.type, tp.duration ? `${tp.duration} min` : '', tp.title, tp.role].filter(Boolean); + return bits.join(' · '); + }) + .join('\n'); +} + +module.exports = { + parseNovelScheduleCsv, + parseSessionTimeRange, + formatScheduleTimeDisplay, + mapTopicTypeToSessionType, + topicsToDescription, +}; diff --git a/src/utils/participantMembership.js b/src/utils/participantMembership.js index 5308150..047543d 100644 --- a/src/utils/participantMembership.js +++ b/src/utils/participantMembership.js @@ -14,8 +14,90 @@ function participantInEvent(participant, eventId) { return Boolean(getMembership(participant, eventId)); } +function normalizeTagList(tags) { + return [...new Set((tags || []).map((t) => String(t).trim()).filter(Boolean))]; +} + +/** + * Merge tags onto the event membership only (does not touch root Participant.tags). + * Requires an existing membership for eventId; returns false if missing. + * @returns {boolean} whether membership was found and updated + */ +function addMembershipTags(participant, eventId, tags) { + const m = getMembership(participant, eventId); + if (!m) return false; + const add = normalizeTagList(tags); + if (!add.length) return true; + m.tags = [...new Set([...(Array.isArray(m.tags) ? m.tags.map(String) : []), ...add])]; + if (typeof participant.markModified === 'function') { + participant.markModified('eventMemberships'); + } + return true; +} + +/** + * Remove tags from the event membership only (does not touch root Participant.tags). + * @returns {boolean} whether membership was found + */ +function removeMembershipTags(participant, eventId, tags) { + const m = getMembership(participant, eventId); + if (!m) return false; + const removeSet = new Set(normalizeTagList(tags)); + if (!removeSet.size) return true; + m.tags = (Array.isArray(m.tags) ? m.tags : []).map(String).filter((t) => !removeSet.has(t)); + if (typeof participant.markModified === 'function') { + participant.markModified('eventMemberships'); + } + return true; +} + +/** + * Remove tags from org-global root and every event membership (global Participants UI). + * @returns {boolean} whether any tag was removed + */ +function removeTagsEverywhere(participant, tags) { + const removeSet = new Set(normalizeTagList(tags)); + if (!removeSet.size) return false; + let changed = false; + const root = Array.isArray(participant.tags) ? participant.tags.map(String) : []; + const nextRoot = root.filter((t) => !removeSet.has(t)); + if (nextRoot.length !== root.length) { + participant.tags = nextRoot; + changed = true; + } + if (Array.isArray(participant.eventMemberships)) { + for (const m of participant.eventMemberships) { + const memTags = Array.isArray(m.tags) ? m.tags.map(String) : []; + const nextMem = memTags.filter((t) => !removeSet.has(t)); + if (nextMem.length !== memTags.length) { + m.tags = nextMem; + changed = true; + } + } + if (changed && typeof participant.markModified === 'function') { + participant.markModified('eventMemberships'); + } + } + return changed; +} + +/** + * Replace membership tags for an event (event-scoped update). + * @returns {boolean} whether membership was found + */ +function setMembershipTags(participant, eventId, tags) { + const m = getMembership(participant, eventId); + if (!m) return false; + m.tags = normalizeTagList(tags); + if (typeof participant.markModified === 'function') { + participant.markModified('eventMemberships'); + } + return true; +} + /** * API shape expected by dashboards / eventbuzz (single-event slice). + * Tags = org-global root tags ∪ this event's membership tags. * @param {object} participant lean * @param {string|import('mongoose').Types.ObjectId} eventId */ @@ -26,8 +108,8 @@ function flattenParticipantForEvent(participant, eventId) { const p = { ...participant }; delete p.eventMemberships; const rootTags = Array.isArray(participant.tags) ? participant.tags : []; - const legacyMembershipTags = Array.isArray(m.tags) ? m.tags : []; - const tags = [...new Set([...rootTags, ...legacyMembershipTags])]; + const membershipTags = Array.isArray(m.tags) ? m.tags : []; + const tags = [...new Set([...rootTags, ...membershipTags].map(String).filter(Boolean))]; return { ...p, event: String(eventId), @@ -65,6 +147,7 @@ function membershipEmailQuery(tenantOrgId, eventId, email) { return { tenantOrganization: tenantOrgId, email: em, + deletedAt: null, eventMemberships: { $elemMatch: { event: new mongoose.Types.ObjectId(String(eventId)) } }, }; } @@ -73,6 +156,7 @@ function membershipGuestQuery(tenantOrgId, eventId, guestToken) { const gt = String(guestToken || '').trim(); return { tenantOrganization: tenantOrgId, + deletedAt: null, eventMemberships: { $elemMatch: { event: new mongoose.Types.ObjectId(String(eventId)), @@ -91,6 +175,11 @@ function baseQueryForEvent(eventId) { module.exports = { getMembership, participantInEvent, + normalizeTagList, + addMembershipTags, + removeMembershipTags, + removeTagsEverywhere, + setMembershipTags, flattenParticipantForEvent, flattenParticipantForCampaignList, membershipEmailQuery, diff --git a/src/utils/phone.js b/src/utils/phone.js index 1ba32b8..d6f4776 100644 --- a/src/utils/phone.js +++ b/src/utils/phone.js @@ -22,4 +22,17 @@ function normalizeWhatsAppTo(raw) { return digits; } -module.exports = { normalizeWhatsAppTo }; +/** + * Last 10 digits of a phone for duplicate registration matching. + * Strips all non-digits, then takes the trailing 10 (so +91 / leading 0 are ignored). + * @param {string} raw + * @returns {string} up to 10 digits, or empty string + */ +function phoneLast10Digits(raw) { + const digits = String(raw || '').replace(/\D/g, ''); + if (!digits) return ''; + if (digits.length <= 10) return digits; + return digits.slice(-10); +} + +module.exports = { normalizeWhatsAppTo, phoneLast10Digits }; diff --git a/src/utils/quizPollLiveControls.js b/src/utils/quizPollLiveControls.js new file mode 100644 index 0000000..5c868b1 --- /dev/null +++ b/src/utils/quizPollLiveControls.js @@ -0,0 +1,136 @@ +const QuizPoll = require('../models/QuizPoll'); +const { syncQuizPollToFirebase } = require('./quizPollFirebaseSync'); + +const MANUAL_OR_QUIZ_MASTER = new Set(['manual', 'quiz_master']); + +function displayModeOf(item) { + return String(item?.settings?.displayMode || '').trim(); +} + +function questionIdString(q) { + if (!q || q._id == null) return ''; + return String(q._id); +} + +function findQuestionById(item, questionId) { + if (!questionId) return null; + const target = String(questionId).trim(); + return (item.questions || []).find((q) => questionIdString(q) === target) || null; +} + +/** + * When one manual / quiz_master activity goes live, take siblings on the same session offline. + * Leaves always_live / always_sched unchanged. + * @param {import('mongoose').Document} item + */ +async function offlineSiblingManualAndQuizMaster(item) { + if (!item?.session || !item._id) return; + + const siblings = await QuizPoll.find({ + session: item.session, + _id: { $ne: item._id }, + deletedAt: null, + 'settings.displayMode': { $in: ['manual', 'quiz_master'] }, + }); + + for (const sib of siblings) { + const mode = displayModeOf(sib); + if (!MANUAL_OR_QUIZ_MASTER.has(mode)) continue; + const s = sib.settings || {}; + const isLive = Boolean(s.isLive); + const hasLiveQ = + s.liveQuestionId != null && String(s.liveQuestionId).trim() !== ''; + if (!isLive && !hasLiveQ) continue; + await applyClose(sib); + } +} + +/** + * @param {import('mongoose').Document} item + * @returns {Promise<{ ok: true, item: object, message: string } | { ok: false, code: string, message: string, status: number }>} + */ +async function applyPublish(item) { + if (displayModeOf(item) === 'quiz_master') { + return { + ok: false, + code: 'VALIDATION_ERROR', + message: + 'Quiz Master mode uses per-question live control. Use live-question instead.', + status: 400, + }; + } + item.settings = item.settings || {}; + item.settings.isLive = true; + await item.save(); + await syncQuizPollToFirebase(item); + await offlineSiblingManualAndQuizMaster(item); + return { ok: true, item, message: 'Published' }; +} + +/** + * @param {import('mongoose').Document} item + */ +async function applyClose(item) { + item.settings = item.settings || {}; + item.settings.isLive = false; + item.settings.liveQuestionId = null; + item.settings.showCorrectAnswer = false; + await item.save(); + await syncQuizPollToFirebase(item); + return { ok: true, item, message: 'Closed' }; +} + +/** + * @param {import('mongoose').Document} item + * @param {unknown} rawQuestionId + */ +async function applySetLiveQuestion(item, rawQuestionId) { + if (displayModeOf(item) !== 'quiz_master') { + return { + ok: false, + code: 'VALIDATION_ERROR', + message: 'Per-question live control is only available in Quiz Master mode', + status: 400, + }; + } + + item.settings = item.settings || {}; + + if (rawQuestionId == null || String(rawQuestionId).trim() === '') { + item.settings.liveQuestionId = null; + item.settings.showCorrectAnswer = false; + await item.save(); + await syncQuizPollToFirebase(item); + return { ok: true, item, message: 'Live question cleared' }; + } + + const question = findQuestionById(item, rawQuestionId); + if (!question) { + return { + ok: false, + code: 'NOT_FOUND', + message: 'Question not found on this quiz', + status: 404, + }; + } + + const nextLiveId = questionIdString(question); + if (item.settings.liveQuestionId !== nextLiveId) { + item.settings.showCorrectAnswer = false; + } + item.settings.liveQuestionId = nextLiveId; + item.settings.isLive = true; + await item.save(); + await syncQuizPollToFirebase(item); + await offlineSiblingManualAndQuizMaster(item); + return { ok: true, item, message: 'Question is now live' }; +} + +module.exports = { + displayModeOf, + questionIdString, + findQuestionById, + applyPublish, + applyClose, + applySetLiveQuestion, +}; diff --git a/src/utils/registrationConfirmationMail.js b/src/utils/registrationConfirmationMail.js new file mode 100644 index 0000000..e59697e --- /dev/null +++ b/src/utils/registrationConfirmationMail.js @@ -0,0 +1,91 @@ +const DesignTemplate = require('../models/DesignTemplate'); +const Event = require('../models/Event'); +const Participant = require('../models/Participant'); +const { buildEmailerHtmlFromContent } = require('./emailerHtml'); +const { mergeCampaignContent } = require('./campaignMerge'); +const { sendOrgMail } = require('./mail'); + +/** + * Send registration confirmation emailer when form settings request it. + * Failures are logged only — never block the public form response. + * + * @param {{ form: object, participantId: string|import('mongoose').Types.ObjectId, eventId?: string|null }} opts + */ +async function sendRegistrationConfirmationEmail({ form, participantId, eventId }) { + if (!form || form.type !== 'registration') return { skipped: true, reason: 'not_registration' }; + if (!form.settings?.sendConfirmationEmail) return { skipped: true, reason: 'disabled' }; + + const tplId = form.settings?.confirmationEmailTemplateId; + if (!tplId) { + console.warn('[registrationConfirmation] sendConfirmationEmail=true but no confirmationEmailTemplateId'); + return { skipped: true, reason: 'no_template' }; + } + if (!participantId) return { skipped: true, reason: 'no_participant' }; + + const participant = await Participant.findById(participantId).lean(); + const to = String(participant?.email || '').trim().toLowerCase(); + if (!to) { + console.warn('[registrationConfirmation] participant has no email', participantId); + return { skipped: true, reason: 'no_email' }; + } + + const orgId = form.tenantOrganization; + const tpl = await DesignTemplate.findById(tplId).lean(); + if (!tpl) { + console.warn('[registrationConfirmation] template not found', tplId); + return { skipped: true, reason: 'template_missing' }; + } + + const isSystem = tpl.isSystemTemplate === true; + const orgOk = orgId && tpl.organization && String(tpl.organization) === String(orgId); + if (!isSystem && !orgOk) { + console.warn('[registrationConfirmation] template not allowed for org', String(tplId), String(orgId)); + return { skipped: true, reason: 'template_forbidden' }; + } + + const event = eventId ? await Event.findById(eventId).lean() : null; + const content = tpl.content; + let subjectTpl = ''; + let bodyTpl = ''; + + if (content && typeof content === 'object') { + subjectTpl = String(content.subjectLine || content.subject || '').trim(); + if (Array.isArray(content.blocks) && content.blocks.length) { + bodyTpl = await buildEmailerHtmlFromContent(content, event || {}, participant); + } else if (typeof content.html === 'string') { + bodyTpl = content.html; + } + } else if (typeof content === 'string') { + bodyTpl = content; + } + + if (!String(bodyTpl).trim()) { + console.warn('[registrationConfirmation] template has empty body', tplId); + return { skipped: true, reason: 'empty_body' }; + } + + const { subject, body } = mergeCampaignContent( + subjectTpl || 'Registration received — {{event.name}}', + bodyTpl, + participant, + event || {}, + ); + + const result = await sendOrgMail({ + organizationId: orgId, + to, + subject, + html: body, + }); + + if (result?.ok) { + console.log('[registrationConfirmation] sent to=', to, 'form=', form._id, 'template=', tplId); + } else if (result?.skipped) { + console.warn('[registrationConfirmation] skipped (no SMTP) to=', to); + } else { + console.error('[registrationConfirmation] failed to=', to, result?.error); + } + return result; +} + +module.exports = { sendRegistrationConfirmationEmail }; diff --git a/src/utils/visitorBuiltinForms.js b/src/utils/visitorBuiltinForms.js index 88f36b5..43b669b 100644 --- a/src/utils/visitorBuiltinForms.js +++ b/src/utils/visitorBuiltinForms.js @@ -94,6 +94,7 @@ async function ensureBuiltinVisitorForm(event, purpose = 'feedback') { module.exports = { BUILTIN_FEEDBACK_FORM_NAME, BUILTIN_RATINGS_FORM_NAME, + ALL_BUILTIN_RATINGS_NAMES, isBuiltinVisitorFormName, ensureBuiltinVisitorForm, };

${previewText ? `

${escapeHtml(previewText)}

` : ''}