├── web ├── README.md ├── src │ ├── actions │ │ ├── index.js │ │ ├── types.js │ │ └── page.js │ ├── history.js │ ├── reducers │ │ ├── index.js │ │ ├── menu.js │ │ └── page.js │ ├── store.js │ ├── components │ │ ├── header.js │ │ ├── menu.js │ │ ├── page.js │ │ ├── elements │ │ │ ├── builder.js │ │ │ └── index.js │ │ └── toolbar │ │ │ └── index.js │ ├── index.js │ ├── css │ │ ├── app.css.map │ │ ├── app.scss │ │ ├── app.css │ │ └── grid.css │ ├── containers │ │ └── app.js │ └── registerServiceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── .gitignore └── package.json ├── .gitignore └── README.md /web/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/src/actions/index.js: -------------------------------------------------------------------------------- 1 | export * from './page' -------------------------------------------------------------------------------- /web/src/actions/types.js: -------------------------------------------------------------------------------- 1 | // Page types 2 | 3 | export const UPDATE_PAGE = 'page/update_page' -------------------------------------------------------------------------------- /web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tabvn/react-redux-pagebuilder/HEAD/web/public/favicon.ico -------------------------------------------------------------------------------- /web/src/history.js: -------------------------------------------------------------------------------- 1 | import createHistory from 'history/createBrowserHistory' 2 | 3 | export const history = createHistory() -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | web/node_modules 2 | web/package-lock.json 3 | .idea 4 | .idea/* 5 | .idea/workspace.xml 6 | .idea/tasks.xml 7 | .idea/dictionaries 8 | .idea/vcs.xml 9 | .idea/jsLibraryMappings.xml -------------------------------------------------------------------------------- /web/src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from 'redux' 2 | import page from './page' 3 | import menu from './menu' 4 | export default combineReducers({ 5 | page, 6 | menu 7 | }) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-redux-pagebuilder 2 | Create Page builder for static page use React & Redux 3 | 4 | ## Video Tutorials 5 | 6 | https://www.youtube.com/playlist?list=PLFaW_8zE4amNImOhLMD577Lx87IaA4_fp&disable_polymer=true 7 | -------------------------------------------------------------------------------- /web/src/store.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware} from 'redux' 2 | import thunk from 'redux-thunk' 3 | import reducers from './reducers' 4 | 5 | // Create Redux store 6 | export const store = createStore(reducers, applyMiddleware(thunk)) 7 | -------------------------------------------------------------------------------- /web/src/actions/page.js: -------------------------------------------------------------------------------- 1 | import {UPDATE_PAGE} from './types' 2 | 3 | export const updatePage = (page) => { 4 | return (dispatch) => { 5 | 6 | console.log("Receive redux actions", page) 7 | dispatch({ 8 | type: UPDATE_PAGE, 9 | payload: page 10 | }) 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /web/src/components/header.js: -------------------------------------------------------------------------------- 1 | import React,{Component} from 'react' 2 | import Menu from './menu' 3 | 4 | class Header extends Component{ 5 | 6 | 7 | render(){ 8 | return ( 9 |
10 | 11 |
12 | ) 13 | } 14 | } 15 | 16 | export default Header -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /web/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /web/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import registerServiceWorker from './registerServiceWorker'; 4 | import App from './containers/app' 5 | import {store} from './store' 6 | import {Provider} from 'react-redux' 7 | 8 | ReactDOM.render( 9 | 10 | 11 | , document.getElementById('root')); 12 | registerServiceWorker(); 13 | -------------------------------------------------------------------------------- /web/src/reducers/menu.js: -------------------------------------------------------------------------------- 1 | 2 | const initState = { 3 | items: [ 4 | { 5 | id: "menu-1", 6 | path: '/', 7 | title: 'Home' 8 | }, 9 | { 10 | id: "menu-2", 11 | path: 'about', 12 | title: 'About' 13 | } 14 | ], 15 | active: null, 16 | } 17 | 18 | export default (state = initState, action) => { 19 | 20 | switch (action.type){ 21 | 22 | 23 | default: 24 | 25 | return state 26 | } 27 | } -------------------------------------------------------------------------------- /web/src/css/app.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAQ,qBAAU;AAElB,IAAK;EACH,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,KAAK;EACZ,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;;AAGX,CAAE;EACA,UAAU,EAAE,UAAU;;AAGxB,WAAW;EACT,UAAU,EAAE,mBAAgB;EAC5B,OAAO,EAAE,IAAI;;AAGb,YAAG;EACD,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EACV,eAAG;IACD,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,OAAO;IACf,2BAAc;MACZ,YAAY,EAAE,CAAC;IAEjB,0BAAa;MACX,aAAa,EAAE,CAAC;IAElB,iBAAE;MACA,KAAK,EAAE,KAAK;MACZ,eAAe,EAAE,IAAI", 4 | "sources": ["app.scss"], 5 | "names": [], 6 | "file": "app.css" 7 | } -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "lodash": "^4.17.10", 7 | "react": "^16.3.2", 8 | "react-dom": "^16.3.2", 9 | "react-redux": "^5.0.7", 10 | "react-router": "^4.2.0", 11 | "react-router-dom": "^4.2.2", 12 | "react-scripts": "1.1.4", 13 | "redux": "^4.0.0", 14 | "redux-thunk": "^2.2.0", 15 | "styled-components": "^3.2.6", 16 | "uuid": "^3.2.1" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test --env=jsdom", 22 | "eject": "react-scripts eject" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /web/src/css/app.scss: -------------------------------------------------------------------------------- 1 | @import "grid.css"; 2 | 3 | body { 4 | font-size: 14px; 5 | color: black; 6 | padding: 0; 7 | margin: 0; 8 | } 9 | 10 | * { 11 | box-sizing: border-box; 12 | } 13 | 14 | .app-header{ 15 | background: rgba(0,0,0, .05); 16 | padding: 20px; 17 | } 18 | .app-menu { 19 | ul { 20 | list-style: none; 21 | margin: 0; 22 | padding: 0; 23 | li { 24 | list-style: none; 25 | margin: 0; 26 | padding: 0 10px; 27 | display: inline-block; 28 | cursor: pointer; 29 | &:first-child { 30 | padding-left: 0; 31 | } 32 | &:last-child { 33 | padding-right: 0; 34 | } 35 | a { 36 | color: black; 37 | text-decoration: none; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /web/src/css/app.css: -------------------------------------------------------------------------------- 1 | @import url(grid.css); 2 | body { 3 | font-size: 14px; 4 | color: black; 5 | padding: 0; 6 | margin: 0; } 7 | 8 | * { 9 | box-sizing: border-box; } 10 | 11 | .app-header { 12 | background: rgba(0, 0, 0, 0.05); 13 | padding: 20px; } 14 | 15 | .app-menu ul { 16 | list-style: none; 17 | margin: 0; 18 | padding: 0; } 19 | .app-menu ul li { 20 | list-style: none; 21 | margin: 0; 22 | padding: 0 10px; 23 | display: inline-block; 24 | cursor: pointer; } 25 | .app-menu ul li:first-child { 26 | padding-left: 0; } 27 | .app-menu ul li:last-child { 28 | padding-right: 0; } 29 | .app-menu ul li a { 30 | color: black; 31 | text-decoration: none; } 32 | 33 | /*# sourceMappingURL=app.css.map */ 34 | -------------------------------------------------------------------------------- /web/src/containers/app.js: -------------------------------------------------------------------------------- 1 | import React,{Component} from 'react' 2 | import Header from '../components/header' 3 | import '../css/app.css' 4 | 5 | import {history} from '../history' 6 | import {Router, Route, Switch} from 'react-router-dom' 7 | 8 | import Page from '../components/page' 9 | class App extends Component{ 10 | 11 | constructor (props){ 12 | super(props) 13 | } 14 | 15 | render(){ 16 | return ( 17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | ) 29 | } 30 | } 31 | 32 | 33 | export default App -------------------------------------------------------------------------------- /web/src/components/menu.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | import { history } from '../history' 4 | 5 | class Menu extends Component { 6 | 7 | constructor (props) { 8 | super(props) 9 | 10 | this._openPage = this._openPage.bind(this) 11 | } 12 | 13 | _openPage (link) { 14 | history.push(link.path) 15 | } 16 | 17 | render () { 18 | 19 | const {menu} = this.props 20 | const {items} = menu 21 | 22 | return ( 23 |
24 | 34 |
35 | ) 36 | } 37 | } 38 | 39 | const mapStateToProps = (state) => ({ 40 | menu: state.menu, 41 | }) 42 | 43 | const mapDispatchToProps = (dispatch) => ({}) 44 | export default connect( 45 | mapStateToProps, 46 | mapDispatchToProps, 47 | )(Menu) -------------------------------------------------------------------------------- /web/src/components/page.js: -------------------------------------------------------------------------------- 1 | import React,{Component} from 'react' 2 | import {connect} from 'react-redux' 3 | import _ from 'lodash' 4 | import Builder from './elements/builder' 5 | 6 | class Page extends Component{ 7 | 8 | constructor (props){ 9 | super(props) 10 | 11 | 12 | this.getPageByPath = this.getPageByPath.bind(this) 13 | } 14 | 15 | getPageByPath(path){ 16 | 17 | const {pages} = this.props 18 | 19 | const page = pages.find((p) => p.path === path) 20 | return page 21 | } 22 | render(){ 23 | const {match, pages} = this.props 24 | 25 | const path = _.trim(_.get(match, 'params.path', '/')) 26 | 27 | const page = this.getPageByPath(path) 28 | 29 | const pageTitle = _.get(page, 'title', '') 30 | const pageBody = _.get(page, 'body', '') 31 | return ( 32 |
33 |

{pageTitle}

34 |
35 | { 36 | pageBody 37 | } 38 |
39 | 40 | 41 |
42 | ) 43 | } 44 | } 45 | 46 | const mapStateToProps = (state) => ({ 47 | pages: state.page, 48 | }) 49 | 50 | 51 | const mapDispatchToProps = (dispatch) => ({ 52 | 53 | }) 54 | 55 | export default connect( 56 | mapStateToProps, 57 | mapDispatchToProps 58 | )(Page) 59 | 60 | -------------------------------------------------------------------------------- /web/src/components/elements/builder.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react' 2 | import _ from 'lodash' 3 | import BuilderElement from './index' 4 | import Toolbar from '../toolbar' 5 | import { connect } from 'react-redux' 6 | import { updatePage } from '../../actions' 7 | 8 | const isEditing = true 9 | 10 | class Builder extends Component { 11 | 12 | render () { 13 | const {page} = this.props 14 | 15 | const allElements = _.get(page, 'elements', []) 16 | 17 | const elements = allElements.filter((e) => e.parent === null || !e.parent) 18 | return ( 19 | 20 | { 21 | isEditing ? { 22 | 23 | console.log('Receive page change from children component is:', page) 24 | 25 | this.props.update(page) 26 | 27 | }} page={page} parentElement={null}/> : null 28 | } 29 | { 30 | elements.map((element, index) => { 31 | return 32 | }) 33 | } 34 | 35 | ) 36 | } 37 | } 38 | 39 | const mapStateToProps = (state) => ({ 40 | pages: state.page, 41 | }) 42 | 43 | const mapDispatchToProps = (dispatch) => ({ 44 | update: (page) => { 45 | dispatch(updatePage(page)) 46 | }, 47 | }) 48 | 49 | export default connect(mapStateToProps, mapDispatchToProps)(Builder) -------------------------------------------------------------------------------- /web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /web/src/components/toolbar/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import styled from 'styled-components' 3 | import _ from 'lodash' 4 | import uuid from 'uuid/v1' 5 | 6 | const Wrapper = styled.div ` 7 | 8 | margin: 20px; 9 | padding: 0; 10 | background: rgba(0,0,0,0.03); 11 | 12 | ul{ 13 | margin: 0; 14 | padding: 0; 15 | li { 16 | color: blue; 17 | cursor: pointer; 18 | padding: 3px 8px; 19 | margin: 0; 20 | display: inline-block; 21 | } 22 | } 23 | 24 | ` 25 | 26 | export default class Toolbar extends Component { 27 | 28 | constructor (props) { 29 | super(props) 30 | 31 | this._onAddElement = this._onAddElement.bind(this) 32 | } 33 | 34 | _handleCreateRow(parentElement){ 35 | 36 | return { 37 | id: this.autoId(), 38 | type: 'row', 39 | options: { 40 | container: 'container-fluid', 41 | }, 42 | parent: _.get(parentElement, 'id', null), 43 | } 44 | } 45 | /** 46 | * Handle add new element 47 | * @param elementType 48 | * @param parentElement 49 | * @private 50 | */ 51 | _onAddElement (elementType, parentElement) { 52 | 53 | let {page} = this.props 54 | 55 | let pageElements = _.get(page, 'elements', []) 56 | 57 | let newElement = null 58 | 59 | switch (elementType) { 60 | 61 | case 'row': 62 | 63 | newElement = this._handleCreateRow(parentElement) 64 | 65 | break 66 | 67 | case 'column': 68 | 69 | // let add row first, then add new column 70 | 71 | const newRow = this._handleCreateRow(parentElement) 72 | // push new row to pageElements 73 | 74 | pageElements.push(newRow) 75 | 76 | newElement = { 77 | type: 'column', 78 | id: this.autoId(), 79 | options: { 80 | responsive:{ 81 | extraSmall: 4, 82 | } 83 | }, 84 | parent: newRow.id, 85 | } 86 | 87 | break 88 | 89 | 90 | case 'p': 91 | 92 | newElement = { 93 | type: 'p', 94 | options: { 95 | text: "Sample text...." 96 | }, 97 | parent: _.get(parentElement, 'id', null) 98 | } 99 | break 100 | 101 | default: 102 | 103 | break 104 | } 105 | 106 | if (newElement) { 107 | pageElements.push(newElement) 108 | //page.elements = pageElements 109 | page = _.setWith(page, 'elements', pageElements) 110 | if (this.props.onChange) { 111 | 112 | this.props.onChange(page) 113 | } 114 | } 115 | 116 | } 117 | 118 | autoId () { 119 | 120 | return uuid() 121 | } 122 | 123 | render () { 124 | const {parentElement} = this.props 125 | 126 | const actionsItems = [ 127 | { 128 | type: 'row', 129 | title: 'Add row', 130 | }, 131 | { 132 | type: 'column', 133 | title: 'Add column', 134 | }, 135 | { 136 | type: 'p', 137 | title: 'Add Text' 138 | } 139 | ] 140 | return ( 141 | 142 | 153 | 154 | ) 155 | } 156 | } -------------------------------------------------------------------------------- /web/src/reducers/page.js: -------------------------------------------------------------------------------- 1 | import { UPDATE_PAGE } from '../actions/types' 2 | import _ from 'lodash' 3 | 4 | const initState = [ 5 | { 6 | id: 'page-about-us', 7 | title: 'About Us', 8 | path: 'about', 9 | body: 'hello from About page simple text content', 10 | elements: [ 11 | { 12 | id: 'id-h2-1', 13 | type: 'h2', 14 | options: { 15 | style: {fontSize: '20px', color: 'blue'}, 16 | text: 'Heading 2 - id-h2-1', 17 | }, 18 | parent: 'column-row-1-1', 19 | sort: 0, 20 | }, 21 | { 22 | id: 'id-h3-1', 23 | type: 'h3', 24 | options: { 25 | style: {fontSize: '18px', color: 'blue'}, 26 | text: 'Heading 3 - id-h3-1', 27 | }, 28 | sort: 2, 29 | parent: 'column-row-1-3', 30 | }, 31 | { 32 | id: 'id-p-1', 33 | type: 'p', 34 | options: { 35 | text: 'This is paragraph text content - id-p-1', 36 | }, 37 | sort: 1, 38 | parent: 'column-row-1-2', 39 | }, 40 | 41 | // row Element 42 | { 43 | id: 'row-1', 44 | type: 'row', 45 | options: { 46 | container: 'container-fluid', 47 | style: {border: 'border 1px solid rgba(0,0,0,0.08)'}, 48 | 49 | }, 50 | }, 51 | //Column element 52 | { 53 | id: 'column-row-1-1', 54 | type: 'column', 55 | options: { 56 | responsive: { 57 | extraSmall: 6, 58 | small: 6, 59 | medium: 4, 60 | large: 3, 61 | extraLarge: 2, 62 | }, 63 | style: {}, 64 | }, 65 | parent: 'row-1', 66 | }, 67 | { 68 | id: 'column-row-1-2', 69 | type: 'column', 70 | options: { 71 | responsive: { 72 | extraSmall: 6, 73 | small: 6, 74 | medium: 4, 75 | large: 3, 76 | extraLarge: 2, 77 | }, 78 | style: {}, 79 | }, 80 | parent: 'row-1', 81 | }, 82 | { 83 | id: 'column-row-1-3', 84 | type: 'column', 85 | options: { 86 | responsive: { 87 | extraSmall: 6, 88 | small: 6, 89 | medium: 4, 90 | large: 3, 91 | extraLarge: 2, 92 | }, 93 | style: {}, 94 | }, 95 | parent: 'row-1', 96 | }, 97 | // row 2 98 | 99 | { 100 | id: 'row-2', 101 | type: 'row', 102 | options: { 103 | container: 'container-fluid', 104 | }, 105 | }, 106 | // column 107 | { 108 | id: 'column-row-2-1', 109 | type: 'column', 110 | options: { 111 | responsive: { 112 | extraSmall: 6, 113 | }, 114 | }, 115 | parent: 'row-2', 116 | }, 117 | //Column 118 | { 119 | id: 'column-row-2-2', 120 | type: 'column', 121 | options: { 122 | responsive: { 123 | extraSmall: 6, 124 | }, 125 | }, 126 | parent: 'row-2', 127 | }, 128 | { 129 | id: 'p-text-1', 130 | type: 'p', 131 | options: { 132 | text: 'Text content in column 1', 133 | }, 134 | parent: 'column-row-2-1', 135 | }, 136 | { 137 | id: 'p-text-2', 138 | type: 'p', 139 | options: { 140 | text: 'Text content in column 2', 141 | }, 142 | parent: 'column-row-2-2', 143 | }, 144 | ], 145 | }, 146 | { 147 | id: 'home', 148 | title: 'Home', 149 | path: '/', 150 | body: 'Welcome to the Home page', 151 | elements: [], 152 | }, 153 | ] 154 | 155 | export default (state = initState, action) => { 156 | 157 | const payload = _.get(action, 'payload') 158 | 159 | switch (action.type) { 160 | 161 | case UPDATE_PAGE: 162 | 163 | // remove existing with ID 164 | let pages = state.filter((p) => p.id !== payload.id) 165 | 166 | return [ 167 | ...pages, 168 | payload 169 | ] 170 | 171 | default: 172 | 173 | return state 174 | } 175 | } -------------------------------------------------------------------------------- /web/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /web/src/components/elements/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from 'react' 2 | import _ from 'lodash' 3 | import styled from 'styled-components' 4 | 5 | const themeSettings = { 6 | defaultColor: 'black', 7 | defaultFontSize: '14px', 8 | defaultH2FontSize: '20px', 9 | defaultH3FontSize: '18px', 10 | defaultH4FontSize: '16px', 11 | defaultH5FontSize: '15px', 12 | defaultH6FontSize: '14px', 13 | } 14 | 15 | const P = styled.p` 16 | font-size: 14px; 17 | color: blue; 18 | ` 19 | 20 | const H2 = styled.h2 ` 21 | font-size: ${props => _.get(props, 'options.style.fontSize', 22 | themeSettings.defaultH2FontSize)}; 23 | color: ${props => _.get(props, 'options.style.color', 24 | themeSettings.defaultColor)} 25 | ` 26 | const H3 = styled.h3 ` 27 | font-size: ${props => _.get(props, 'options.style.fontSize', 28 | themeSettings.defaultH3FontSize)}; 29 | color: ${props => _.get(props, 'options.style.color', 30 | themeSettings.defaultColor)} 31 | ` 32 | 33 | const H4 = styled.h4 ` 34 | font-size: ${props => _.get(props, 'options.style.fontSize', 35 | themeSettings.defaultH4FontSize)}; 36 | color: ${props => _.get(props, 'options.style.color', 37 | themeSettings.defaultColor)} 38 | ` 39 | 40 | const H5 = styled.h5 ` 41 | font-size: ${props => _.get(props, 'options.style.fontSize', 42 | themeSettings.defaultH5FontSize)}; 43 | color: ${props => _.get(props, 'options.style.color', 44 | themeSettings.defaultColor)} 45 | ` 46 | 47 | const H6 = styled.h6 ` 48 | font-size: ${props => _.get(props, 'options.style.fontSize', 49 | themeSettings.defaultH6FontSize)}; 50 | color: ${props => _.get(props, 'options.style.color', 51 | themeSettings.defaultColor)} 52 | ` 53 | 54 | const Row = styled.div ` 55 | 56 | ` 57 | 58 | const Column = styled.div ` 59 | border: 1px solid rgba(0,0,0,0.04); 60 | min-height: 30px; 61 | ` 62 | 63 | class BuilderElement extends Component { 64 | 65 | constructor (props) { 66 | 67 | super(props) 68 | 69 | this._renderElement = this._renderElement.bind(this) 70 | this._renderRowElement = this._renderRowElement.bind(this) 71 | this._renderColumnElement = this._renderColumnElement.bind(this) 72 | } 73 | 74 | _renderColumnElement (columnElement) { 75 | 76 | const {page} = this.props 77 | const allElements = _.get(page, 'elements', []) 78 | 79 | const childrenElements = allElements.filter( 80 | (e) => e.parent === columnElement.id) 81 | 82 | return childrenElements.map((e, index) => { 83 | return {this._renderElement(e)} 84 | }) 85 | 86 | } 87 | 88 | _renderRowElement (element) { 89 | 90 | const {page} = this.props 91 | const allElements = _.get(page, 'elements', []) 92 | 93 | let output = null 94 | const rowContainer = _.get(element, 'options.container', null) 95 | const id = _.get(element, 'id') 96 | 97 | const columns = allElements.filter( 98 | (e) => e.type === 'column' && e.parent === id) 99 | 100 | const row = 101 | { 102 | columns.map((column, index) => { 103 | 104 | const responsive = _.get(column, 'options.responsive') 105 | const extraSmall = _.get(responsive, 'extraSmall', null) 106 | const small = _.get(responsive, 'small', null) 107 | const medium = _.get(responsive, 'medium', null) 108 | const large = _.get(responsive, 'large', null) 109 | const extraLarge = _.get(responsive, 'extraLarge', null) 110 | 111 | let classes = [] 112 | if (extraSmall) { 113 | classes.push(`col-${extraSmall}`) 114 | } 115 | if (small) { 116 | classes.push(`col-sm-${small}`) 117 | } 118 | if (medium) { 119 | classes.push(`col-md-${medium}`) 120 | } 121 | if (large) { 122 | classes.push(`col-lg-${large}`) 123 | } 124 | if (extraLarge) { 125 | classes.push(`col-xl-${extraLarge}`) 126 | } 127 | 128 | return {this._renderColumnElement(column)} 130 | }) 131 | } 132 | 133 | if (rowContainer) { 134 | output =
{row}
135 | } else { 136 | output = row 137 | } 138 | 139 | return output 140 | } 141 | 142 | _renderElement (element) { 143 | 144 | const type = _.get(element, 'type') 145 | const options = _.get(element, 'options') 146 | 147 | let output = null 148 | const text = _.get(element, 'options.text', null) 149 | 150 | switch (type) { 151 | 152 | case 'p': 153 | if (text && text !== '') { 154 | output =

{text}

155 | } 156 | 157 | break 158 | 159 | case 'h2': 160 | 161 | output =

{text}

162 | 163 | break 164 | 165 | case 'h3': 166 | 167 | output =

{text}

168 | 169 | break 170 | 171 | case 'h4': 172 | 173 | output =

{text}

174 | 175 | break 176 | 177 | case 'h5': 178 | 179 | output =
{text}
180 | 181 | break 182 | 183 | case 'h6': 184 | 185 | output =
{text}
186 | 187 | break 188 | 189 | case 'row': 190 | 191 | output = this._renderRowElement(element) 192 | break 193 | 194 | case 'column': 195 | 196 | output = this._renderColumnElement(element) 197 | 198 | break 199 | 200 | default: 201 | 202 | break 203 | } 204 | 205 | return output 206 | } 207 | 208 | render () { 209 | 210 | const {element} = this.props 211 | 212 | return ( 213 | 214 | { 215 | this._renderElement(element) 216 | } 217 | 218 | ) 219 | } 220 | } 221 | 222 | export default BuilderElement -------------------------------------------------------------------------------- /web/src/css/grid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v4.1.0 (https://getbootstrap.com/) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | @-ms-viewport { 8 | width: device-width; 9 | } 10 | 11 | html { 12 | box-sizing: border-box; 13 | -ms-overflow-style: scrollbar; 14 | } 15 | 16 | *, 17 | *::before, 18 | *::after { 19 | box-sizing: inherit; 20 | } 21 | 22 | .container { 23 | width: 100%; 24 | padding-right: 15px; 25 | padding-left: 15px; 26 | margin-right: auto; 27 | margin-left: auto; 28 | } 29 | 30 | @media (min-width: 576px) { 31 | .container { 32 | max-width: 540px; 33 | } 34 | } 35 | 36 | @media (min-width: 768px) { 37 | .container { 38 | max-width: 720px; 39 | } 40 | } 41 | 42 | @media (min-width: 992px) { 43 | .container { 44 | max-width: 960px; 45 | } 46 | } 47 | 48 | @media (min-width: 1200px) { 49 | .container { 50 | max-width: 1140px; 51 | } 52 | } 53 | 54 | .container-fluid { 55 | width: 100%; 56 | padding-right: 15px; 57 | padding-left: 15px; 58 | margin-right: auto; 59 | margin-left: auto; 60 | } 61 | 62 | .row { 63 | display: -ms-flexbox; 64 | display: flex; 65 | -ms-flex-wrap: wrap; 66 | flex-wrap: wrap; 67 | margin-right: -15px; 68 | margin-left: -15px; 69 | } 70 | 71 | .no-gutters { 72 | margin-right: 0; 73 | margin-left: 0; 74 | } 75 | 76 | .no-gutters > .col, 77 | .no-gutters > [class*="col-"] { 78 | padding-right: 0; 79 | padding-left: 0; 80 | } 81 | 82 | .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, 83 | .col-auto, .col-sm-1, .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-10, .col-sm-11, .col-sm-12, .col-sm, 84 | .col-sm-auto, .col-md-1, .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-10, .col-md-11, .col-md-12, .col-md, 85 | .col-md-auto, .col-lg-1, .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-10, .col-lg-11, .col-lg-12, .col-lg, 86 | .col-lg-auto, .col-xl-1, .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-10, .col-xl-11, .col-xl-12, .col-xl, 87 | .col-xl-auto { 88 | position: relative; 89 | width: 100%; 90 | min-height: 1px; 91 | padding-right: 15px; 92 | padding-left: 15px; 93 | } 94 | 95 | .col { 96 | -ms-flex-preferred-size: 0; 97 | flex-basis: 0; 98 | -ms-flex-positive: 1; 99 | flex-grow: 1; 100 | max-width: 100%; 101 | } 102 | 103 | .col-auto { 104 | -ms-flex: 0 0 auto; 105 | flex: 0 0 auto; 106 | width: auto; 107 | max-width: none; 108 | } 109 | 110 | .col-1 { 111 | -ms-flex: 0 0 8.333333%; 112 | flex: 0 0 8.333333%; 113 | max-width: 8.333333%; 114 | } 115 | 116 | .col-2 { 117 | -ms-flex: 0 0 16.666667%; 118 | flex: 0 0 16.666667%; 119 | max-width: 16.666667%; 120 | } 121 | 122 | .col-3 { 123 | -ms-flex: 0 0 25%; 124 | flex: 0 0 25%; 125 | max-width: 25%; 126 | } 127 | 128 | .col-4 { 129 | -ms-flex: 0 0 33.333333%; 130 | flex: 0 0 33.333333%; 131 | max-width: 33.333333%; 132 | } 133 | 134 | .col-5 { 135 | -ms-flex: 0 0 41.666667%; 136 | flex: 0 0 41.666667%; 137 | max-width: 41.666667%; 138 | } 139 | 140 | .col-6 { 141 | -ms-flex: 0 0 50%; 142 | flex: 0 0 50%; 143 | max-width: 50%; 144 | } 145 | 146 | .col-7 { 147 | -ms-flex: 0 0 58.333333%; 148 | flex: 0 0 58.333333%; 149 | max-width: 58.333333%; 150 | } 151 | 152 | .col-8 { 153 | -ms-flex: 0 0 66.666667%; 154 | flex: 0 0 66.666667%; 155 | max-width: 66.666667%; 156 | } 157 | 158 | .col-9 { 159 | -ms-flex: 0 0 75%; 160 | flex: 0 0 75%; 161 | max-width: 75%; 162 | } 163 | 164 | .col-10 { 165 | -ms-flex: 0 0 83.333333%; 166 | flex: 0 0 83.333333%; 167 | max-width: 83.333333%; 168 | } 169 | 170 | .col-11 { 171 | -ms-flex: 0 0 91.666667%; 172 | flex: 0 0 91.666667%; 173 | max-width: 91.666667%; 174 | } 175 | 176 | .col-12 { 177 | -ms-flex: 0 0 100%; 178 | flex: 0 0 100%; 179 | max-width: 100%; 180 | } 181 | 182 | .order-first { 183 | -ms-flex-order: -1; 184 | order: -1; 185 | } 186 | 187 | .order-last { 188 | -ms-flex-order: 13; 189 | order: 13; 190 | } 191 | 192 | .order-0 { 193 | -ms-flex-order: 0; 194 | order: 0; 195 | } 196 | 197 | .order-1 { 198 | -ms-flex-order: 1; 199 | order: 1; 200 | } 201 | 202 | .order-2 { 203 | -ms-flex-order: 2; 204 | order: 2; 205 | } 206 | 207 | .order-3 { 208 | -ms-flex-order: 3; 209 | order: 3; 210 | } 211 | 212 | .order-4 { 213 | -ms-flex-order: 4; 214 | order: 4; 215 | } 216 | 217 | .order-5 { 218 | -ms-flex-order: 5; 219 | order: 5; 220 | } 221 | 222 | .order-6 { 223 | -ms-flex-order: 6; 224 | order: 6; 225 | } 226 | 227 | .order-7 { 228 | -ms-flex-order: 7; 229 | order: 7; 230 | } 231 | 232 | .order-8 { 233 | -ms-flex-order: 8; 234 | order: 8; 235 | } 236 | 237 | .order-9 { 238 | -ms-flex-order: 9; 239 | order: 9; 240 | } 241 | 242 | .order-10 { 243 | -ms-flex-order: 10; 244 | order: 10; 245 | } 246 | 247 | .order-11 { 248 | -ms-flex-order: 11; 249 | order: 11; 250 | } 251 | 252 | .order-12 { 253 | -ms-flex-order: 12; 254 | order: 12; 255 | } 256 | 257 | .offset-1 { 258 | margin-left: 8.333333%; 259 | } 260 | 261 | .offset-2 { 262 | margin-left: 16.666667%; 263 | } 264 | 265 | .offset-3 { 266 | margin-left: 25%; 267 | } 268 | 269 | .offset-4 { 270 | margin-left: 33.333333%; 271 | } 272 | 273 | .offset-5 { 274 | margin-left: 41.666667%; 275 | } 276 | 277 | .offset-6 { 278 | margin-left: 50%; 279 | } 280 | 281 | .offset-7 { 282 | margin-left: 58.333333%; 283 | } 284 | 285 | .offset-8 { 286 | margin-left: 66.666667%; 287 | } 288 | 289 | .offset-9 { 290 | margin-left: 75%; 291 | } 292 | 293 | .offset-10 { 294 | margin-left: 83.333333%; 295 | } 296 | 297 | .offset-11 { 298 | margin-left: 91.666667%; 299 | } 300 | 301 | @media (min-width: 576px) { 302 | .col-sm { 303 | -ms-flex-preferred-size: 0; 304 | flex-basis: 0; 305 | -ms-flex-positive: 1; 306 | flex-grow: 1; 307 | max-width: 100%; 308 | } 309 | 310 | .col-sm-auto { 311 | -ms-flex: 0 0 auto; 312 | flex: 0 0 auto; 313 | width: auto; 314 | max-width: none; 315 | } 316 | 317 | .col-sm-1 { 318 | -ms-flex: 0 0 8.333333%; 319 | flex: 0 0 8.333333%; 320 | max-width: 8.333333%; 321 | } 322 | 323 | .col-sm-2 { 324 | -ms-flex: 0 0 16.666667%; 325 | flex: 0 0 16.666667%; 326 | max-width: 16.666667%; 327 | } 328 | 329 | .col-sm-3 { 330 | -ms-flex: 0 0 25%; 331 | flex: 0 0 25%; 332 | max-width: 25%; 333 | } 334 | 335 | .col-sm-4 { 336 | -ms-flex: 0 0 33.333333%; 337 | flex: 0 0 33.333333%; 338 | max-width: 33.333333%; 339 | } 340 | 341 | .col-sm-5 { 342 | -ms-flex: 0 0 41.666667%; 343 | flex: 0 0 41.666667%; 344 | max-width: 41.666667%; 345 | } 346 | 347 | .col-sm-6 { 348 | -ms-flex: 0 0 50%; 349 | flex: 0 0 50%; 350 | max-width: 50%; 351 | } 352 | 353 | .col-sm-7 { 354 | -ms-flex: 0 0 58.333333%; 355 | flex: 0 0 58.333333%; 356 | max-width: 58.333333%; 357 | } 358 | 359 | .col-sm-8 { 360 | -ms-flex: 0 0 66.666667%; 361 | flex: 0 0 66.666667%; 362 | max-width: 66.666667%; 363 | } 364 | 365 | .col-sm-9 { 366 | -ms-flex: 0 0 75%; 367 | flex: 0 0 75%; 368 | max-width: 75%; 369 | } 370 | 371 | .col-sm-10 { 372 | -ms-flex: 0 0 83.333333%; 373 | flex: 0 0 83.333333%; 374 | max-width: 83.333333%; 375 | } 376 | 377 | .col-sm-11 { 378 | -ms-flex: 0 0 91.666667%; 379 | flex: 0 0 91.666667%; 380 | max-width: 91.666667%; 381 | } 382 | 383 | .col-sm-12 { 384 | -ms-flex: 0 0 100%; 385 | flex: 0 0 100%; 386 | max-width: 100%; 387 | } 388 | 389 | .order-sm-first { 390 | -ms-flex-order: -1; 391 | order: -1; 392 | } 393 | 394 | .order-sm-last { 395 | -ms-flex-order: 13; 396 | order: 13; 397 | } 398 | 399 | .order-sm-0 { 400 | -ms-flex-order: 0; 401 | order: 0; 402 | } 403 | 404 | .order-sm-1 { 405 | -ms-flex-order: 1; 406 | order: 1; 407 | } 408 | 409 | .order-sm-2 { 410 | -ms-flex-order: 2; 411 | order: 2; 412 | } 413 | 414 | .order-sm-3 { 415 | -ms-flex-order: 3; 416 | order: 3; 417 | } 418 | 419 | .order-sm-4 { 420 | -ms-flex-order: 4; 421 | order: 4; 422 | } 423 | 424 | .order-sm-5 { 425 | -ms-flex-order: 5; 426 | order: 5; 427 | } 428 | 429 | .order-sm-6 { 430 | -ms-flex-order: 6; 431 | order: 6; 432 | } 433 | 434 | .order-sm-7 { 435 | -ms-flex-order: 7; 436 | order: 7; 437 | } 438 | 439 | .order-sm-8 { 440 | -ms-flex-order: 8; 441 | order: 8; 442 | } 443 | 444 | .order-sm-9 { 445 | -ms-flex-order: 9; 446 | order: 9; 447 | } 448 | 449 | .order-sm-10 { 450 | -ms-flex-order: 10; 451 | order: 10; 452 | } 453 | 454 | .order-sm-11 { 455 | -ms-flex-order: 11; 456 | order: 11; 457 | } 458 | 459 | .order-sm-12 { 460 | -ms-flex-order: 12; 461 | order: 12; 462 | } 463 | 464 | .offset-sm-0 { 465 | margin-left: 0; 466 | } 467 | 468 | .offset-sm-1 { 469 | margin-left: 8.333333%; 470 | } 471 | 472 | .offset-sm-2 { 473 | margin-left: 16.666667%; 474 | } 475 | 476 | .offset-sm-3 { 477 | margin-left: 25%; 478 | } 479 | 480 | .offset-sm-4 { 481 | margin-left: 33.333333%; 482 | } 483 | 484 | .offset-sm-5 { 485 | margin-left: 41.666667%; 486 | } 487 | 488 | .offset-sm-6 { 489 | margin-left: 50%; 490 | } 491 | 492 | .offset-sm-7 { 493 | margin-left: 58.333333%; 494 | } 495 | 496 | .offset-sm-8 { 497 | margin-left: 66.666667%; 498 | } 499 | 500 | .offset-sm-9 { 501 | margin-left: 75%; 502 | } 503 | 504 | .offset-sm-10 { 505 | margin-left: 83.333333%; 506 | } 507 | 508 | .offset-sm-11 { 509 | margin-left: 91.666667%; 510 | } 511 | } 512 | 513 | @media (min-width: 768px) { 514 | .col-md { 515 | -ms-flex-preferred-size: 0; 516 | flex-basis: 0; 517 | -ms-flex-positive: 1; 518 | flex-grow: 1; 519 | max-width: 100%; 520 | } 521 | 522 | .col-md-auto { 523 | -ms-flex: 0 0 auto; 524 | flex: 0 0 auto; 525 | width: auto; 526 | max-width: none; 527 | } 528 | 529 | .col-md-1 { 530 | -ms-flex: 0 0 8.333333%; 531 | flex: 0 0 8.333333%; 532 | max-width: 8.333333%; 533 | } 534 | 535 | .col-md-2 { 536 | -ms-flex: 0 0 16.666667%; 537 | flex: 0 0 16.666667%; 538 | max-width: 16.666667%; 539 | } 540 | 541 | .col-md-3 { 542 | -ms-flex: 0 0 25%; 543 | flex: 0 0 25%; 544 | max-width: 25%; 545 | } 546 | 547 | .col-md-4 { 548 | -ms-flex: 0 0 33.333333%; 549 | flex: 0 0 33.333333%; 550 | max-width: 33.333333%; 551 | } 552 | 553 | .col-md-5 { 554 | -ms-flex: 0 0 41.666667%; 555 | flex: 0 0 41.666667%; 556 | max-width: 41.666667%; 557 | } 558 | 559 | .col-md-6 { 560 | -ms-flex: 0 0 50%; 561 | flex: 0 0 50%; 562 | max-width: 50%; 563 | } 564 | 565 | .col-md-7 { 566 | -ms-flex: 0 0 58.333333%; 567 | flex: 0 0 58.333333%; 568 | max-width: 58.333333%; 569 | } 570 | 571 | .col-md-8 { 572 | -ms-flex: 0 0 66.666667%; 573 | flex: 0 0 66.666667%; 574 | max-width: 66.666667%; 575 | } 576 | 577 | .col-md-9 { 578 | -ms-flex: 0 0 75%; 579 | flex: 0 0 75%; 580 | max-width: 75%; 581 | } 582 | 583 | .col-md-10 { 584 | -ms-flex: 0 0 83.333333%; 585 | flex: 0 0 83.333333%; 586 | max-width: 83.333333%; 587 | } 588 | 589 | .col-md-11 { 590 | -ms-flex: 0 0 91.666667%; 591 | flex: 0 0 91.666667%; 592 | max-width: 91.666667%; 593 | } 594 | 595 | .col-md-12 { 596 | -ms-flex: 0 0 100%; 597 | flex: 0 0 100%; 598 | max-width: 100%; 599 | } 600 | 601 | .order-md-first { 602 | -ms-flex-order: -1; 603 | order: -1; 604 | } 605 | 606 | .order-md-last { 607 | -ms-flex-order: 13; 608 | order: 13; 609 | } 610 | 611 | .order-md-0 { 612 | -ms-flex-order: 0; 613 | order: 0; 614 | } 615 | 616 | .order-md-1 { 617 | -ms-flex-order: 1; 618 | order: 1; 619 | } 620 | 621 | .order-md-2 { 622 | -ms-flex-order: 2; 623 | order: 2; 624 | } 625 | 626 | .order-md-3 { 627 | -ms-flex-order: 3; 628 | order: 3; 629 | } 630 | 631 | .order-md-4 { 632 | -ms-flex-order: 4; 633 | order: 4; 634 | } 635 | 636 | .order-md-5 { 637 | -ms-flex-order: 5; 638 | order: 5; 639 | } 640 | 641 | .order-md-6 { 642 | -ms-flex-order: 6; 643 | order: 6; 644 | } 645 | 646 | .order-md-7 { 647 | -ms-flex-order: 7; 648 | order: 7; 649 | } 650 | 651 | .order-md-8 { 652 | -ms-flex-order: 8; 653 | order: 8; 654 | } 655 | 656 | .order-md-9 { 657 | -ms-flex-order: 9; 658 | order: 9; 659 | } 660 | 661 | .order-md-10 { 662 | -ms-flex-order: 10; 663 | order: 10; 664 | } 665 | 666 | .order-md-11 { 667 | -ms-flex-order: 11; 668 | order: 11; 669 | } 670 | 671 | .order-md-12 { 672 | -ms-flex-order: 12; 673 | order: 12; 674 | } 675 | 676 | .offset-md-0 { 677 | margin-left: 0; 678 | } 679 | 680 | .offset-md-1 { 681 | margin-left: 8.333333%; 682 | } 683 | 684 | .offset-md-2 { 685 | margin-left: 16.666667%; 686 | } 687 | 688 | .offset-md-3 { 689 | margin-left: 25%; 690 | } 691 | 692 | .offset-md-4 { 693 | margin-left: 33.333333%; 694 | } 695 | 696 | .offset-md-5 { 697 | margin-left: 41.666667%; 698 | } 699 | 700 | .offset-md-6 { 701 | margin-left: 50%; 702 | } 703 | 704 | .offset-md-7 { 705 | margin-left: 58.333333%; 706 | } 707 | 708 | .offset-md-8 { 709 | margin-left: 66.666667%; 710 | } 711 | 712 | .offset-md-9 { 713 | margin-left: 75%; 714 | } 715 | 716 | .offset-md-10 { 717 | margin-left: 83.333333%; 718 | } 719 | 720 | .offset-md-11 { 721 | margin-left: 91.666667%; 722 | } 723 | } 724 | 725 | @media (min-width: 992px) { 726 | .col-lg { 727 | -ms-flex-preferred-size: 0; 728 | flex-basis: 0; 729 | -ms-flex-positive: 1; 730 | flex-grow: 1; 731 | max-width: 100%; 732 | } 733 | 734 | .col-lg-auto { 735 | -ms-flex: 0 0 auto; 736 | flex: 0 0 auto; 737 | width: auto; 738 | max-width: none; 739 | } 740 | 741 | .col-lg-1 { 742 | -ms-flex: 0 0 8.333333%; 743 | flex: 0 0 8.333333%; 744 | max-width: 8.333333%; 745 | } 746 | 747 | .col-lg-2 { 748 | -ms-flex: 0 0 16.666667%; 749 | flex: 0 0 16.666667%; 750 | max-width: 16.666667%; 751 | } 752 | 753 | .col-lg-3 { 754 | -ms-flex: 0 0 25%; 755 | flex: 0 0 25%; 756 | max-width: 25%; 757 | } 758 | 759 | .col-lg-4 { 760 | -ms-flex: 0 0 33.333333%; 761 | flex: 0 0 33.333333%; 762 | max-width: 33.333333%; 763 | } 764 | 765 | .col-lg-5 { 766 | -ms-flex: 0 0 41.666667%; 767 | flex: 0 0 41.666667%; 768 | max-width: 41.666667%; 769 | } 770 | 771 | .col-lg-6 { 772 | -ms-flex: 0 0 50%; 773 | flex: 0 0 50%; 774 | max-width: 50%; 775 | } 776 | 777 | .col-lg-7 { 778 | -ms-flex: 0 0 58.333333%; 779 | flex: 0 0 58.333333%; 780 | max-width: 58.333333%; 781 | } 782 | 783 | .col-lg-8 { 784 | -ms-flex: 0 0 66.666667%; 785 | flex: 0 0 66.666667%; 786 | max-width: 66.666667%; 787 | } 788 | 789 | .col-lg-9 { 790 | -ms-flex: 0 0 75%; 791 | flex: 0 0 75%; 792 | max-width: 75%; 793 | } 794 | 795 | .col-lg-10 { 796 | -ms-flex: 0 0 83.333333%; 797 | flex: 0 0 83.333333%; 798 | max-width: 83.333333%; 799 | } 800 | 801 | .col-lg-11 { 802 | -ms-flex: 0 0 91.666667%; 803 | flex: 0 0 91.666667%; 804 | max-width: 91.666667%; 805 | } 806 | 807 | .col-lg-12 { 808 | -ms-flex: 0 0 100%; 809 | flex: 0 0 100%; 810 | max-width: 100%; 811 | } 812 | 813 | .order-lg-first { 814 | -ms-flex-order: -1; 815 | order: -1; 816 | } 817 | 818 | .order-lg-last { 819 | -ms-flex-order: 13; 820 | order: 13; 821 | } 822 | 823 | .order-lg-0 { 824 | -ms-flex-order: 0; 825 | order: 0; 826 | } 827 | 828 | .order-lg-1 { 829 | -ms-flex-order: 1; 830 | order: 1; 831 | } 832 | 833 | .order-lg-2 { 834 | -ms-flex-order: 2; 835 | order: 2; 836 | } 837 | 838 | .order-lg-3 { 839 | -ms-flex-order: 3; 840 | order: 3; 841 | } 842 | 843 | .order-lg-4 { 844 | -ms-flex-order: 4; 845 | order: 4; 846 | } 847 | 848 | .order-lg-5 { 849 | -ms-flex-order: 5; 850 | order: 5; 851 | } 852 | 853 | .order-lg-6 { 854 | -ms-flex-order: 6; 855 | order: 6; 856 | } 857 | 858 | .order-lg-7 { 859 | -ms-flex-order: 7; 860 | order: 7; 861 | } 862 | 863 | .order-lg-8 { 864 | -ms-flex-order: 8; 865 | order: 8; 866 | } 867 | 868 | .order-lg-9 { 869 | -ms-flex-order: 9; 870 | order: 9; 871 | } 872 | 873 | .order-lg-10 { 874 | -ms-flex-order: 10; 875 | order: 10; 876 | } 877 | 878 | .order-lg-11 { 879 | -ms-flex-order: 11; 880 | order: 11; 881 | } 882 | 883 | .order-lg-12 { 884 | -ms-flex-order: 12; 885 | order: 12; 886 | } 887 | 888 | .offset-lg-0 { 889 | margin-left: 0; 890 | } 891 | 892 | .offset-lg-1 { 893 | margin-left: 8.333333%; 894 | } 895 | 896 | .offset-lg-2 { 897 | margin-left: 16.666667%; 898 | } 899 | 900 | .offset-lg-3 { 901 | margin-left: 25%; 902 | } 903 | 904 | .offset-lg-4 { 905 | margin-left: 33.333333%; 906 | } 907 | 908 | .offset-lg-5 { 909 | margin-left: 41.666667%; 910 | } 911 | 912 | .offset-lg-6 { 913 | margin-left: 50%; 914 | } 915 | 916 | .offset-lg-7 { 917 | margin-left: 58.333333%; 918 | } 919 | 920 | .offset-lg-8 { 921 | margin-left: 66.666667%; 922 | } 923 | 924 | .offset-lg-9 { 925 | margin-left: 75%; 926 | } 927 | 928 | .offset-lg-10 { 929 | margin-left: 83.333333%; 930 | } 931 | 932 | .offset-lg-11 { 933 | margin-left: 91.666667%; 934 | } 935 | } 936 | 937 | @media (min-width: 1200px) { 938 | .col-xl { 939 | -ms-flex-preferred-size: 0; 940 | flex-basis: 0; 941 | -ms-flex-positive: 1; 942 | flex-grow: 1; 943 | max-width: 100%; 944 | } 945 | 946 | .col-xl-auto { 947 | -ms-flex: 0 0 auto; 948 | flex: 0 0 auto; 949 | width: auto; 950 | max-width: none; 951 | } 952 | 953 | .col-xl-1 { 954 | -ms-flex: 0 0 8.333333%; 955 | flex: 0 0 8.333333%; 956 | max-width: 8.333333%; 957 | } 958 | 959 | .col-xl-2 { 960 | -ms-flex: 0 0 16.666667%; 961 | flex: 0 0 16.666667%; 962 | max-width: 16.666667%; 963 | } 964 | 965 | .col-xl-3 { 966 | -ms-flex: 0 0 25%; 967 | flex: 0 0 25%; 968 | max-width: 25%; 969 | } 970 | 971 | .col-xl-4 { 972 | -ms-flex: 0 0 33.333333%; 973 | flex: 0 0 33.333333%; 974 | max-width: 33.333333%; 975 | } 976 | 977 | .col-xl-5 { 978 | -ms-flex: 0 0 41.666667%; 979 | flex: 0 0 41.666667%; 980 | max-width: 41.666667%; 981 | } 982 | 983 | .col-xl-6 { 984 | -ms-flex: 0 0 50%; 985 | flex: 0 0 50%; 986 | max-width: 50%; 987 | } 988 | 989 | .col-xl-7 { 990 | -ms-flex: 0 0 58.333333%; 991 | flex: 0 0 58.333333%; 992 | max-width: 58.333333%; 993 | } 994 | 995 | .col-xl-8 { 996 | -ms-flex: 0 0 66.666667%; 997 | flex: 0 0 66.666667%; 998 | max-width: 66.666667%; 999 | } 1000 | 1001 | .col-xl-9 { 1002 | -ms-flex: 0 0 75%; 1003 | flex: 0 0 75%; 1004 | max-width: 75%; 1005 | } 1006 | 1007 | .col-xl-10 { 1008 | -ms-flex: 0 0 83.333333%; 1009 | flex: 0 0 83.333333%; 1010 | max-width: 83.333333%; 1011 | } 1012 | 1013 | .col-xl-11 { 1014 | -ms-flex: 0 0 91.666667%; 1015 | flex: 0 0 91.666667%; 1016 | max-width: 91.666667%; 1017 | } 1018 | 1019 | .col-xl-12 { 1020 | -ms-flex: 0 0 100%; 1021 | flex: 0 0 100%; 1022 | max-width: 100%; 1023 | } 1024 | 1025 | .order-xl-first { 1026 | -ms-flex-order: -1; 1027 | order: -1; 1028 | } 1029 | 1030 | .order-xl-last { 1031 | -ms-flex-order: 13; 1032 | order: 13; 1033 | } 1034 | 1035 | .order-xl-0 { 1036 | -ms-flex-order: 0; 1037 | order: 0; 1038 | } 1039 | 1040 | .order-xl-1 { 1041 | -ms-flex-order: 1; 1042 | order: 1; 1043 | } 1044 | 1045 | .order-xl-2 { 1046 | -ms-flex-order: 2; 1047 | order: 2; 1048 | } 1049 | 1050 | .order-xl-3 { 1051 | -ms-flex-order: 3; 1052 | order: 3; 1053 | } 1054 | 1055 | .order-xl-4 { 1056 | -ms-flex-order: 4; 1057 | order: 4; 1058 | } 1059 | 1060 | .order-xl-5 { 1061 | -ms-flex-order: 5; 1062 | order: 5; 1063 | } 1064 | 1065 | .order-xl-6 { 1066 | -ms-flex-order: 6; 1067 | order: 6; 1068 | } 1069 | 1070 | .order-xl-7 { 1071 | -ms-flex-order: 7; 1072 | order: 7; 1073 | } 1074 | 1075 | .order-xl-8 { 1076 | -ms-flex-order: 8; 1077 | order: 8; 1078 | } 1079 | 1080 | .order-xl-9 { 1081 | -ms-flex-order: 9; 1082 | order: 9; 1083 | } 1084 | 1085 | .order-xl-10 { 1086 | -ms-flex-order: 10; 1087 | order: 10; 1088 | } 1089 | 1090 | .order-xl-11 { 1091 | -ms-flex-order: 11; 1092 | order: 11; 1093 | } 1094 | 1095 | .order-xl-12 { 1096 | -ms-flex-order: 12; 1097 | order: 12; 1098 | } 1099 | 1100 | .offset-xl-0 { 1101 | margin-left: 0; 1102 | } 1103 | 1104 | .offset-xl-1 { 1105 | margin-left: 8.333333%; 1106 | } 1107 | 1108 | .offset-xl-2 { 1109 | margin-left: 16.666667%; 1110 | } 1111 | 1112 | .offset-xl-3 { 1113 | margin-left: 25%; 1114 | } 1115 | 1116 | .offset-xl-4 { 1117 | margin-left: 33.333333%; 1118 | } 1119 | 1120 | .offset-xl-5 { 1121 | margin-left: 41.666667%; 1122 | } 1123 | 1124 | .offset-xl-6 { 1125 | margin-left: 50%; 1126 | } 1127 | 1128 | .offset-xl-7 { 1129 | margin-left: 58.333333%; 1130 | } 1131 | 1132 | .offset-xl-8 { 1133 | margin-left: 66.666667%; 1134 | } 1135 | 1136 | .offset-xl-9 { 1137 | margin-left: 75%; 1138 | } 1139 | 1140 | .offset-xl-10 { 1141 | margin-left: 83.333333%; 1142 | } 1143 | 1144 | .offset-xl-11 { 1145 | margin-left: 91.666667%; 1146 | } 1147 | } 1148 | 1149 | .d-none { 1150 | display: none !important; 1151 | } 1152 | 1153 | .d-inline { 1154 | display: inline !important; 1155 | } 1156 | 1157 | .d-inline-block { 1158 | display: inline-block !important; 1159 | } 1160 | 1161 | .d-block { 1162 | display: block !important; 1163 | } 1164 | 1165 | .d-table { 1166 | display: table !important; 1167 | } 1168 | 1169 | .d-table-row { 1170 | display: table-row !important; 1171 | } 1172 | 1173 | .d-table-cell { 1174 | display: table-cell !important; 1175 | } 1176 | 1177 | .d-flex { 1178 | display: -ms-flexbox !important; 1179 | display: flex !important; 1180 | } 1181 | 1182 | .d-inline-flex { 1183 | display: -ms-inline-flexbox !important; 1184 | display: inline-flex !important; 1185 | } 1186 | 1187 | @media (min-width: 576px) { 1188 | .d-sm-none { 1189 | display: none !important; 1190 | } 1191 | 1192 | .d-sm-inline { 1193 | display: inline !important; 1194 | } 1195 | 1196 | .d-sm-inline-block { 1197 | display: inline-block !important; 1198 | } 1199 | 1200 | .d-sm-block { 1201 | display: block !important; 1202 | } 1203 | 1204 | .d-sm-table { 1205 | display: table !important; 1206 | } 1207 | 1208 | .d-sm-table-row { 1209 | display: table-row !important; 1210 | } 1211 | 1212 | .d-sm-table-cell { 1213 | display: table-cell !important; 1214 | } 1215 | 1216 | .d-sm-flex { 1217 | display: -ms-flexbox !important; 1218 | display: flex !important; 1219 | } 1220 | 1221 | .d-sm-inline-flex { 1222 | display: -ms-inline-flexbox !important; 1223 | display: inline-flex !important; 1224 | } 1225 | } 1226 | 1227 | @media (min-width: 768px) { 1228 | .d-md-none { 1229 | display: none !important; 1230 | } 1231 | 1232 | .d-md-inline { 1233 | display: inline !important; 1234 | } 1235 | 1236 | .d-md-inline-block { 1237 | display: inline-block !important; 1238 | } 1239 | 1240 | .d-md-block { 1241 | display: block !important; 1242 | } 1243 | 1244 | .d-md-table { 1245 | display: table !important; 1246 | } 1247 | 1248 | .d-md-table-row { 1249 | display: table-row !important; 1250 | } 1251 | 1252 | .d-md-table-cell { 1253 | display: table-cell !important; 1254 | } 1255 | 1256 | .d-md-flex { 1257 | display: -ms-flexbox !important; 1258 | display: flex !important; 1259 | } 1260 | 1261 | .d-md-inline-flex { 1262 | display: -ms-inline-flexbox !important; 1263 | display: inline-flex !important; 1264 | } 1265 | } 1266 | 1267 | @media (min-width: 992px) { 1268 | .d-lg-none { 1269 | display: none !important; 1270 | } 1271 | 1272 | .d-lg-inline { 1273 | display: inline !important; 1274 | } 1275 | 1276 | .d-lg-inline-block { 1277 | display: inline-block !important; 1278 | } 1279 | 1280 | .d-lg-block { 1281 | display: block !important; 1282 | } 1283 | 1284 | .d-lg-table { 1285 | display: table !important; 1286 | } 1287 | 1288 | .d-lg-table-row { 1289 | display: table-row !important; 1290 | } 1291 | 1292 | .d-lg-table-cell { 1293 | display: table-cell !important; 1294 | } 1295 | 1296 | .d-lg-flex { 1297 | display: -ms-flexbox !important; 1298 | display: flex !important; 1299 | } 1300 | 1301 | .d-lg-inline-flex { 1302 | display: -ms-inline-flexbox !important; 1303 | display: inline-flex !important; 1304 | } 1305 | } 1306 | 1307 | @media (min-width: 1200px) { 1308 | .d-xl-none { 1309 | display: none !important; 1310 | } 1311 | 1312 | .d-xl-inline { 1313 | display: inline !important; 1314 | } 1315 | 1316 | .d-xl-inline-block { 1317 | display: inline-block !important; 1318 | } 1319 | 1320 | .d-xl-block { 1321 | display: block !important; 1322 | } 1323 | 1324 | .d-xl-table { 1325 | display: table !important; 1326 | } 1327 | 1328 | .d-xl-table-row { 1329 | display: table-row !important; 1330 | } 1331 | 1332 | .d-xl-table-cell { 1333 | display: table-cell !important; 1334 | } 1335 | 1336 | .d-xl-flex { 1337 | display: -ms-flexbox !important; 1338 | display: flex !important; 1339 | } 1340 | 1341 | .d-xl-inline-flex { 1342 | display: -ms-inline-flexbox !important; 1343 | display: inline-flex !important; 1344 | } 1345 | } 1346 | 1347 | @media print { 1348 | .d-print-none { 1349 | display: none !important; 1350 | } 1351 | 1352 | .d-print-inline { 1353 | display: inline !important; 1354 | } 1355 | 1356 | .d-print-inline-block { 1357 | display: inline-block !important; 1358 | } 1359 | 1360 | .d-print-block { 1361 | display: block !important; 1362 | } 1363 | 1364 | .d-print-table { 1365 | display: table !important; 1366 | } 1367 | 1368 | .d-print-table-row { 1369 | display: table-row !important; 1370 | } 1371 | 1372 | .d-print-table-cell { 1373 | display: table-cell !important; 1374 | } 1375 | 1376 | .d-print-flex { 1377 | display: -ms-flexbox !important; 1378 | display: flex !important; 1379 | } 1380 | 1381 | .d-print-inline-flex { 1382 | display: -ms-inline-flexbox !important; 1383 | display: inline-flex !important; 1384 | } 1385 | } 1386 | 1387 | .flex-row { 1388 | -ms-flex-direction: row !important; 1389 | flex-direction: row !important; 1390 | } 1391 | 1392 | .flex-column { 1393 | -ms-flex-direction: column !important; 1394 | flex-direction: column !important; 1395 | } 1396 | 1397 | .flex-row-reverse { 1398 | -ms-flex-direction: row-reverse !important; 1399 | flex-direction: row-reverse !important; 1400 | } 1401 | 1402 | .flex-column-reverse { 1403 | -ms-flex-direction: column-reverse !important; 1404 | flex-direction: column-reverse !important; 1405 | } 1406 | 1407 | .flex-wrap { 1408 | -ms-flex-wrap: wrap !important; 1409 | flex-wrap: wrap !important; 1410 | } 1411 | 1412 | .flex-nowrap { 1413 | -ms-flex-wrap: nowrap !important; 1414 | flex-wrap: nowrap !important; 1415 | } 1416 | 1417 | .flex-wrap-reverse { 1418 | -ms-flex-wrap: wrap-reverse !important; 1419 | flex-wrap: wrap-reverse !important; 1420 | } 1421 | 1422 | .flex-fill { 1423 | -ms-flex: 1 1 auto !important; 1424 | flex: 1 1 auto !important; 1425 | } 1426 | 1427 | .flex-grow-0 { 1428 | -ms-flex-positive: 0 !important; 1429 | flex-grow: 0 !important; 1430 | } 1431 | 1432 | .flex-grow-1 { 1433 | -ms-flex-positive: 1 !important; 1434 | flex-grow: 1 !important; 1435 | } 1436 | 1437 | .flex-shrink-0 { 1438 | -ms-flex-negative: 0 !important; 1439 | flex-shrink: 0 !important; 1440 | } 1441 | 1442 | .flex-shrink-1 { 1443 | -ms-flex-negative: 1 !important; 1444 | flex-shrink: 1 !important; 1445 | } 1446 | 1447 | .justify-content-start { 1448 | -ms-flex-pack: start !important; 1449 | justify-content: flex-start !important; 1450 | } 1451 | 1452 | .justify-content-end { 1453 | -ms-flex-pack: end !important; 1454 | justify-content: flex-end !important; 1455 | } 1456 | 1457 | .justify-content-center { 1458 | -ms-flex-pack: center !important; 1459 | justify-content: center !important; 1460 | } 1461 | 1462 | .justify-content-between { 1463 | -ms-flex-pack: justify !important; 1464 | justify-content: space-between !important; 1465 | } 1466 | 1467 | .justify-content-around { 1468 | -ms-flex-pack: distribute !important; 1469 | justify-content: space-around !important; 1470 | } 1471 | 1472 | .align-items-start { 1473 | -ms-flex-align: start !important; 1474 | align-items: flex-start !important; 1475 | } 1476 | 1477 | .align-items-end { 1478 | -ms-flex-align: end !important; 1479 | align-items: flex-end !important; 1480 | } 1481 | 1482 | .align-items-center { 1483 | -ms-flex-align: center !important; 1484 | align-items: center !important; 1485 | } 1486 | 1487 | .align-items-baseline { 1488 | -ms-flex-align: baseline !important; 1489 | align-items: baseline !important; 1490 | } 1491 | 1492 | .align-items-stretch { 1493 | -ms-flex-align: stretch !important; 1494 | align-items: stretch !important; 1495 | } 1496 | 1497 | .align-content-start { 1498 | -ms-flex-line-pack: start !important; 1499 | align-content: flex-start !important; 1500 | } 1501 | 1502 | .align-content-end { 1503 | -ms-flex-line-pack: end !important; 1504 | align-content: flex-end !important; 1505 | } 1506 | 1507 | .align-content-center { 1508 | -ms-flex-line-pack: center !important; 1509 | align-content: center !important; 1510 | } 1511 | 1512 | .align-content-between { 1513 | -ms-flex-line-pack: justify !important; 1514 | align-content: space-between !important; 1515 | } 1516 | 1517 | .align-content-around { 1518 | -ms-flex-line-pack: distribute !important; 1519 | align-content: space-around !important; 1520 | } 1521 | 1522 | .align-content-stretch { 1523 | -ms-flex-line-pack: stretch !important; 1524 | align-content: stretch !important; 1525 | } 1526 | 1527 | .align-self-auto { 1528 | -ms-flex-item-align: auto !important; 1529 | align-self: auto !important; 1530 | } 1531 | 1532 | .align-self-start { 1533 | -ms-flex-item-align: start !important; 1534 | align-self: flex-start !important; 1535 | } 1536 | 1537 | .align-self-end { 1538 | -ms-flex-item-align: end !important; 1539 | align-self: flex-end !important; 1540 | } 1541 | 1542 | .align-self-center { 1543 | -ms-flex-item-align: center !important; 1544 | align-self: center !important; 1545 | } 1546 | 1547 | .align-self-baseline { 1548 | -ms-flex-item-align: baseline !important; 1549 | align-self: baseline !important; 1550 | } 1551 | 1552 | .align-self-stretch { 1553 | -ms-flex-item-align: stretch !important; 1554 | align-self: stretch !important; 1555 | } 1556 | 1557 | @media (min-width: 576px) { 1558 | .flex-sm-row { 1559 | -ms-flex-direction: row !important; 1560 | flex-direction: row !important; 1561 | } 1562 | 1563 | .flex-sm-column { 1564 | -ms-flex-direction: column !important; 1565 | flex-direction: column !important; 1566 | } 1567 | 1568 | .flex-sm-row-reverse { 1569 | -ms-flex-direction: row-reverse !important; 1570 | flex-direction: row-reverse !important; 1571 | } 1572 | 1573 | .flex-sm-column-reverse { 1574 | -ms-flex-direction: column-reverse !important; 1575 | flex-direction: column-reverse !important; 1576 | } 1577 | 1578 | .flex-sm-wrap { 1579 | -ms-flex-wrap: wrap !important; 1580 | flex-wrap: wrap !important; 1581 | } 1582 | 1583 | .flex-sm-nowrap { 1584 | -ms-flex-wrap: nowrap !important; 1585 | flex-wrap: nowrap !important; 1586 | } 1587 | 1588 | .flex-sm-wrap-reverse { 1589 | -ms-flex-wrap: wrap-reverse !important; 1590 | flex-wrap: wrap-reverse !important; 1591 | } 1592 | 1593 | .flex-sm-fill { 1594 | -ms-flex: 1 1 auto !important; 1595 | flex: 1 1 auto !important; 1596 | } 1597 | 1598 | .flex-sm-grow-0 { 1599 | -ms-flex-positive: 0 !important; 1600 | flex-grow: 0 !important; 1601 | } 1602 | 1603 | .flex-sm-grow-1 { 1604 | -ms-flex-positive: 1 !important; 1605 | flex-grow: 1 !important; 1606 | } 1607 | 1608 | .flex-sm-shrink-0 { 1609 | -ms-flex-negative: 0 !important; 1610 | flex-shrink: 0 !important; 1611 | } 1612 | 1613 | .flex-sm-shrink-1 { 1614 | -ms-flex-negative: 1 !important; 1615 | flex-shrink: 1 !important; 1616 | } 1617 | 1618 | .justify-content-sm-start { 1619 | -ms-flex-pack: start !important; 1620 | justify-content: flex-start !important; 1621 | } 1622 | 1623 | .justify-content-sm-end { 1624 | -ms-flex-pack: end !important; 1625 | justify-content: flex-end !important; 1626 | } 1627 | 1628 | .justify-content-sm-center { 1629 | -ms-flex-pack: center !important; 1630 | justify-content: center !important; 1631 | } 1632 | 1633 | .justify-content-sm-between { 1634 | -ms-flex-pack: justify !important; 1635 | justify-content: space-between !important; 1636 | } 1637 | 1638 | .justify-content-sm-around { 1639 | -ms-flex-pack: distribute !important; 1640 | justify-content: space-around !important; 1641 | } 1642 | 1643 | .align-items-sm-start { 1644 | -ms-flex-align: start !important; 1645 | align-items: flex-start !important; 1646 | } 1647 | 1648 | .align-items-sm-end { 1649 | -ms-flex-align: end !important; 1650 | align-items: flex-end !important; 1651 | } 1652 | 1653 | .align-items-sm-center { 1654 | -ms-flex-align: center !important; 1655 | align-items: center !important; 1656 | } 1657 | 1658 | .align-items-sm-baseline { 1659 | -ms-flex-align: baseline !important; 1660 | align-items: baseline !important; 1661 | } 1662 | 1663 | .align-items-sm-stretch { 1664 | -ms-flex-align: stretch !important; 1665 | align-items: stretch !important; 1666 | } 1667 | 1668 | .align-content-sm-start { 1669 | -ms-flex-line-pack: start !important; 1670 | align-content: flex-start !important; 1671 | } 1672 | 1673 | .align-content-sm-end { 1674 | -ms-flex-line-pack: end !important; 1675 | align-content: flex-end !important; 1676 | } 1677 | 1678 | .align-content-sm-center { 1679 | -ms-flex-line-pack: center !important; 1680 | align-content: center !important; 1681 | } 1682 | 1683 | .align-content-sm-between { 1684 | -ms-flex-line-pack: justify !important; 1685 | align-content: space-between !important; 1686 | } 1687 | 1688 | .align-content-sm-around { 1689 | -ms-flex-line-pack: distribute !important; 1690 | align-content: space-around !important; 1691 | } 1692 | 1693 | .align-content-sm-stretch { 1694 | -ms-flex-line-pack: stretch !important; 1695 | align-content: stretch !important; 1696 | } 1697 | 1698 | .align-self-sm-auto { 1699 | -ms-flex-item-align: auto !important; 1700 | align-self: auto !important; 1701 | } 1702 | 1703 | .align-self-sm-start { 1704 | -ms-flex-item-align: start !important; 1705 | align-self: flex-start !important; 1706 | } 1707 | 1708 | .align-self-sm-end { 1709 | -ms-flex-item-align: end !important; 1710 | align-self: flex-end !important; 1711 | } 1712 | 1713 | .align-self-sm-center { 1714 | -ms-flex-item-align: center !important; 1715 | align-self: center !important; 1716 | } 1717 | 1718 | .align-self-sm-baseline { 1719 | -ms-flex-item-align: baseline !important; 1720 | align-self: baseline !important; 1721 | } 1722 | 1723 | .align-self-sm-stretch { 1724 | -ms-flex-item-align: stretch !important; 1725 | align-self: stretch !important; 1726 | } 1727 | } 1728 | 1729 | @media (min-width: 768px) { 1730 | .flex-md-row { 1731 | -ms-flex-direction: row !important; 1732 | flex-direction: row !important; 1733 | } 1734 | 1735 | .flex-md-column { 1736 | -ms-flex-direction: column !important; 1737 | flex-direction: column !important; 1738 | } 1739 | 1740 | .flex-md-row-reverse { 1741 | -ms-flex-direction: row-reverse !important; 1742 | flex-direction: row-reverse !important; 1743 | } 1744 | 1745 | .flex-md-column-reverse { 1746 | -ms-flex-direction: column-reverse !important; 1747 | flex-direction: column-reverse !important; 1748 | } 1749 | 1750 | .flex-md-wrap { 1751 | -ms-flex-wrap: wrap !important; 1752 | flex-wrap: wrap !important; 1753 | } 1754 | 1755 | .flex-md-nowrap { 1756 | -ms-flex-wrap: nowrap !important; 1757 | flex-wrap: nowrap !important; 1758 | } 1759 | 1760 | .flex-md-wrap-reverse { 1761 | -ms-flex-wrap: wrap-reverse !important; 1762 | flex-wrap: wrap-reverse !important; 1763 | } 1764 | 1765 | .flex-md-fill { 1766 | -ms-flex: 1 1 auto !important; 1767 | flex: 1 1 auto !important; 1768 | } 1769 | 1770 | .flex-md-grow-0 { 1771 | -ms-flex-positive: 0 !important; 1772 | flex-grow: 0 !important; 1773 | } 1774 | 1775 | .flex-md-grow-1 { 1776 | -ms-flex-positive: 1 !important; 1777 | flex-grow: 1 !important; 1778 | } 1779 | 1780 | .flex-md-shrink-0 { 1781 | -ms-flex-negative: 0 !important; 1782 | flex-shrink: 0 !important; 1783 | } 1784 | 1785 | .flex-md-shrink-1 { 1786 | -ms-flex-negative: 1 !important; 1787 | flex-shrink: 1 !important; 1788 | } 1789 | 1790 | .justify-content-md-start { 1791 | -ms-flex-pack: start !important; 1792 | justify-content: flex-start !important; 1793 | } 1794 | 1795 | .justify-content-md-end { 1796 | -ms-flex-pack: end !important; 1797 | justify-content: flex-end !important; 1798 | } 1799 | 1800 | .justify-content-md-center { 1801 | -ms-flex-pack: center !important; 1802 | justify-content: center !important; 1803 | } 1804 | 1805 | .justify-content-md-between { 1806 | -ms-flex-pack: justify !important; 1807 | justify-content: space-between !important; 1808 | } 1809 | 1810 | .justify-content-md-around { 1811 | -ms-flex-pack: distribute !important; 1812 | justify-content: space-around !important; 1813 | } 1814 | 1815 | .align-items-md-start { 1816 | -ms-flex-align: start !important; 1817 | align-items: flex-start !important; 1818 | } 1819 | 1820 | .align-items-md-end { 1821 | -ms-flex-align: end !important; 1822 | align-items: flex-end !important; 1823 | } 1824 | 1825 | .align-items-md-center { 1826 | -ms-flex-align: center !important; 1827 | align-items: center !important; 1828 | } 1829 | 1830 | .align-items-md-baseline { 1831 | -ms-flex-align: baseline !important; 1832 | align-items: baseline !important; 1833 | } 1834 | 1835 | .align-items-md-stretch { 1836 | -ms-flex-align: stretch !important; 1837 | align-items: stretch !important; 1838 | } 1839 | 1840 | .align-content-md-start { 1841 | -ms-flex-line-pack: start !important; 1842 | align-content: flex-start !important; 1843 | } 1844 | 1845 | .align-content-md-end { 1846 | -ms-flex-line-pack: end !important; 1847 | align-content: flex-end !important; 1848 | } 1849 | 1850 | .align-content-md-center { 1851 | -ms-flex-line-pack: center !important; 1852 | align-content: center !important; 1853 | } 1854 | 1855 | .align-content-md-between { 1856 | -ms-flex-line-pack: justify !important; 1857 | align-content: space-between !important; 1858 | } 1859 | 1860 | .align-content-md-around { 1861 | -ms-flex-line-pack: distribute !important; 1862 | align-content: space-around !important; 1863 | } 1864 | 1865 | .align-content-md-stretch { 1866 | -ms-flex-line-pack: stretch !important; 1867 | align-content: stretch !important; 1868 | } 1869 | 1870 | .align-self-md-auto { 1871 | -ms-flex-item-align: auto !important; 1872 | align-self: auto !important; 1873 | } 1874 | 1875 | .align-self-md-start { 1876 | -ms-flex-item-align: start !important; 1877 | align-self: flex-start !important; 1878 | } 1879 | 1880 | .align-self-md-end { 1881 | -ms-flex-item-align: end !important; 1882 | align-self: flex-end !important; 1883 | } 1884 | 1885 | .align-self-md-center { 1886 | -ms-flex-item-align: center !important; 1887 | align-self: center !important; 1888 | } 1889 | 1890 | .align-self-md-baseline { 1891 | -ms-flex-item-align: baseline !important; 1892 | align-self: baseline !important; 1893 | } 1894 | 1895 | .align-self-md-stretch { 1896 | -ms-flex-item-align: stretch !important; 1897 | align-self: stretch !important; 1898 | } 1899 | } 1900 | 1901 | @media (min-width: 992px) { 1902 | .flex-lg-row { 1903 | -ms-flex-direction: row !important; 1904 | flex-direction: row !important; 1905 | } 1906 | 1907 | .flex-lg-column { 1908 | -ms-flex-direction: column !important; 1909 | flex-direction: column !important; 1910 | } 1911 | 1912 | .flex-lg-row-reverse { 1913 | -ms-flex-direction: row-reverse !important; 1914 | flex-direction: row-reverse !important; 1915 | } 1916 | 1917 | .flex-lg-column-reverse { 1918 | -ms-flex-direction: column-reverse !important; 1919 | flex-direction: column-reverse !important; 1920 | } 1921 | 1922 | .flex-lg-wrap { 1923 | -ms-flex-wrap: wrap !important; 1924 | flex-wrap: wrap !important; 1925 | } 1926 | 1927 | .flex-lg-nowrap { 1928 | -ms-flex-wrap: nowrap !important; 1929 | flex-wrap: nowrap !important; 1930 | } 1931 | 1932 | .flex-lg-wrap-reverse { 1933 | -ms-flex-wrap: wrap-reverse !important; 1934 | flex-wrap: wrap-reverse !important; 1935 | } 1936 | 1937 | .flex-lg-fill { 1938 | -ms-flex: 1 1 auto !important; 1939 | flex: 1 1 auto !important; 1940 | } 1941 | 1942 | .flex-lg-grow-0 { 1943 | -ms-flex-positive: 0 !important; 1944 | flex-grow: 0 !important; 1945 | } 1946 | 1947 | .flex-lg-grow-1 { 1948 | -ms-flex-positive: 1 !important; 1949 | flex-grow: 1 !important; 1950 | } 1951 | 1952 | .flex-lg-shrink-0 { 1953 | -ms-flex-negative: 0 !important; 1954 | flex-shrink: 0 !important; 1955 | } 1956 | 1957 | .flex-lg-shrink-1 { 1958 | -ms-flex-negative: 1 !important; 1959 | flex-shrink: 1 !important; 1960 | } 1961 | 1962 | .justify-content-lg-start { 1963 | -ms-flex-pack: start !important; 1964 | justify-content: flex-start !important; 1965 | } 1966 | 1967 | .justify-content-lg-end { 1968 | -ms-flex-pack: end !important; 1969 | justify-content: flex-end !important; 1970 | } 1971 | 1972 | .justify-content-lg-center { 1973 | -ms-flex-pack: center !important; 1974 | justify-content: center !important; 1975 | } 1976 | 1977 | .justify-content-lg-between { 1978 | -ms-flex-pack: justify !important; 1979 | justify-content: space-between !important; 1980 | } 1981 | 1982 | .justify-content-lg-around { 1983 | -ms-flex-pack: distribute !important; 1984 | justify-content: space-around !important; 1985 | } 1986 | 1987 | .align-items-lg-start { 1988 | -ms-flex-align: start !important; 1989 | align-items: flex-start !important; 1990 | } 1991 | 1992 | .align-items-lg-end { 1993 | -ms-flex-align: end !important; 1994 | align-items: flex-end !important; 1995 | } 1996 | 1997 | .align-items-lg-center { 1998 | -ms-flex-align: center !important; 1999 | align-items: center !important; 2000 | } 2001 | 2002 | .align-items-lg-baseline { 2003 | -ms-flex-align: baseline !important; 2004 | align-items: baseline !important; 2005 | } 2006 | 2007 | .align-items-lg-stretch { 2008 | -ms-flex-align: stretch !important; 2009 | align-items: stretch !important; 2010 | } 2011 | 2012 | .align-content-lg-start { 2013 | -ms-flex-line-pack: start !important; 2014 | align-content: flex-start !important; 2015 | } 2016 | 2017 | .align-content-lg-end { 2018 | -ms-flex-line-pack: end !important; 2019 | align-content: flex-end !important; 2020 | } 2021 | 2022 | .align-content-lg-center { 2023 | -ms-flex-line-pack: center !important; 2024 | align-content: center !important; 2025 | } 2026 | 2027 | .align-content-lg-between { 2028 | -ms-flex-line-pack: justify !important; 2029 | align-content: space-between !important; 2030 | } 2031 | 2032 | .align-content-lg-around { 2033 | -ms-flex-line-pack: distribute !important; 2034 | align-content: space-around !important; 2035 | } 2036 | 2037 | .align-content-lg-stretch { 2038 | -ms-flex-line-pack: stretch !important; 2039 | align-content: stretch !important; 2040 | } 2041 | 2042 | .align-self-lg-auto { 2043 | -ms-flex-item-align: auto !important; 2044 | align-self: auto !important; 2045 | } 2046 | 2047 | .align-self-lg-start { 2048 | -ms-flex-item-align: start !important; 2049 | align-self: flex-start !important; 2050 | } 2051 | 2052 | .align-self-lg-end { 2053 | -ms-flex-item-align: end !important; 2054 | align-self: flex-end !important; 2055 | } 2056 | 2057 | .align-self-lg-center { 2058 | -ms-flex-item-align: center !important; 2059 | align-self: center !important; 2060 | } 2061 | 2062 | .align-self-lg-baseline { 2063 | -ms-flex-item-align: baseline !important; 2064 | align-self: baseline !important; 2065 | } 2066 | 2067 | .align-self-lg-stretch { 2068 | -ms-flex-item-align: stretch !important; 2069 | align-self: stretch !important; 2070 | } 2071 | } 2072 | 2073 | @media (min-width: 1200px) { 2074 | .flex-xl-row { 2075 | -ms-flex-direction: row !important; 2076 | flex-direction: row !important; 2077 | } 2078 | 2079 | .flex-xl-column { 2080 | -ms-flex-direction: column !important; 2081 | flex-direction: column !important; 2082 | } 2083 | 2084 | .flex-xl-row-reverse { 2085 | -ms-flex-direction: row-reverse !important; 2086 | flex-direction: row-reverse !important; 2087 | } 2088 | 2089 | .flex-xl-column-reverse { 2090 | -ms-flex-direction: column-reverse !important; 2091 | flex-direction: column-reverse !important; 2092 | } 2093 | 2094 | .flex-xl-wrap { 2095 | -ms-flex-wrap: wrap !important; 2096 | flex-wrap: wrap !important; 2097 | } 2098 | 2099 | .flex-xl-nowrap { 2100 | -ms-flex-wrap: nowrap !important; 2101 | flex-wrap: nowrap !important; 2102 | } 2103 | 2104 | .flex-xl-wrap-reverse { 2105 | -ms-flex-wrap: wrap-reverse !important; 2106 | flex-wrap: wrap-reverse !important; 2107 | } 2108 | 2109 | .flex-xl-fill { 2110 | -ms-flex: 1 1 auto !important; 2111 | flex: 1 1 auto !important; 2112 | } 2113 | 2114 | .flex-xl-grow-0 { 2115 | -ms-flex-positive: 0 !important; 2116 | flex-grow: 0 !important; 2117 | } 2118 | 2119 | .flex-xl-grow-1 { 2120 | -ms-flex-positive: 1 !important; 2121 | flex-grow: 1 !important; 2122 | } 2123 | 2124 | .flex-xl-shrink-0 { 2125 | -ms-flex-negative: 0 !important; 2126 | flex-shrink: 0 !important; 2127 | } 2128 | 2129 | .flex-xl-shrink-1 { 2130 | -ms-flex-negative: 1 !important; 2131 | flex-shrink: 1 !important; 2132 | } 2133 | 2134 | .justify-content-xl-start { 2135 | -ms-flex-pack: start !important; 2136 | justify-content: flex-start !important; 2137 | } 2138 | 2139 | .justify-content-xl-end { 2140 | -ms-flex-pack: end !important; 2141 | justify-content: flex-end !important; 2142 | } 2143 | 2144 | .justify-content-xl-center { 2145 | -ms-flex-pack: center !important; 2146 | justify-content: center !important; 2147 | } 2148 | 2149 | .justify-content-xl-between { 2150 | -ms-flex-pack: justify !important; 2151 | justify-content: space-between !important; 2152 | } 2153 | 2154 | .justify-content-xl-around { 2155 | -ms-flex-pack: distribute !important; 2156 | justify-content: space-around !important; 2157 | } 2158 | 2159 | .align-items-xl-start { 2160 | -ms-flex-align: start !important; 2161 | align-items: flex-start !important; 2162 | } 2163 | 2164 | .align-items-xl-end { 2165 | -ms-flex-align: end !important; 2166 | align-items: flex-end !important; 2167 | } 2168 | 2169 | .align-items-xl-center { 2170 | -ms-flex-align: center !important; 2171 | align-items: center !important; 2172 | } 2173 | 2174 | .align-items-xl-baseline { 2175 | -ms-flex-align: baseline !important; 2176 | align-items: baseline !important; 2177 | } 2178 | 2179 | .align-items-xl-stretch { 2180 | -ms-flex-align: stretch !important; 2181 | align-items: stretch !important; 2182 | } 2183 | 2184 | .align-content-xl-start { 2185 | -ms-flex-line-pack: start !important; 2186 | align-content: flex-start !important; 2187 | } 2188 | 2189 | .align-content-xl-end { 2190 | -ms-flex-line-pack: end !important; 2191 | align-content: flex-end !important; 2192 | } 2193 | 2194 | .align-content-xl-center { 2195 | -ms-flex-line-pack: center !important; 2196 | align-content: center !important; 2197 | } 2198 | 2199 | .align-content-xl-between { 2200 | -ms-flex-line-pack: justify !important; 2201 | align-content: space-between !important; 2202 | } 2203 | 2204 | .align-content-xl-around { 2205 | -ms-flex-line-pack: distribute !important; 2206 | align-content: space-around !important; 2207 | } 2208 | 2209 | .align-content-xl-stretch { 2210 | -ms-flex-line-pack: stretch !important; 2211 | align-content: stretch !important; 2212 | } 2213 | 2214 | .align-self-xl-auto { 2215 | -ms-flex-item-align: auto !important; 2216 | align-self: auto !important; 2217 | } 2218 | 2219 | .align-self-xl-start { 2220 | -ms-flex-item-align: start !important; 2221 | align-self: flex-start !important; 2222 | } 2223 | 2224 | .align-self-xl-end { 2225 | -ms-flex-item-align: end !important; 2226 | align-self: flex-end !important; 2227 | } 2228 | 2229 | .align-self-xl-center { 2230 | -ms-flex-item-align: center !important; 2231 | align-self: center !important; 2232 | } 2233 | 2234 | .align-self-xl-baseline { 2235 | -ms-flex-item-align: baseline !important; 2236 | align-self: baseline !important; 2237 | } 2238 | 2239 | .align-self-xl-stretch { 2240 | -ms-flex-item-align: stretch !important; 2241 | align-self: stretch !important; 2242 | } 2243 | } --------------------------------------------------------------------------------