mirror of
https://github.com/MontFerret/ferret.git
synced 2025-01-16 03:21:03 +02:00
Feature/#44 e2e tests (#122)
This commit is contained in:
parent
0f3128e842
commit
2bb67f6a90
32
.travis.yml
32
.travis.yml
@ -6,7 +6,6 @@ os:
|
||||
- linux
|
||||
|
||||
go:
|
||||
- "1.9"
|
||||
- "1.10"
|
||||
- "1.11"
|
||||
- master
|
||||
@ -15,6 +14,7 @@ addons:
|
||||
apt:
|
||||
packages:
|
||||
- oracle-java8-set-default
|
||||
chrome: stable
|
||||
|
||||
before_install:
|
||||
- curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||
@ -27,5 +27,31 @@ before_install:
|
||||
- chmod +x $HOME/travis-bin/*
|
||||
- export PATH=$PATH:$HOME/travis-bin
|
||||
|
||||
script:
|
||||
- revive -config revive.toml -formatter friendly -exclude ./pkg/parser/fql/... -exclude ./vendor/... ./...
|
||||
install:
|
||||
- make install
|
||||
|
||||
stages:
|
||||
- lint
|
||||
- compile
|
||||
- test
|
||||
- e2e
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: lint
|
||||
script:
|
||||
- make vet
|
||||
- make lint
|
||||
- stage: compile
|
||||
script:
|
||||
- make generate
|
||||
- make compile
|
||||
- stage: test
|
||||
script: make test
|
||||
- stage: e2e
|
||||
script:
|
||||
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 --disable-setuid-sandbox --no-sandbox about:blank &
|
||||
- make e2e
|
||||
|
||||
after_script:
|
||||
- killall google-chrome-stable
|
71
Gopkg.lock
generated
71
Gopkg.lock
generated
@ -73,6 +73,25 @@
|
||||
revision = "77f18212c9c7edc9bd6a33d383a7b545ce62f064"
|
||||
version = "v4.2.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:63801c64679bdeef1b63206f065d5a1f4c3a75ed66a3fbbd909bf98766542980"
|
||||
name = "github.com/labstack/echo"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "1abaa3049251d17932e4313c2d6165073fd07fd8"
|
||||
version = "v3.3.6"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:faee5b9f53eb1ae4eb04708c040c8c4dd685ce46509671e57a08520a15c54368"
|
||||
name = "github.com/labstack/gommon"
|
||||
packages = [
|
||||
"color",
|
||||
"log",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "2a618302b929cc20862dda3aa6f02f64dbe740dd"
|
||||
version = "v0.2.7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7ffdd69928c5153fc351132aa80bbcc18a8f8122de1ba592cf42dccb65732361"
|
||||
name = "github.com/mafredri/cdp"
|
||||
@ -129,6 +148,22 @@
|
||||
revision = "75b0ecc5efcff27ac756a33ec71f0db75dc3d21c"
|
||||
version = "v0.19.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
|
||||
version = "v0.0.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c805e517269b0ba4c21ded5836019ed7d16953d4026cb7d00041d039c7906be9"
|
||||
name = "github.com/natefinch/lumberjack"
|
||||
@ -189,6 +224,33 @@
|
||||
revision = "9e8dc3f972df6c8fcc0375ef492c24d0bb204857"
|
||||
version = "1.6.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c468422f334a6b46a19448ad59aaffdfc0a36b08fdcc1c749a0b29b6453d7e59"
|
||||
name = "github.com/valyala/bytebufferpool"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:268b8bce0064e8c057d7b913605459f9a26dcab864c0886a56d196540fbf003f"
|
||||
name = "github.com/valyala/fasttemplate"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:dedf20eb0d3e8d6aa8a4d3d2fae248222b688ed528201995e152cc497899123c"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"acme",
|
||||
"acme/autocert",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a92615f3c49003920a58dedcf32cf55022cefb8d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:24641a15105cc4281b8a4a701ac4019194618102c327b1495485b3f19ffdd53e"
|
||||
@ -209,6 +271,14 @@
|
||||
pruneopts = "UT"
|
||||
revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0a40b0bdd57a93e741d8557465be3a2edeec408e9b6399586ad65bbe8e355796"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
pruneopts = "UT"
|
||||
revision = "fa43e7bc11baaae89f3f902b2b4d832b68234844"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
@ -218,6 +288,7 @@
|
||||
"github.com/chzyer/readline",
|
||||
"github.com/corpix/uarand",
|
||||
"github.com/gofrs/uuid",
|
||||
"github.com/labstack/echo",
|
||||
"github.com/mafredri/cdp",
|
||||
"github.com/mafredri/cdp/devtool",
|
||||
"github.com/mafredri/cdp/protocol/dom",
|
||||
|
6
Makefile
6
Makefile
@ -1,4 +1,4 @@
|
||||
.PHONY: build install test doc fmt lint vet
|
||||
.PHONY: build compile install test e2e doc fmt lint vet release
|
||||
|
||||
export GOPATH
|
||||
|
||||
@ -6,6 +6,7 @@ VERSION ?= $(shell git describe --tags --always --dirty)
|
||||
DIR_BIN = ./bin
|
||||
DIR_PKG = ./pkg
|
||||
DIR_CLI = ./cli
|
||||
DIR_E2E = ./e2e
|
||||
|
||||
default: build
|
||||
|
||||
@ -22,6 +23,9 @@ install:
|
||||
test:
|
||||
go test ${DIR_PKG}/...
|
||||
|
||||
e2e:
|
||||
go run ${DIR_E2E}/main.go --tests ${DIR_E2E}/tests --pages ${DIR_E2E}/pages
|
||||
|
||||
generate:
|
||||
go generate ${DIR_PKG}/...
|
||||
|
||||
|
88
e2e/main.go
Normal file
88
e2e/main.go
Normal file
@ -0,0 +1,88 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/MontFerret/ferret/e2e/runner"
|
||||
"github.com/MontFerret/ferret/e2e/server"
|
||||
"github.com/rs/zerolog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
testsDir = flag.String(
|
||||
"tests",
|
||||
"./tests",
|
||||
"root directory with test scripts",
|
||||
)
|
||||
|
||||
pagesDir = flag.String(
|
||||
"pages",
|
||||
"./pages",
|
||||
"root directory with test pages",
|
||||
)
|
||||
|
||||
port = flag.Uint64(
|
||||
"port",
|
||||
8080,
|
||||
"server port",
|
||||
)
|
||||
|
||||
cdp = flag.String(
|
||||
"cdp",
|
||||
"http://0.0.0.0:9222",
|
||||
"address of remote Chrome instance",
|
||||
)
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
logger := zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr})
|
||||
|
||||
s := server.New(server.Settings{
|
||||
Port: *port,
|
||||
Dir: *pagesDir,
|
||||
})
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
go func() {
|
||||
if err := s.Start(); err != nil {
|
||||
logger.Info().Timestamp().Msg("shutting down the server")
|
||||
}
|
||||
}()
|
||||
|
||||
dirname := *testsDir
|
||||
|
||||
if dirname == "" {
|
||||
d, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
|
||||
if err != nil {
|
||||
logger.Fatal().Timestamp().Err(err).Msg("failed to get testsDir")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
dirname = d
|
||||
}
|
||||
|
||||
r := runner.New(logger, runner.Settings{
|
||||
ServerAddress: fmt.Sprintf("http://0.0.0.0:%d", *port),
|
||||
CDPAddress: *cdp,
|
||||
Dir: *testsDir,
|
||||
})
|
||||
|
||||
err := r.Run()
|
||||
|
||||
if err := s.Stop(ctx); err != nil {
|
||||
logger.Fatal().Timestamp().Err(err).Msg("failed to stop server")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
73
e2e/pages/bootstrap/assets/analytics.js
Normal file
73
e2e/pages/bootstrap/assets/analytics.js
Normal file
@ -0,0 +1,73 @@
|
||||
(function(){function La(a){var b=1,c;if(a)for(b=0,c=a.length-1;0<=c;c--){var d=a.charCodeAt(c);b=(b<<6&268435455)+d+(d<<14);d=b&266338304;b=0!=d?b^d>>21:b}return b};(function(){function a(){for(var a=te,b={},c=0;c<a.length;++c)b[a[c]]=c;return b}function b(){var a="ABCDEFGHIJKLMNOPQRSTUVWXYZ";a+=a.toLowerCase()+"0123456789-_";return a+"."}function c(a,b){if(!a||b===He.location.hostname)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof RegExp){if(a[c].test(b))return!0}else if(0<=b.indexOf(a[c]))return!0;return!1}function d(a){var b=ze.exec(a);if(b){var c=b[2],d=b[4];a=b[1];d&&(a=a+c+d)}return a}function e(a,b,c){function e(a){a=d(a);var b=a.charAt(a.length-
|
||||
1);a&&"&"!==b&&(a+="&");return a+Fe}c=void 0===c?!1:c;var Ee=we.exec(b);if(!Ee)return"";b=Ee[1];var g=Ee[2]||"";Ee=Ee[3]||"";var Fe="_gl="+a;c?Ee="#"+e(Ee.substring(1)):g="?"+e(g.substring(1));return""+b+g+Ee}function g(a,b,d){for(var e={},Ee={},g=Me().va,Fe=0;Fe<g.length;++Fe){var Te=g[Fe];(!d||Te.forms)&&c(Te.Aa,b)&&(Te.ea?ue(Ee,Te.za()):ue(e,Te.za()))}Ge(e)&&(b=Qe(e),d?l(b,a):ca(b,a,!1));!d&&Ge(Ee)&&(d=Qe(Ee),ca(d,a,!0))}function ca(a,b,c){b.href&&(a=e(a,b.href,void 0===c?!1:c),ye.test(a)&&(b.href=
|
||||
a))}function l(a,b){if(b&&b.action){var c=(b.method||"").toLowerCase();if("get"===c){c=b.childNodes||[];for(var d=!1,Ee=0;Ee<c.length;Ee++){var g=c[Ee];if("_gl"===g.name){g.setAttribute("value",a);d=!0;break}}d||(c=He.createElement("input"),c.setAttribute("type","hidden"),c.setAttribute("name","_gl"),c.setAttribute("value",a),b.appendChild(c))}else"post"===c&&(a=e(a,b.action),ye.test(a)&&(b.action=a))}}var k=this,w=function(a,b){a=a.split(".");var c=k;a[0]in c||"undefined"==typeof c.execScript||c.execScript("var "+
|
||||
a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c=c[d]&&c[d]!==Object.prototype[d]?c[d]:c[d]={}:c[d]=b},ha=function(a){var b=[];if(Array.prototype.indexOf)return a=b.indexOf(a),"number"==typeof a?a:-1;for(var c=0;c<b.length;c++)if(b[c]===a)return c;return-1},ue=function(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])},Ge=function(a){for(var b in a)if(a.hasOwnProperty(b))return!0;return!1},ye=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i,Ie=window,He=document,Be=function(a,
|
||||
b){He.addEventListener?He.addEventListener(a,b,!1):He.attachEvent&&He.attachEvent("on"+a,b)},Ce=/:[0-9]+$/,xe=function(a,b){var c=function(a){return a?a.replace(":","").toLowerCase():""};c=c(a.protocol)||c(Ie.location.protocol);b&&(b=String(b).toLowerCase());switch(b){case "protocol":a=c;break;case "host":a=(a.hostname||Ie.location.hostname).replace(Ce,"").toLowerCase();break;case "port":a=String(Number(a.hostname?a.port:Ie.location.port)||("http"==c?80:"https"==c?443:""));break;case "path":a="/"==
|
||||
a.pathname.substr(0,1)?a.pathname:"/"+a.pathname;a=a.split("/");0<=ha(a[a.length-1])&&(a[a.length-1]="");a=a.join("/");break;case "query":a=a.search.replace("?","");break;case "extension":a=a.pathname.split(".");a=1<a.length?a[a.length-1]:"";a=a.split("/")[0];break;case "fragment":a=a.hash.replace("#","");break;default:a=a&&a.href}return a},da=function(a){var b=document.createElement("a");a&&(ye.test(a),b.href=a);a=b.pathname;"/"!==a[0]&&(a="/"+a);var c=b.hostname.replace(Ce,"");return{href:b.href,
|
||||
protocol:b.protocol,host:b.host,hostname:c,pathname:a,search:b.search,hash:b.hash,port:b.port}},te,Ae,ve=function(c){te=te||b();Ae=Ae||a();for(var d=[],e=0;e<c.length;e+=3){var g=e+1<c.length,ca=e+2<c.length,Ee=c.charCodeAt(e),l=g?c.charCodeAt(e+1):0,w=ca?c.charCodeAt(e+2):0,k=Ee>>2;Ee=(Ee&3)<<4|l>>4;l=(l&15)<<2|w>>6;w&=63;ca||(w=64,g||(l=64));d.push(te[k],te[Ee],te[l],te[w])}return d.join("")},Ke=function(c){function d(a){for(;g<c.length;){var b=c.charAt(g++),d=Ae[b];if(null!=d)return d;if(!/^[\s\xa0]*$/.test(b))throw Error("Unknown base64 encoding at char: "+
|
||||
b);}return a}te=te||b();Ae=Ae||a();for(var e="",g=0;;){var ca=d(-1),Ee=d(0),l=d(64),w=d(64);if(64===w&&-1===ca)return e;e+=String.fromCharCode(ca<<2|Ee>>4);64!=l&&(e+=String.fromCharCode(Ee<<4&240|l>>2),64!=w&&(e+=String.fromCharCode(l<<6&192|w)))}},Le,Me=function(){var a={},b=Ie.sa;Ie.sa=void 0===b?a:b;a=Ie.sa;(b=a.wa)&&b.va||(b={va:[]},a.wa=b);return b},Nd=/(.*?)\*(.*?)\*(.*)/,we=/([^?#]+)(\?[^#]*)?(#.*)?/,ze=/(.*?)(^|&)_gl=([^&]*)&?(.*)/,Qe=function(a){var b=[],c;for(c in a)if(a.hasOwnProperty(c)){var d=
|
||||
a[c];void 0!==d&&d===d&&null!==d&&"[object Object]"!==d.toString()&&(b.push(c),b.push(ve(String(d))))}a=b.join("*");return["1",Ne(a),a].join("*")},Ne=function(a,b){a=[window.navigator.userAgent,(new Date).getTimezoneOffset(),window.navigator.xa||window.navigator.language,Math.floor((new Date).getTime()/60/1E3)-(void 0===b?0:b),a].join("*");if(!(b=Le)){b=Array(256);for(var c=0;256>c;c++){for(var d=c,e=0;8>e;e++)d=d&1?d>>>1^3988292384:d>>>1;b[c]=d}}Le=b;b=4294967295;for(c=0;c<a.length;c++)b=b>>>8^Le[(b^
|
||||
a.charCodeAt(c))&255];return((b^-1)>>>0).toString(36)},Oe=function(a){return function(b){var c=da(Ie.location.href),d=c.search.replace("?","");a:{for(var e=d.split("&"),g=0;g<e.length;g++){var ca=e[g].split("=");if("_gl"==decodeURIComponent(ca[0]).replace(/\+/g," ")){e=ca.slice(1).join("=");break a}}e=void 0}b.query=Re(e||"")||{};e=xe(c,"fragment");g=e.match(ze);b.ea=Re(g&&g[3]||"")||{};a&&Pe(c,d,e)}},Pe=function(a,b,c){function e(a,b){a=d(a);a.length&&(a=b+a);return a}Ie.history&&Ie.history.replaceState&&
|
||||
(ze.test(b)||ze.test(c))&&(a=xe(a,"path"),b=e(b,"?"),c=e(c,"#"),Ie.history.replaceState({},void 0,""+a+b+c))},Re=function(a){var b=void 0===b?3:b;try{if(a){var c=Nd.exec(a);if(c&&"1"===c[1]){var d=c[2],e=c[3];a:{for(a=0;a<b;++a)if(d===Ne(e,a)){var g=!0;break a}g=!1}if(g){b={};var ca=e?e.split("*"):[];for(e=0;e<ca.length;e+=2)b[ca[e]]=Ke(ca[e+1]);return b}}}}catch(ef){}},Se=function(a){try{a:{var b=a.target||a.srcElement||{};for(a=100;b&&0<a;){if(b.href&&b.nodeName.match(/^a(?:rea)?$/i)){var c=b;break a}b=
|
||||
b.parentNode;a--}c=null}if(c){var d=c.protocol;"http:"!==d&&"https:"!==d||g(c,c.hostname,!1)}}catch(ff){}},Je=function(a){try{var b=a.target||a.srcElement||{};if(b.action){var c=xe(da(b.action),"host");g(b,c,!0)}}catch(df){}};w("google_tag_data.glBridge.auto",function(a,b,c,d){var e=Me();e.N||(Be("mousedown",Se),Be("keyup",Se),Be("submit",Je),e.N=!0);a={za:a,Aa:b,ea:"fragment"===c,forms:!!d};Me().va.push(a)});w("google_tag_data.glBridge.decorate",function(a,b,c){c=!!c;a=Qe(a);if(b.tagName){if("a"==
|
||||
b.tagName.toLowerCase())return ca(a,b,c);if("form"==b.tagName.toLowerCase())return l(a,b)}if("string"==typeof b)return e(a,b,c)});w("google_tag_data.glBridge.generate",Qe);w("google_tag_data.glBridge.get",function(a,b){var c=Oe(!!b);b=Me();b.data||(b.data={query:{},ea:{}},c(b.data));c={};if(b=b.data)ue(c,b.query),a&&ue(c,b.ea);return c})})(window);var $c=function(a){this.w=a||[]};$c.prototype.set=function(a){this.w[a]=!0};$c.prototype.encode=function(){for(var a=[],b=0;b<this.w.length;b++)this.w[b]&&(a[Math.floor(b/6)]^=1<<b%6);for(b=0;b<a.length;b++)a[b]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt(a[b]||0);return a.join("")+"~"};var vd=new $c;function J(a){vd.set(a)}var Td=function(a){a=Dd(a);a=new $c(a);for(var b=vd.w.slice(),c=0;c<a.w.length;c++)b[c]=b[c]||a.w[c];return(new $c(b)).encode()},Dd=function(a){a=a.get(Gd);ka(a)||(a=[]);return a};var ea=function(a){return"function"==typeof a},ka=function(a){return"[object Array]"==Object.prototype.toString.call(Object(a))},qa=function(a){return void 0!=a&&-1<(a.constructor+"").indexOf("String")},D=function(a,b){return 0==a.indexOf(b)},sa=function(a){return a?a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,""):""},ra=function(){for(var a=O.navigator.userAgent+(M.cookie?M.cookie:"")+(M.referrer?M.referrer:""),b=a.length,c=O.history.length;0<c;)a+=c--^b++;return[hd()^La(a)&2147483647,Math.round((new Date).getTime()/
|
||||
1E3)].join(".")},ta=function(a){var b=M.createElement("img");b.width=1;b.height=1;b.src=a;return b},ua=function(){},K=function(a){if(encodeURIComponent instanceof Function)return encodeURIComponent(a);J(28);return a},L=function(a,b,c,d){try{a.addEventListener?a.addEventListener(b,c,!!d):a.attachEvent&&a.attachEvent("on"+b,c)}catch(e){J(27)}},f=/^[\w\-:/.?=&%!\[\]]+$/,wa=function(a,b,c){a&&(c?(c="",b&&f.test(b)&&(c=' id="'+b+'"'),f.test(a)&&M.write("<script"+c+' src="'+a+'">\x3c/script>')):(c=M.createElement("script"),
|
||||
c.type="text/javascript",c.async=!0,c.src=a,b&&(c.id=b),a=M.getElementsByTagName("script")[0],a.parentNode.insertBefore(c,a)))},be=function(a,b){return E(M.location[b?"href":"search"],a)},E=function(a,b){return(a=a.match("(?:&|#|\\?)"+K(b).replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")+"=([^&#]*)"))&&2==a.length?a[1]:""},xa=function(){var a=""+M.location.hostname;return 0==a.indexOf("www.")?a.substring(4):a},de=function(a,b){var c=a.indexOf(b);if(5==c||6==c)if(a=a.charAt(c+b.length),"/"==a||"?"==a||
|
||||
""==a||":"==a)return!0;return!1},ya=function(a,b){var c=M.referrer;if(/^(https?|android-app):\/\//i.test(c)){if(a)return c;a="//"+M.location.hostname;if(!de(c,a))return b&&(b=a.replace(/\./g,"-")+".cdn.ampproject.org",de(c,b))?void 0:c}},za=function(a,b){if(1==b.length&&null!=b[0]&&"object"===typeof b[0])return b[0];for(var c={},d=Math.min(a.length+1,b.length),e=0;e<d;e++)if("object"===typeof b[e]){for(var g in b[e])b[e].hasOwnProperty(g)&&(c[g]=b[e][g]);break}else e<a.length&&(c[a[e]]=b[e]);return c};var ee=function(){this.keys=[];this.values={};this.m={}};ee.prototype.set=function(a,b,c){this.keys.push(a);c?this.m[":"+a]=b:this.values[":"+a]=b};ee.prototype.get=function(a){return this.m.hasOwnProperty(":"+a)?this.m[":"+a]:this.values[":"+a]};ee.prototype.map=function(a){for(var b=0;b<this.keys.length;b++){var c=this.keys[b],d=this.get(c);d&&a(c,d)}};var O=window,M=document,va=function(a,b){return setTimeout(a,b)};var F=window,Ea=document,G=function(a){var b=F._gaUserPrefs;if(b&&b.ioo&&b.ioo()||a&&!0===F["ga-disable-"+a])return!0;try{var c=F.external;if(c&&c._gaUserPrefs&&"oo"==c._gaUserPrefs)return!0}catch(g){}a=[];b=String(Ea.cookie||document.cookie).split(";");for(c=0;c<b.length;c++){var d=b[c].split("="),e=d[0].replace(/^\s*|\s*$/g,"");e&&"AMP_TOKEN"==e&&((d=d.slice(1).join("=").replace(/^\s*|\s*$/g,""))&&(d=decodeURIComponent(d)),a.push(d))}for(b=0;b<a.length;b++)if("$OPT_OUT"==a[b])return!0;return!1};var Ca=function(a){var b=[],c=M.cookie.split(";");a=new RegExp("^\\s*"+a+"=\\s*(.*?)\\s*$");for(var d=0;d<c.length;d++){var e=c[d].match(a);e&&b.push(e[1])}return b},zc=function(a,b,c,d,e,g){e=G(e)?!1:eb.test(M.location.hostname)||"/"==c&&vc.test(d)?!1:!0;if(!e)return!1;b&&1200<b.length&&(b=b.substring(0,1200));c=a+"="+b+"; path="+c+"; ";g&&(c+="expires="+(new Date((new Date).getTime()+g)).toGMTString()+"; ");d&&"none"!==d&&(c+="domain="+d+";");d=M.cookie;M.cookie=c;if(!(d=d!=M.cookie))a:{a=Ca(a);
|
||||
for(d=0;d<a.length;d++)if(b==a[d]){d=!0;break a}d=!1}return d},Cc=function(a){return encodeURIComponent?encodeURIComponent(a).replace(/\(/g,"%28").replace(/\)/g,"%29"):a},vc=/^(www\.)?google(\.com?)?(\.[a-z]{2})?$/,eb=/(^|\.)doubleclick\.net$/i;var oc,Id=/^.*Version\/?(\d+)[^\d].*$/i,ne=function(){if(void 0!==O.__ga4__)return O.__ga4__;if(void 0===oc){var a=O.navigator.userAgent;if(a){var b=a;try{b=decodeURIComponent(a)}catch(c){}if(a=!(0<=b.indexOf("Chrome"))&&!(0<=b.indexOf("CriOS"))&&(0<=b.indexOf("Safari/")||0<=b.indexOf("Safari,")))b=Id.exec(b),a=11<=(b?Number(b[1]):-1);oc=a}else oc=!1}return oc};var Fa,Ga,fb,Ab,ja=/^https?:\/\/[^/]*cdn\.ampproject\.org\//,Ue=/^(?:www\.|m\.|amp\.)+/,Ub=[],ic=function(){Z.D([ua])},tc=function(a,b){var c=Ca("AMP_TOKEN");if(1<c.length)return J(55),!1;c=decodeURIComponent(c[0]||"");if("$OPT_OUT"==c||"$ERROR"==c||G(b))return J(62),!1;if(!ja.test(M.referrer)&&"$NOT_FOUND"==c)return J(68),!1;if(void 0!==Ab)return J(56),va(function(){a(Ab)},0),!0;if(Fa)return Ub.push(a),!0;if("$RETRIEVING"==c)return J(57),va(function(){tc(a,b)},1E4),!0;Fa=!0;c&&"$"!=c[0]||(xc("$RETRIEVING",
|
||||
3E4),setTimeout(Mc,3E4),c="");return Pc(c,b)?(Ub.push(a),!0):!1},Pc=function(a,b,c){if(!window.JSON)return J(58),!1;var d=O.XMLHttpRequest;if(!d)return J(59),!1;var e=new d;if(!("withCredentials"in e))return J(60),!1;e.open("POST",(c||"https://ampcid.google.com/v1/publisher:getClientId")+"?key=AIzaSyA65lEHUEizIsNtlbNo-l2K18dT680nsaM",!0);e.withCredentials=!0;e.setRequestHeader("Content-Type","text/plain");e.onload=function(){Fa=!1;if(4==e.readyState){try{200!=e.status&&(J(61),Qc("","$ERROR",3E4));
|
||||
var d=JSON.parse(e.responseText);d.optOut?(J(63),Qc("","$OPT_OUT",31536E6)):d.clientId?Qc(d.clientId,d.securityToken,31536E6):!c&&d.alternateUrl?(Ga&&clearTimeout(Ga),Fa=!0,Pc(a,b,d.alternateUrl)):(J(64),Qc("","$NOT_FOUND",36E5))}catch(ca){J(65),Qc("","$ERROR",3E4)}e=null}};d={originScope:"AMP_ECID_GOOGLE"};a&&(d.securityToken=a);e.send(JSON.stringify(d));Ga=va(function(){J(66);Qc("","$ERROR",3E4)},1E4);return!0},Mc=function(){Fa=!1},xc=function(a,b){if(void 0===fb){fb="";for(var c=id(),d=0;d<c.length;d++){var e=
|
||||
c[d];if(zc("AMP_TOKEN",encodeURIComponent(a),"/",e,"",b)){fb=e;return}}}zc("AMP_TOKEN",encodeURIComponent(a),"/",fb,"",b)},Qc=function(a,b,c){Ga&&clearTimeout(Ga);b&&xc(b,c);Ab=a;b=Ub;Ub=[];for(c=0;c<b.length;c++)b[c](a)};var oe=function(){return(Ba||"https:"==M.location.protocol?"https:":"http:")+"//www.google-analytics.com"},Da=function(a){this.name="len";this.message=a+"-8192"},ba=function(a,b,c){c=c||ua;if(2036>=b.length)wc(a,b,c);else if(8192>=b.length)x(a,b,c)||wd(a,b,c)||wc(a,b,c);else throw ge("len",b.length),new Da(b.length);},pe=function(a,b,c,d){d=d||ua;wd(a+"?"+b,"",d,c)},wc=function(a,b,c){var d=ta(a+"?"+b);d.onload=d.onerror=function(){d.onload=null;d.onerror=null;c()}},wd=function(a,b,c,d){var e=O.XMLHttpRequest;
|
||||
if(!e)return!1;var g=new e;if(!("withCredentials"in g))return!1;a=a.replace(/^http:/,"https:");g.open("POST",a,!0);g.withCredentials=!0;g.setRequestHeader("Content-Type","text/plain");g.onreadystatechange=function(){if(4==g.readyState){if(d)try{var a=g.responseText;if(1>a.length)ge("xhr","ver","0"),c();else if("1"!=a.charAt(0))ge("xhr","ver",String(a.length)),c();else if(3<d.count++)ge("xhr","tmr",""+d.count),c();else if(1==a.length)c();else{var b=a.charAt(1);if("d"==b)pe("https://stats.g.doubleclick.net/j/collect",
|
||||
d.U,d,c);else if("g"==b){var e="https://www.google.%/ads/ga-audiences".replace("%","com");wc(e,d.google,c);var w=a.substring(2);if(w)if(/^[a-z.]{1,6}$/.test(w)){var ha="https://www.google.%/ads/ga-audiences".replace("%",w);wc(ha,d.google,ua)}else ge("tld","bcc",w)}else ge("xhr","brc",b),c()}}catch(ue){ge("xhr","rsp"),c()}else c();g=null}};g.send(b);return!0},x=function(a,b,c){return O.navigator.sendBeacon?O.navigator.sendBeacon(a,b)?(c(),!0):!1:!1},ge=function(a,b,c){1<=100*Math.random()||G("?")||
|
||||
(a=["t=error","_e="+a,"_v=j70","sr=1"],b&&a.push("_f="+b),c&&a.push("_m="+K(c.substring(0,100))),a.push("aip=1"),a.push("z="+hd()),wc("https://www.google-analytics.com/u/d",a.join("&"),ua))};var h=function(a){var b=O.gaData=O.gaData||{};return b[a]=b[a]||{}};var Ha=function(){this.M=[]};Ha.prototype.add=function(a){this.M.push(a)};Ha.prototype.D=function(a){try{for(var b=0;b<this.M.length;b++){var c=a.get(this.M[b]);c&&ea(c)&&c.call(O,a)}}catch(d){}b=a.get(Ia);b!=ua&&ea(b)&&(a.set(Ia,ua,!0),setTimeout(b,10))};function Ja(a){if(100!=a.get(Ka)&&La(P(a,Q))%1E4>=100*R(a,Ka))throw"abort";}function Ma(a){if(G(P(a,Na)))throw"abort";}function Oa(){var a=M.location.protocol;if("http:"!=a&&"https:"!=a)throw"abort";}
|
||||
function Pa(a){try{O.navigator.sendBeacon?J(42):O.XMLHttpRequest&&"withCredentials"in new O.XMLHttpRequest&&J(40)}catch(c){}a.set(ld,Td(a),!0);a.set(Ac,R(a,Ac)+1);var b=[];Qa.map(function(c,d){d.F&&(c=a.get(c),void 0!=c&&c!=d.defaultValue&&("boolean"==typeof c&&(c*=1),b.push(d.F+"="+K(""+c))))});b.push("z="+Bd());a.set(Ra,b.join("&"),!0)}
|
||||
function Sa(a){var b=P(a,gd)||oe()+"/collect",c=a.get(qe),d=P(a,fa);!d&&a.get(Vd)&&(d="beacon");if(c)pe(b,P(a,Ra),c,a.get(Ia));else if(d){c=d;d=P(a,Ra);var e=a.get(Ia);e=e||ua;"image"==c?wc(b,d,e):"xhr"==c&&wd(b,d,e)||"beacon"==c&&x(b,d,e)||ba(b,d,e)}else ba(b,P(a,Ra),a.get(Ia));b=a.get(Na);b=h(b);c=b.hitcount;b.hitcount=c?c+1:1;b=a.get(Na);delete h(b).pending_experiments;a.set(Ia,ua,!0)}
|
||||
function Hc(a){(O.gaData=O.gaData||{}).expId&&a.set(Nc,(O.gaData=O.gaData||{}).expId);(O.gaData=O.gaData||{}).expVar&&a.set(Oc,(O.gaData=O.gaData||{}).expVar);var b=a.get(Na);if(b=h(b).pending_experiments){var c=[];for(d in b)b.hasOwnProperty(d)&&b[d]&&c.push(encodeURIComponent(d)+"."+encodeURIComponent(b[d]));var d=c.join("!")}else d=void 0;d&&a.set(m,d,!0)}function cd(){if(O.navigator&&"preview"==O.navigator.loadPurpose)throw"abort";}
|
||||
function yd(a){var b=O.gaDevIds;ka(b)&&0!=b.length&&a.set("&did",b.join(","),!0)}function vb(a){if(!a.get(Na))throw"abort";};var hd=function(){return Math.round(2147483647*Math.random())},Bd=function(){try{var a=new Uint32Array(1);O.crypto.getRandomValues(a);return a[0]&2147483647}catch(b){return hd()}};function Ta(a){var b=R(a,Ua);500<=b&&J(15);var c=P(a,Va);if("transaction"!=c&&"item"!=c){c=R(a,Wa);var d=(new Date).getTime(),e=R(a,Xa);0==e&&a.set(Xa,d);e=Math.round(2*(d-e)/1E3);0<e&&(c=Math.min(c+e,20),a.set(Xa,d));if(0>=c)throw"abort";a.set(Wa,--c)}a.set(Ua,++b)};var Ya=function(){this.data=new ee},Qa=new ee,Za=[];Ya.prototype.get=function(a){var b=$a(a),c=this.data.get(a);b&&void 0==c&&(c=ea(b.defaultValue)?b.defaultValue():b.defaultValue);return b&&b.Z?b.Z(this,a,c):c};var P=function(a,b){a=a.get(b);return void 0==a?"":""+a},R=function(a,b){a=a.get(b);return void 0==a||""===a?0:1*a};Ya.prototype.set=function(a,b,c){if(a)if("object"==typeof a)for(var d in a)a.hasOwnProperty(d)&&ab(this,d,a[d],c);else ab(this,a,b,c)};
|
||||
var ab=function(a,b,c,d){if(void 0!=c)switch(b){case Na:wb.test(c)}var e=$a(b);e&&e.o?e.o(a,b,c,d):a.data.set(b,c,d)},bb=function(a,b,c,d,e){this.name=a;this.F=b;this.Z=d;this.o=e;this.defaultValue=c},$a=function(a){var b=Qa.get(a);if(!b)for(var c=0;c<Za.length;c++){var d=Za[c],e=d[0].exec(a);if(e){b=d[1](e);Qa.set(b.name,b);break}}return b},yc=function(a){var b;Qa.map(function(c,d){d.F==a&&(b=d)});return b&&b.name},S=function(a,b,c,d,e){a=new bb(a,b,c,d,e);Qa.set(a.name,a);return a.name},cb=function(a,
|
||||
b){Za.push([new RegExp("^"+a+"$"),b])},T=function(a,b,c){return S(a,b,c,void 0,db)},db=function(){};var gb=qa(window.GoogleAnalyticsObject)&&sa(window.GoogleAnalyticsObject)||"ga",jd=/^(?:utma\.)?\d+\.\d+$/,kd=/^amp-[\w.-]{22,64}$/,Ba=!1,hb=T("apiVersion","v"),ib=T("clientVersion","_v");S("anonymizeIp","aip");var jb=S("adSenseId","a"),Va=S("hitType","t"),Ia=S("hitCallback"),Ra=S("hitPayload");S("nonInteraction","ni");S("currencyCode","cu");S("dataSource","ds");var Vd=S("useBeacon",void 0,!1),fa=S("transport");S("sessionControl","sc","");S("sessionGroup","sg");S("queueTime","qt");var Ac=S("_s","_s");
|
||||
S("screenName","cd");var kb=S("location","dl",""),lb=S("referrer","dr"),mb=S("page","dp","");S("hostname","dh");var nb=S("language","ul"),ob=S("encoding","de");S("title","dt",function(){return M.title||void 0});cb("contentGroup([0-9]+)",function(a){return new bb(a[0],"cg"+a[1])});var pb=S("screenColors","sd"),qb=S("screenResolution","sr"),rb=S("viewportSize","vp"),sb=S("javaEnabled","je"),tb=S("flashVersion","fl");S("campaignId","ci");S("campaignName","cn");S("campaignSource","cs");
|
||||
S("campaignMedium","cm");S("campaignKeyword","ck");S("campaignContent","cc");
|
||||
var ub=S("eventCategory","ec"),xb=S("eventAction","ea"),yb=S("eventLabel","el"),zb=S("eventValue","ev"),Bb=S("socialNetwork","sn"),Cb=S("socialAction","sa"),Db=S("socialTarget","st"),Eb=S("l1","plt"),Fb=S("l2","pdt"),Gb=S("l3","dns"),Hb=S("l4","rrt"),Ib=S("l5","srt"),Jb=S("l6","tcp"),Kb=S("l7","dit"),Lb=S("l8","clt"),Ve=S("l9","_gst"),We=S("l10","_gbt"),Xe=S("l11","_cst"),Ye=S("l12","_cbt"),Mb=S("timingCategory","utc"),Nb=S("timingVar","utv"),Ob=S("timingLabel","utl"),Pb=S("timingValue","utt");
|
||||
S("appName","an");S("appVersion","av","");S("appId","aid","");S("appInstallerId","aiid","");S("exDescription","exd");S("exFatal","exf");var Nc=S("expId","xid"),Oc=S("expVar","xvar"),m=S("exp","exp"),Rc=S("_utma","_utma"),Sc=S("_utmz","_utmz"),Tc=S("_utmht","_utmht"),Ua=S("_hc",void 0,0),Xa=S("_ti",void 0,0),Wa=S("_to",void 0,20);cb("dimension([0-9]+)",function(a){return new bb(a[0],"cd"+a[1])});cb("metric([0-9]+)",function(a){return new bb(a[0],"cm"+a[1])});S("linkerParam",void 0,void 0,Bc,db);
|
||||
var Ze=T("_cd2l",void 0,!1),ld=S("usage","_u"),Gd=S("_um");S("forceSSL",void 0,void 0,function(){return Ba},function(a,b,c){J(34);Ba=!!c});var ed=S("_j1","jid"),ia=S("_j2","gjid");cb("\\&(.*)",function(a){var b=new bb(a[0],a[1]),c=yc(a[0].substring(1));c&&(b.Z=function(a){return a.get(c)},b.o=function(a,b,g,ca){a.set(c,g,ca)},b.F=void 0);return b});
|
||||
var Qb=T("_oot"),dd=S("previewTask"),Rb=S("checkProtocolTask"),md=S("validationTask"),Sb=S("checkStorageTask"),Uc=S("historyImportTask"),Tb=S("samplerTask"),Vb=S("_rlt"),Wb=S("buildHitTask"),Xb=S("sendHitTask"),Vc=S("ceTask"),zd=S("devIdTask"),Cd=S("timingTask"),Ld=S("displayFeaturesTask"),oa=S("customTask"),V=T("name"),Q=T("clientId","cid"),n=T("clientIdTime"),xd=T("storedClientId"),Ad=S("userId","uid"),Na=T("trackingId","tid"),U=T("cookieName",void 0,"_ga"),W=T("cookieDomain"),Yb=T("cookiePath",
|
||||
void 0,"/"),Zb=T("cookieExpires",void 0,63072E3),Hd=T("cookieUpdate",void 0,!0),$b=T("legacyCookieDomain"),Wc=T("legacyHistoryImport",void 0,!0),ac=T("storage",void 0,"cookie"),bc=T("allowLinker",void 0,!1),cc=T("allowAnchor",void 0,!0),Ka=T("sampleRate","sf",100),dc=T("siteSpeedSampleRate",void 0,1),ec=T("alwaysSendReferrer",void 0,!1),I=T("_gid","_gid"),la=T("_gcn"),Kd=T("useAmpClientId"),ce=T("_gclid"),fe=T("_gt"),he=T("_ge",void 0,7776E6),ie=T("_gclsrc"),je=T("storeGac",void 0,!0),gd=S("transportUrl"),
|
||||
Md=S("_r","_r"),qe=S("_dp"),Ud=S("allowAdFeatures",void 0,!0);function X(a,b,c,d){b[a]=function(){try{return d&&J(d),c.apply(this,arguments)}catch(e){throw ge("exc",a,e&&e.name),e;}}};var Od=function(){this.V=100;this.$=this.fa=!1;this.oa="detourexp";this.groups=1},Ed=function(a){var b=new Od,c;if(b.fa&&b.$)return 0;b.$=!0;if(a){if(b.oa&&void 0!==a.get(b.oa))return R(a,b.oa);if(0==a.get(dc))return 0}if(0==b.V)return 0;void 0===c&&(c=Bd());return 0==c%b.V?Math.floor(c/b.V)%b.groups+1:0};function fc(){var a,b;if((b=(b=O.navigator)?b.plugins:null)&&b.length)for(var c=0;c<b.length&&!a;c++){var d=b[c];-1<d.name.indexOf("Shockwave Flash")&&(a=d.description)}if(!a)try{var e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"),a="WIN 6,0,21,0",e.AllowScriptAccess="always",a=e.GetVariable("$version")}catch(g){}if(!a)try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),a=e.GetVariable("$version")}catch(g){}a&&
|
||||
(e=a.match(/[\d]+/g))&&3<=e.length&&(a=e[0]+"."+e[1]+" r"+e[2]);return a||void 0};var aa=function(a){var b=Math.min(R(a,dc),100);return La(P(a,Q))%100>=b?!1:!0},gc=function(a){var b={};if(Ec(b)||Fc(b)){var c=b[Eb];void 0==c||Infinity==c||isNaN(c)||(0<c?(Y(b,Gb),Y(b,Jb),Y(b,Ib),Y(b,Fb),Y(b,Hb),Y(b,Kb),Y(b,Lb),Y(b,Ve),Y(b,We),Y(b,Xe),Y(b,Ye),va(function(){a(b)},10)):L(O,"load",function(){gc(a)},!1))}},Ec=function(a){var b=O.performance||O.webkitPerformance;b=b&&b.timing;if(!b)return!1;var c=b.navigationStart;if(0==c)return!1;a[Eb]=b.loadEventStart-c;a[Gb]=b.domainLookupEnd-b.domainLookupStart;
|
||||
a[Jb]=b.connectEnd-b.connectStart;a[Ib]=b.responseStart-b.requestStart;a[Fb]=b.responseEnd-b.responseStart;a[Hb]=b.fetchStart-c;a[Kb]=b.domInteractive-c;a[Lb]=b.domContentLoadedEventStart-c;a[Ve]=N.L-c;a[We]=N.ya-c;O.google_tag_manager&&O.google_tag_manager._li&&(b=O.google_tag_manager._li,a[Xe]=b.cst,a[Ye]=b.cbt);return!0},Fc=function(a){if(O.top!=O)return!1;var b=O.external,c=b&&b.onloadT;b&&!b.isValidLoadTime&&(c=void 0);2147483648<c&&(c=void 0);0<c&&b.setPageReadyTime();if(void 0==c)return!1;
|
||||
a[Eb]=c;return!0},Y=function(a,b){var c=a[b];if(isNaN(c)||Infinity==c||0>c)a[b]=void 0},Fd=function(a){return function(b){if("pageview"==b.get(Va)&&!a.I){a.I=!0;var c=aa(b),d=0<E(b.get(kb),"gclid").length;(c||d)&&gc(function(b){c&&a.send("timing",b);d&&a.send("adtiming",b)})}}};var hc=!1,mc=function(a){if("cookie"==P(a,ac)){if(a.get(Hd)||P(a,xd)!=P(a,Q)){var b=1E3*R(a,Zb);ma(a,Q,U,b)}ma(a,I,la,864E5);if(a.get(je)){var c=a.get(ce);if(c){var d=Math.min(R(a,he),1E3*R(a,Zb));d=Math.min(d,1E3*R(a,fe)+d-(new Date).getTime());a.data.set(he,d);b={};var e=a.get(fe),g=a.get(ie),ca=kc(P(a,Yb)),l=lc(P(a,W));a=P(a,Na);g&&"aw.ds"!=g?b&&(b.ua=!0):(c=["1",e,Cc(c)].join("."),0<d&&(b&&(b.ta=!0),zc("_gac_"+Cc(a),c,ca,l,a,d)));le(b)}}else J(75)}},ma=function(a,b,c,d){var e=nd(a,b);if(e){c=
|
||||
P(a,c);var g=kc(P(a,Yb)),ca=lc(P(a,W)),l=P(a,Na);if("auto"!=ca)zc(c,e,g,ca,l,d)&&(hc=!0);else{J(32);for(var k=id(),w=0;w<k.length;w++)if(ca=k[w],a.data.set(W,ca),e=nd(a,b),zc(c,e,g,ca,l,d)){hc=!0;return}a.data.set(W,"auto")}}},nc=function(a){if("cookie"==P(a,ac)&&!hc&&(mc(a),!hc))throw"abort";},Yc=function(a){if(a.get(Wc)){var b=P(a,W),c=P(a,$b)||xa(),d=Xc("__utma",c,b);d&&(J(19),a.set(Tc,(new Date).getTime(),!0),a.set(Rc,d.R),(b=Xc("__utmz",c,b))&&d.hash==b.hash&&a.set(Sc,b.R))}},nd=function(a,b){b=
|
||||
Cc(P(a,b));var c=lc(P(a,W)).split(".").length;a=jc(P(a,Yb));1<a&&(c+="-"+a);return b?["GA1",c,b].join("."):""},Xd=function(a,b){return na(b,P(a,W),P(a,Yb))},na=function(a,b,c){if(!a||1>a.length)J(12);else{for(var d=[],e=0;e<a.length;e++){var g=a[e];var ca=g.split(".");var l=ca.shift();("GA1"==l||"1"==l)&&1<ca.length?(g=ca.shift().split("-"),1==g.length&&(g[1]="1"),g[0]*=1,g[1]*=1,ca={H:g,s:ca.join(".")}):ca=kd.test(g)?{H:[0,0],s:g}:void 0;ca&&d.push(ca)}if(1==d.length)return J(13),d[0].s;if(0==d.length)J(12);
|
||||
else{J(14);d=Gc(d,lc(b).split(".").length,0);if(1==d.length)return d[0].s;d=Gc(d,jc(c),1);1<d.length&&J(41);return d[0]&&d[0].s}}},Gc=function(a,b,c){for(var d=[],e=[],g,ca=0;ca<a.length;ca++){var l=a[ca];l.H[c]==b?d.push(l):void 0==g||l.H[c]<g?(e=[l],g=l.H[c]):l.H[c]==g&&e.push(l)}return 0<d.length?d:e},lc=function(a){return 0==a.indexOf(".")?a.substr(1):a},id=function(){var a=[],b=xa().split(".");if(4==b.length){var c=b[b.length-1];if(parseInt(c,10)==c)return["none"]}for(c=b.length-2;0<=c;c--)a.push(b.slice(c).join("."));
|
||||
b=M.location.hostname;eb.test(b)||vc.test(b)||a.push("none");return a},kc=function(a){if(!a)return"/";1<a.length&&a.lastIndexOf("/")==a.length-1&&(a=a.substr(0,a.length-1));0!=a.indexOf("/")&&(a="/"+a);return a},jc=function(a){a=kc(a);return"/"==a?1:a.split("/").length},le=function(a){a.ta&&J(77);a.na&&J(74);a.pa&&J(73);a.ua&&J(69)};function Xc(a,b,c){"none"==b&&(b="");var d=[],e=Ca(a);a="__utma"==a?6:2;for(var g=0;g<e.length;g++){var ca=(""+e[g]).split(".");ca.length>=a&&d.push({hash:ca[0],R:e[g],O:ca})}if(0!=d.length)return 1==d.length?d[0]:Zc(b,d)||Zc(c,d)||Zc(null,d)||d[0]}function Zc(a,b){if(null==a)var c=a=1;else c=La(a),a=La(D(a,".")?a.substring(1):"."+a);for(var d=0;d<b.length;d++)if(b[d].hash==c||b[d].hash==a)return b[d]};var od=new RegExp(/^https?:\/\/([^\/:]+)/),De=O.google_tag_data.glBridge,pd=/(.*)([?&#])(?:_ga=[^&#]*)(?:&?)(.*)/,me=/(.*)([?&#])(?:_gac=[^&#]*)(?:&?)(.*)/;function Bc(a){if(a.get(Ze))return J(35),De.generate($e(a));var b=a.get(Q),c=a.get(I)||"";b="_ga=2."+K(pa(c+b,0)+"."+c+"-"+b);(a=af(a))?(J(44),a="&_gac=1."+K([pa(a.qa,0),a.timestamp,a.qa].join("."))):a="";return b+a}
|
||||
function Ic(a,b){var c=new Date,d=O.navigator,e=d.plugins||[];a=[a,d.userAgent,c.getTimezoneOffset(),c.getYear(),c.getDate(),c.getHours(),c.getMinutes()+b];for(b=0;b<e.length;++b)a.push(e[b].description);return La(a.join("."))}function pa(a,b){var c=new Date,d=O.navigator,e=c.getHours()+Math.floor((c.getMinutes()+b)/60);return La([a,d.userAgent,d.language||"",c.getTimezoneOffset(),c.getYear(),c.getDate()+Math.floor(e/24),(24+e)%24,(60+c.getMinutes()+b)%60].join("."))}
|
||||
var Dc=function(a){J(48);this.target=a;this.T=!1};Dc.prototype.ca=function(a,b){if(a){if(this.target.get(Ze))return De.decorate($e(this.target),a,b);if(a.tagName){if("a"==a.tagName.toLowerCase()){a.href&&(a.href=qd(this,a.href,b));return}if("form"==a.tagName.toLowerCase())return rd(this,a)}if("string"==typeof a)return qd(this,a,b)}};
|
||||
var qd=function(a,b,c){var d=pd.exec(b);d&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));(d=me.exec(b))&&3<=d.length&&(b=d[1]+(d[3]?d[2]+d[3]:""));a=a.target.get("linkerParam");var e=b.indexOf("?");d=b.indexOf("#");c?b+=(-1==d?"#":"&")+a:(c=-1==e?"?":"&",b=-1==d?b+(c+a):b.substring(0,d)+c+a+b.substring(d));b=b.replace(/&+_ga=/,"&_ga=");return b=b.replace(/&+_gac=/,"&_gac=")},rd=function(a,b){if(b&&b.action)if("get"==b.method.toLowerCase()){a=a.target.get("linkerParam").split("&");for(var c=0;c<a.length;c++){var d=
|
||||
a[c].split("="),e=d[1];d=d[0];for(var g=b.childNodes||[],ca=!1,l=0;l<g.length;l++)if(g[l].name==d){g[l].setAttribute("value",e);ca=!0;break}ca||(g=M.createElement("input"),g.setAttribute("type","hidden"),g.setAttribute("name",d),g.setAttribute("value",e),b.appendChild(g))}}else"post"==b.method.toLowerCase()&&(b.action=qd(a,b.action))};
|
||||
Dc.prototype.S=function(a,b,c){function d(c){try{c=c||O.event;a:{var d=c.target||c.srcElement;for(c=100;d&&0<c;){if(d.href&&d.nodeName.match(/^a(?:rea)?$/i)){var e=d;break a}d=d.parentNode;c--}e={}}("http:"==e.protocol||"https:"==e.protocol)&&sd(a,e.hostname||"")&&e.href&&(e.href=qd(g,e.href,b))}catch(w){J(26)}}var e=this;if(this.target.get(Ze))De.auto(function(){return $e(e.target)},a,b?"fragment":"",c);else{var g=this;this.T||(this.T=!0,L(M,"mousedown",d,!1),L(M,"keyup",d,!1));c&&L(M,"submit",function(b){b=
|
||||
b||O.event;if((b=b.target||b.srcElement)&&b.action){var c=b.action.match(od);c&&sd(a,c[1])&&rd(g,b)}})}};function sd(a,b){if(b==M.location.hostname)return!1;for(var c=0;c<a.length;c++)if(a[c]instanceof RegExp){if(a[c].test(b))return!0}else if(0<=b.indexOf(a[c]))return!0;return!1}function ke(a,b){return b!=Ic(a,0)&&b!=Ic(a,-1)&&b!=Ic(a,-2)&&b!=pa(a,0)&&b!=pa(a,-1)&&b!=pa(a,-2)}function $e(a){var b=af(a);return{_ga:a.get(Q),_gid:a.get(I)||void 0,_gac:b?[b.qa,b.timestamp].join("."):void 0}}
|
||||
function af(a){function b(a){return void 0==a||""===a?0:Number(a)}var c=a.get(ce);if(c&&a.get(je)){var d=b(a.get(fe));if(1E3*d+b(a.get(he))<=(new Date).getTime())J(76);else return{timestamp:d,qa:c}}};var p=/^(GTM|OPT)-[A-Z0-9]+$/,q=/;_gaexp=[^;]*/g,r=/;((__utma=)|([^;=]+=GAX?\d+\.))[^;]*/g,Aa=/^https?:\/\/[\w\-.]+\.google.com(:\d+)?\/optimize\/opt-launch\.html\?.*$/,t=function(a){function b(a,b){b&&(c+="&"+a+"="+K(b))}var c="https://www.google-analytics.com/gtm/js?id="+K(a.id);"dataLayer"!=a.B&&b("l",a.B);b("t",a.target);b("cid",a.clientId);b("cidt",a.ka);b("gac",a.la);b("aip",a.ia);a.sync&&b("m","sync");b("cycle",a.G);a.qa&&b("gclid",a.qa);Aa.test(M.referrer)&&b("cb",String(hd()));return c};var Jd=function(a,b,c){this.aa=b;(b=c)||(b=(b=P(a,V))&&"t0"!=b?Wd.test(b)?"_gat_"+Cc(P(a,Na)):"_gat_"+Cc(b):"_gat");this.Y=b;this.ra=null},Rd=function(a,b){var c=b.get(Wb);b.set(Wb,function(b){Pd(a,b,ed);Pd(a,b,ia);var d=c(b);Qd(a,b);return d});var d=b.get(Xb);b.set(Xb,function(b){var c=d(b);if(se(b)){if(ne()!==H(a,b)){J(80);var e={U:re(a,b,1),google:re(a,b,2),count:0};pe("https://stats.g.doubleclick.net/j/collect",e.U,e)}else ta(re(a,b,0));b.set(ed,"",!0)}return c})},Pd=function(a,b,c){!1===b.get(Ud)||
|
||||
b.get(c)||("1"==Ca(a.Y)[0]?b.set(c,"",!0):b.set(c,""+hd(),!0))},Qd=function(a,b){se(b)&&zc(a.Y,"1",b.get(Yb),b.get(W),b.get(Na),6E4)},se=function(a){return!!a.get(ed)&&a.get(Ud)},re=function(a,b,c){var d=new ee,e=function(a){$a(a).F&&d.set($a(a).F,b.get(a))};e(hb);e(ib);e(Na);e(Q);e(ed);if(0==c||1==c)e(Ad),e(ia),e(I);d.set($a(ld).F,Td(b));var g="";d.map(function(a,b){g+=K(a)+"=";g+=K(""+b)+"&"});g+="z="+hd();0==c?g=a.aa+g:1==c?g="t=dc&aip=1&_r=3&"+g:2==c&&(g="t=sr&aip=1&_r=4&slf_rd=1&"+g);return g},
|
||||
H=function(a,b){null===a.ra&&(a.ra=1===Ed(b),a.ra&&J(33));return a.ra},Wd=/^gtm\d+$/;var fd=function(a,b){a=a.b;if(!a.get("dcLoaded")){var c=new $c(Dd(a));c.set(29);a.set(Gd,c.w);b=b||{};var d;b[U]&&(d=Cc(b[U]));b=new Jd(a,"https://stats.g.doubleclick.net/r/collect?t=dc&aip=1&_r=3&",d);Rd(b,a);a.set("dcLoaded",!0)}};var Sd=function(a){if(!a.get("dcLoaded")&&"cookie"==a.get(ac)){var b=new Jd(a);Pd(b,a,ed);Pd(b,a,ia);Qd(b,a);if(se(a)){var c=ne()!==H(b,a);a.set(Md,1,!0);c?(J(79),a.set(gd,oe()+"/j/collect",!0),a.set(qe,{U:re(b,a,1),google:re(b,a,2),count:0},!0)):a.set(gd,oe()+"/r/collect",!0)}}};var Lc=function(){var a=O.gaGlobal=O.gaGlobal||{};return a.hid=a.hid||hd()};var ad,bd=function(a,b,c){if(!ad){var d=M.location.hash;var e=O.name,g=/^#?gaso=([^&]*)/;if(e=(d=(d=d&&d.match(g)||e&&e.match(g))?d[1]:Ca("GASO")[0]||"")&&d.match(/^(?:!([-0-9a-z.]{1,40})!)?([-.\w]{10,1200})$/i))zc("GASO",""+d,c,b,a,0),window._udo||(window._udo=b),window._utcp||(window._utcp=c),a=e[1],wa("https://www.google.com/analytics/web/inpage/pub/inpage.js?"+(a?"prefix="+a+"&":"")+hd(),"_gasojs");ad=!0}};var wb=/^(UA|YT|MO|GP)-(\d+)-(\d+)$/,pc=function(a){function b(a,b){d.b.data.set(a,b)}function c(a,c){b(a,c);d.filters.add(a)}var d=this;this.b=new Ya;this.filters=new Ha;b(V,a[V]);b(Na,sa(a[Na]));b(U,a[U]);b(W,a[W]||xa());b(Yb,a[Yb]);b(Zb,a[Zb]);b(Hd,a[Hd]);b($b,a[$b]);b(Wc,a[Wc]);b(bc,a[bc]);b(cc,a[cc]);b(Ka,a[Ka]);b(dc,a[dc]);b(ec,a[ec]);b(ac,a[ac]);b(Ad,a[Ad]);b(n,a[n]);b(Kd,a[Kd]);b(je,a[je]);b(Ze,a[Ze]);b(hb,1);b(ib,"j70");c(Qb,Ma);c(oa,ua);c(dd,cd);c(Rb,Oa);c(md,vb);c(Sb,nc);c(Uc,Yc);c(Tb,
|
||||
Ja);c(Vb,Ta);c(Vc,Hc);c(zd,yd);c(Ld,Sd);c(Wb,Pa);c(Xb,Sa);c(Cd,Fd(this));Kc(this.b);Jc(this.b,a[Q]);this.b.set(jb,Lc());bd(this.b.get(Na),this.b.get(W),this.b.get(Yb))},Jc=function(a,b){var c=P(a,U);a.data.set(la,"_ga"==c?"_gid":c+"_gid");if("cookie"==P(a,ac)){hc=!1;c=Ca(P(a,U));c=Xd(a,c);if(!c){c=P(a,W);var d=P(a,$b)||xa();c=Xc("__utma",d,c);void 0!=c?(J(10),c=c.O[1]+"."+c.O[2]):c=void 0}c&&(hc=!0);if(d=c&&!a.get(Hd))if(d=c.split("."),2!=d.length)d=!1;else if(d=Number(d[1])){var e=R(a,Zb);d=d+e<
|
||||
(new Date).getTime()/1E3}else d=!1;d&&(c=void 0);c&&(a.data.set(xd,c),a.data.set(Q,c),c=Ca(P(a,la)),(c=Xd(a,c))&&a.data.set(I,c));if(a.get(je)&&(c=a.get(ce),d=a.get(ie),!c||d&&"aw.ds"!=d)){c={};if(M){d=[];e=M.cookie.split(";");for(var g=/^\s*_gac_(UA-\d+-\d+)=\s*(.+?)\s*$/,ca=0;ca<e.length;ca++){var l=e[ca].match(g);l&&d.push({ja:l[1],value:l[2]})}e={};if(d&&d.length)for(g=0;g<d.length;g++)(ca=d[g].value.split("."),"1"!=ca[0]||3!=ca.length)?c&&(c.na=!0):ca[1]&&(e[d[g].ja]?c&&(c.pa=!0):e[d[g].ja]=
|
||||
[],e[d[g].ja].push({timestamp:ca[1],qa:ca[2]}));d=e}else d={};d=d[P(a,Na)];le(c);d&&0!=d.length&&(c=d[0],a.data.set(fe,c.timestamp),a.data.set(ce,c.qa))}}if(a.get(Hd)&&(c=be("_ga",a.get(cc)),d=De.get(a.get(cc)),e=d._ga,c||e))if(c&&e&&J(36),a.get(bc)){if(e&&(J(38),a.data.set(Q,e),d._gid&&(J(51),a.data.set(I,d._gid)),d._gac&&(d=d._gac.split("."))&&2==d.length&&(J(37),a.data.set(ce,d[0]),a.data.set(fe,d[1]))),c)b:if(d=c.indexOf("."),-1==d)J(22);else{e=c.substring(0,d);g=c.substring(d+1);d=g.indexOf(".");
|
||||
c=g.substring(0,d);g=g.substring(d+1);if("1"==e){if(d=g,ke(d,c)){J(23);break b}}else if("2"==e){d=g.indexOf("-");e="";0<d?(e=g.substring(0,d),d=g.substring(d+1)):d=g.substring(1);if(ke(e+d,c)){J(53);break b}e&&(J(2),a.data.set(I,e))}else{J(22);break b}J(11);a.data.set(Q,d);if(c=be("_gac",a.get(cc)))c=c.split("."),"1"!=c[0]||4!=c.length?J(72):ke(c[3],c[1])?J(71):(a.data.set(ce,c[3]),a.data.set(fe,c[2]),J(70))}}else J(21);b&&(J(9),a.data.set(Q,K(b)));a.get(Q)||((b=(b=O.gaGlobal&&O.gaGlobal.vid)&&-1!=
|
||||
b.search(jd)?b:void 0)?(J(17),a.data.set(Q,b)):(J(8),a.data.set(Q,ra())));a.get(I)||(J(3),a.data.set(I,ra()));mc(a)},Kc=function(a){var b=O.navigator,c=O.screen,d=M.location;a.set(lb,ya(a.get(ec),a.get(Kd)));if(d){var e=d.pathname||"";"/"!=e.charAt(0)&&(J(31),e="/"+e);a.set(kb,d.protocol+"//"+d.hostname+e+d.search)}c&&a.set(qb,c.width+"x"+c.height);c&&a.set(pb,c.colorDepth+"-bit");c=M.documentElement;var g=(e=M.body)&&e.clientWidth&&e.clientHeight,ca=[];c&&c.clientWidth&&c.clientHeight&&("CSS1Compat"===
|
||||
M.compatMode||!g)?ca=[c.clientWidth,c.clientHeight]:g&&(ca=[e.clientWidth,e.clientHeight]);c=0>=ca[0]||0>=ca[1]?"":ca.join("x");a.set(rb,c);a.set(tb,fc());a.set(ob,M.characterSet||M.charset);a.set(sb,b&&"function"===typeof b.javaEnabled&&b.javaEnabled()||!1);a.set(nb,(b&&(b.language||b.browserLanguage)||"").toLowerCase());a.data.set(ce,be("gclid",!0));a.data.set(ie,be("gclsrc",!0));a.data.set(fe,Math.round((new Date).getTime()/1E3));if(d&&a.get(cc)&&(b=M.location.hash)){b=b.split(/[?&#]+/);d=[];for(c=
|
||||
0;c<b.length;++c)(D(b[c],"utm_id")||D(b[c],"utm_campaign")||D(b[c],"utm_source")||D(b[c],"utm_medium")||D(b[c],"utm_term")||D(b[c],"utm_content")||D(b[c],"gclid")||D(b[c],"dclid")||D(b[c],"gclsrc"))&&d.push(b[c]);0<d.length&&(b="#"+d.join("&"),a.set(kb,a.get(kb)+b))}};pc.prototype.get=function(a){return this.b.get(a)};pc.prototype.set=function(a,b){this.b.set(a,b)};var qc={pageview:[mb],event:[ub,xb,yb,zb],social:[Bb,Cb,Db],timing:[Mb,Nb,Pb,Ob]};
|
||||
pc.prototype.send=function(a){if(!(1>arguments.length)){if("string"===typeof arguments[0]){var b=arguments[0];var c=[].slice.call(arguments,1)}else b=arguments[0]&&arguments[0][Va],c=arguments;b&&(c=za(qc[b]||[],c),c[Va]=b,this.b.set(c,void 0,!0),this.filters.D(this.b),this.b.data.m={})}};pc.prototype.ma=function(a,b){var c=this;u(a,c,b)||(v(a,function(){u(a,c,b)}),y(String(c.get(V)),a,void 0,b,!0))};var rc=function(a){if("prerender"==M.visibilityState)return!1;a();return!0},z=function(a){if(!rc(a)){J(16);var b=!1,c=function(){if(!b&&rc(a)){b=!0;var d=c,e=M;e.removeEventListener?e.removeEventListener("visibilitychange",d,!1):e.detachEvent&&e.detachEvent("onvisibilitychange",d)}};L(M,"visibilitychange",c)}};var td=/^(?:(\w+)\.)?(?:(\w+):)?(\w+)$/,sc=function(a){if(ea(a[0]))this.u=a[0];else{var b=td.exec(a[0]);null!=b&&4==b.length&&(this.c=b[1]||"t0",this.K=b[2]||"",this.C=b[3],this.a=[].slice.call(a,1),this.K||(this.A="create"==this.C,this.i="require"==this.C,this.g="provide"==this.C,this.ba="remove"==this.C),this.i&&(3<=this.a.length?(this.X=this.a[1],this.W=this.a[2]):this.a[1]&&(qa(this.a[1])?this.X=this.a[1]:this.W=this.a[1])));b=a[1];a=a[2];if(!this.C)throw"abort";if(this.i&&(!qa(b)||""==b))throw"abort";
|
||||
if(this.g&&(!qa(b)||""==b||!ea(a)))throw"abort";if(ud(this.c)||ud(this.K))throw"abort";if(this.g&&"t0"!=this.c)throw"abort";}};function ud(a){return 0<=a.indexOf(".")||0<=a.indexOf(":")};var Yd,Zd,$d,A;Yd=new ee;$d=new ee;A=new ee;Zd={ec:45,ecommerce:46,linkid:47};
|
||||
var u=function(a,b,c){b==N||b.get(V);var d=Yd.get(a);if(!ea(d))return!1;b.plugins_=b.plugins_||new ee;if(b.plugins_.get(a))return!0;b.plugins_.set(a,new d(b,c||{}));return!0},y=function(a,b,c,d,e){if(!ea(Yd.get(b))&&!$d.get(b)){Zd.hasOwnProperty(b)&&J(Zd[b]);if(p.test(b)){J(52);a=N.j(a);if(!a)return!0;c=d||{};d={id:b,B:c.dataLayer||"dataLayer",ia:!!a.get("anonymizeIp"),sync:e,G:!1};a.get(">m")==b&&(d.G=!0);var g=String(a.get("name"));"t0"!=g&&(d.target=g);G(String(a.get("trackingId")))||(d.clientId=
|
||||
String(a.get(Q)),d.ka=Number(a.get(n)),c=c.palindrome?r:q,c=(c=M.cookie.replace(/^|(; +)/g,";").match(c))?c.sort().join("").substring(1):void 0,d.la=c,d.qa=E(a.b.get(kb)||"","gclid"));a=d.B;c=(new Date).getTime();O[a]=O[a]||[];c={"gtm.start":c};e||(c.event="gtm.js");O[a].push(c);c=t(d)}!c&&Zd.hasOwnProperty(b)?(J(39),c=b+".js"):J(43);c&&(c&&0<=c.indexOf("/")||(c=(Ba||"https:"==M.location.protocol?"https:":"http:")+"//www.google-analytics.com/plugins/ua/"+c),d=ae(c),a=d.protocol,c=M.location.protocol,
|
||||
("https:"==a||a==c||("http:"!=a?0:"http:"==c))&&B(d)&&(wa(d.url,void 0,e),$d.set(b,!0)))}},v=function(a,b){var c=A.get(a)||[];c.push(b);A.set(a,c)},C=function(a,b){Yd.set(a,b);b=A.get(a)||[];for(var c=0;c<b.length;c++)b[c]();A.set(a,[])},B=function(a){var b=ae(M.location.href);if(D(a.url,"https://www.google-analytics.com/gtm/js?id="))return!0;if(a.query||0<=a.url.indexOf("?")||0<=a.path.indexOf("://"))return!1;if(a.host==b.host&&a.port==b.port)return!0;b="http:"==a.protocol?80:443;return"www.google-analytics.com"==
|
||||
a.host&&(a.port||b)==b&&D(a.path,"/plugins/")?!0:!1},ae=function(a){function b(a){var b=a.hostname||"",c=0<=b.indexOf("]");b=b.split(c?"]":":")[0].toLowerCase();c&&(b+="]");c=(a.protocol||"").toLowerCase();c=1*a.port||("http:"==c?80:"https:"==c?443:"");a=a.pathname||"";D(a,"/")||(a="/"+a);return[b,""+c,a]}var c=M.createElement("a");c.href=M.location.href;var d=(c.protocol||"").toLowerCase(),e=b(c),g=c.search||"",ca=d+"//"+e[0]+(e[1]?":"+e[1]:"");D(a,"//")?a=d+a:D(a,"/")?a=ca+a:!a||D(a,"?")?a=ca+e[2]+
|
||||
(a||g):0>a.split("/")[0].indexOf(":")&&(a=ca+e[2].substring(0,e[2].lastIndexOf("/"))+"/"+a);c.href=a;d=b(c);return{protocol:(c.protocol||"").toLowerCase(),host:d[0],port:d[1],path:d[2],query:c.search||"",url:a||""}};var Z={ga:function(){Z.f=[]}};Z.ga();Z.D=function(a){var b=Z.J.apply(Z,arguments);b=Z.f.concat(b);for(Z.f=[];0<b.length&&!Z.v(b[0])&&!(b.shift(),0<Z.f.length););Z.f=Z.f.concat(b)};Z.J=function(a){for(var b=[],c=0;c<arguments.length;c++)try{var d=new sc(arguments[c]);d.g?C(d.a[0],d.a[1]):(d.i&&(d.ha=y(d.c,d.a[0],d.X,d.W)),b.push(d))}catch(e){}return b};
|
||||
Z.v=function(a){try{if(a.u)a.u.call(O,N.j("t0"));else{var b=a.c==gb?N:N.j(a.c);if(a.A){if("t0"==a.c&&(b=N.create.apply(N,a.a),null===b))return!0}else if(a.ba)N.remove(a.c);else if(b)if(a.i){if(a.ha&&(a.ha=y(a.c,a.a[0],a.X,a.W)),!u(a.a[0],b,a.W))return!0}else if(a.K){var c=a.C,d=a.a,e=b.plugins_.get(a.K);e[c].apply(e,d)}else b[a.C].apply(b,a.a)}}catch(g){}};var N=function(a){J(1);Z.D.apply(Z,[arguments])};N.h={};N.P=[];N.L=0;N.ya=0;N.answer=42;var uc=[Na,W,V];
|
||||
N.create=function(a){var b=za(uc,[].slice.call(arguments));b[V]||(b[V]="t0");var c=""+b[V];if(N.h[c])return N.h[c];a:{if(b[Kd]){J(67);if(b[ac]&&"cookie"!=b[ac]){var d=!1;break a}if(ja.test(M.referrer)){d=M.location.hostname.replace(Ue,"");var e=M.referrer.replace(/^https?:\/\//,"").replace(/^[^/]+/,"").split("/");var g=e[2];e=("s"==g?decodeURIComponent(e[3]):decodeURIComponent(g)).replace(Ue,"");d==e?(d=(d=De.get())&&d._ga||void 0,void 0!==d&&(Ab=d,J(81))):J(78)}if(void 0!==Ab)b[Q]||(b[Q]=Ab);else{b:if(d=
|
||||
String(b[W]||xa()),e=String(b[Yb]||"/"),g=Ca(String(b[U]||"_ga")),d=na(g,d,e),!d||jd.test(d))d=!0;else if(d=Ca("AMP_TOKEN"),0==d.length)d=!0;else{if(1==d.length&&(d=decodeURIComponent(d[0]),"$RETRIEVING"==d||"$OPT_OUT"==d||"$ERROR"==d||"$NOT_FOUND"==d)){d=!0;break b}d=!1}if(d&&tc(ic,String(b[Na]))){d=!0;break a}}}d=!1}if(d)return null;b=new pc(b);N.h[c]=b;N.P.push(b);return b};N.remove=function(a){for(var b=0;b<N.P.length;b++)if(N.P[b].get(V)==a){N.P.splice(b,1);N.h[a]=null;break}};N.j=function(a){return N.h[a]};
|
||||
N.getAll=function(){return N.P.slice(0)};
|
||||
N.N=function(){"ga"!=gb&&J(49);var a=O[gb];if(!a||42!=a.answer){N.L=a&&a.l;N.ya=1*new Date;N.loaded=!0;var b=O[gb]=N;X("create",b,b.create);X("remove",b,b.remove);X("getByName",b,b.j,5);X("getAll",b,b.getAll,6);b=pc.prototype;X("get",b,b.get,7);X("set",b,b.set,4);X("send",b,b.send);X("requireSync",b,b.ma);b=Ya.prototype;X("get",b,b.get);X("set",b,b.set);if("https:"!=M.location.protocol&&!Ba){a:{b=M.getElementsByTagName("script");for(var c=0;c<b.length&&100>c;c++){var d=b[c].src;if(d&&0==d.indexOf("https://www.google-analytics.com/analytics")){b=
|
||||
!0;break a}}b=!1}b&&(Ba=!0)}(O.gaplugins=O.gaplugins||{}).Linker=Dc;b=Dc.prototype;C("linker",Dc);X("decorate",b,b.ca,20);X("autoLink",b,b.S,25);C("displayfeatures",fd);C("adfeatures",fd);a=a&&a.q;ka(a)?Z.D.apply(N,a):J(50)}};N.da=function(){for(var a=N.getAll(),b=0;b<a.length;b++)a[b].get(V)};var bf=N.N,cf=O[gb];cf&&cf.r?bf():z(bf);z(function(){Z.D(["provide","render",ua])});})(window);
|
7
e2e/pages/bootstrap/assets/bootstrap.min.css
vendored
Normal file
7
e2e/pages/bootstrap/assets/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
e2e/pages/bootstrap/assets/bootstrap.min.js
vendored
Normal file
7
e2e/pages/bootstrap/assets/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
e2e/pages/bootstrap/assets/carbon.js
Normal file
1
e2e/pages/bootstrap/assets/carbon.js
Normal file
File diff suppressed because one or more lines are too long
8
e2e/pages/bootstrap/assets/docs.min.css
vendored
Normal file
8
e2e/pages/bootstrap/assets/docs.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
28
e2e/pages/bootstrap/assets/docs.min.js
vendored
Normal file
28
e2e/pages/bootstrap/assets/docs.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
e2e/pages/bootstrap/assets/docsearch.min.css
vendored
Normal file
2
e2e/pages/bootstrap/assets/docsearch.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
e2e/pages/bootstrap/assets/docsearch.min.js
vendored
Normal file
2
e2e/pages/bootstrap/assets/docsearch.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
e2e/pages/bootstrap/assets/jquery-3.3.1.slim.min.js
vendored
Normal file
2
e2e/pages/bootstrap/assets/jquery-3.3.1.slim.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
e2e/pages/bootstrap/assets/popper.min.js
vendored
Normal file
5
e2e/pages/bootstrap/assets/popper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2239
e2e/pages/bootstrap/grid.html
Normal file
2239
e2e/pages/bootstrap/grid.html
Normal file
File diff suppressed because one or more lines are too long
1159
e2e/pages/bootstrap/media.html
Normal file
1159
e2e/pages/bootstrap/media.html
Normal file
File diff suppressed because one or more lines are too long
565
e2e/pages/bootstrap/overview.html
Normal file
565
e2e/pages/bootstrap/overview.html
Normal file
@ -0,0 +1,565 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- saved from url=(0049) -->
|
||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="Components and options for laying out your Bootstrap project, including wrapping containers, a powerful grid system, a flexible media object, and responsive utility classes.">
|
||||
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
|
||||
<meta name="generator" content="Jekyll v3.8.3">
|
||||
|
||||
<title>Overview · Bootstrap</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
|
||||
<style class="anchorjs"></style><link href="./assets/bootstrap.min.css" rel="stylesheet" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
|
||||
|
||||
<!-- Documentation extras -->
|
||||
|
||||
<link href="./assets/docsearch.min.css" rel="stylesheet">
|
||||
|
||||
<link href="./assets/docs.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Favicons -->
|
||||
<link rel="apple-touch-icon" href="http://getbootstrap.com/docs/4.1/assets/img/favicons/apple-touch-icon.png" sizes="180x180">
|
||||
<link rel="icon" href="http://getbootstrap.com/docs/4.1/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png">
|
||||
<link rel="icon" href="http://getbootstrap.com/docs/4.1/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png">
|
||||
<link rel="manifest" href="http://getbootstrap.com/docs/4.1/assets/img/favicons/manifest.json">
|
||||
<link rel="mask-icon" href="http://getbootstrap.com/docs/4.1/assets/img/favicons/safari-pinned-tab.svg" color="#563d7c">
|
||||
<link rel="icon" href="http://getbootstrap.com/favicon.ico">
|
||||
<meta name="msapplication-config" content="/docs/4.1/assets/img/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#563d7c">
|
||||
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@getbootstrap">
|
||||
<meta name="twitter:creator" content="@getbootstrap">
|
||||
<meta name="twitter:title" content="Overview">
|
||||
<meta name="twitter:description" content="Components and options for laying out your Bootstrap project, including wrapping containers, a powerful grid system, a flexible media object, and responsive utility classes.">
|
||||
<meta name="twitter:image" content="https://getbootstrap.com/docs/4.1/assets/brand/bootstrap-social-logo.png">
|
||||
|
||||
<!-- Facebook -->
|
||||
<meta property="og:url" content="https://getbootstrap.com/docs/4.1/layout/overview/">
|
||||
<meta property="og:title" content="Overview">
|
||||
<meta property="og:description" content="Components and options for laying out your Bootstrap project, including wrapping containers, a powerful grid system, a flexible media object, and responsive utility classes.">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="http://getbootstrap.com/docs/4.1/assets/brand/bootstrap-social.png">
|
||||
<meta property="og:image:secure_url" content="https://getbootstrap.com/docs/4.1/assets/brand/bootstrap-social.png">
|
||||
<meta property="og:image:type" content="image/png">
|
||||
<meta property="og:image:width" content="1200">
|
||||
<meta property="og:image:height" content="630">
|
||||
|
||||
|
||||
<script>
|
||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
ga('create', 'UA-146052-10', 'getbootstrap.com');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
<script async="" src="./assets/analytics.js"></script>
|
||||
|
||||
<script id="_carbonads_projs" type="text/javascript" src="./assets/CKYIKKJL.json"></script></head>
|
||||
<body>
|
||||
<a id="skippy" class="sr-only sr-only-focusable" href="#content">
|
||||
<div class="container">
|
||||
<span class="skiplink-text">Skip to main content</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
|
||||
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bd-navbar">
|
||||
<a class="navbar-brand mr-0 mr-md-2" href="http://getbootstrap.com/" aria-label="Bootstrap"><svg class="d-block" width="36" height="36" viewBox="0 0 612 612" xmlns="http://www.w3.org/2000/svg" focusable="false"><title>Bootstrap</title><path fill="currentColor" d="M510 8a94.3 94.3 0 0 1 94 94v408a94.3 94.3 0 0 1-94 94H102a94.3 94.3 0 0 1-94-94V102a94.3 94.3 0 0 1 94-94h408m0-8H102C45.9 0 0 45.9 0 102v408c0 56.1 45.9 102 102 102h408c56.1 0 102-45.9 102-102V102C612 45.9 566.1 0 510 0z"></path><path fill="currentColor" d="M196.77 471.5V154.43h124.15c54.27 0 91 31.64 91 79.1 0 33-24.17 63.72-54.71 69.21v1.76c43.07 5.49 70.75 35.82 70.75 78 0 55.81-40 89-107.45 89zm39.55-180.4h63.28c46.8 0 72.29-18.68 72.29-53 0-31.42-21.53-48.78-60-48.78h-75.57zm78.22 145.46c47.68 0 72.73-19.34 72.73-56s-25.93-55.37-76.46-55.37h-74.49v111.4z"></path></svg>
|
||||
</a>
|
||||
|
||||
<div class="navbar-nav-scroll">
|
||||
<ul class="navbar-nav bd-navbar-nav flex-row">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="http://getbootstrap.com/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Bootstrap');">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="http://getbootstrap.com/docs/4.1/getting-started/introduction/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Docs');">Documentation</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link " href="http://getbootstrap.com/docs/4.1/examples/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Examples');">Examples</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://themes.getbootstrap.com/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Themes');" target="_blank" rel="noopener">Themes</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://expo.getbootstrap.com/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Expo');" target="_blank" rel="noopener">Expo</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://blog.getbootstrap.com/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Blog');" target="_blank" rel="noopener">Blog</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" id="bd-versions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
v4.1
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="bd-versions">
|
||||
<a class="dropdown-item active" href="http://getbootstrap.com/docs/4.1/">Latest (4.1.x)</a>
|
||||
<a class="dropdown-item" href="https://getbootstrap.com/docs/4.0/">v4.0.0</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="https://v4-alpha.getbootstrap.com/">v4 Alpha 6</a>
|
||||
<a class="dropdown-item" href="https://getbootstrap.com/docs/3.3/">v3.3.7</a>
|
||||
<a class="dropdown-item" href="https://getbootstrap.com/2.3.2/">v2.3.2</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://github.com/twbs/bootstrap" target="_blank" rel="noopener" aria-label="GitHub"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://twitter.com/getbootstrap" target="_blank" rel="noopener" aria-label="Twitter"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 416.32" focusable="false"><title>Twitter</title><path d="M160.83 416.32c193.2 0 298.92-160.22 298.92-298.92 0-4.51 0-9-.2-13.52A214 214 0 0 0 512 49.38a212.93 212.93 0 0 1-60.44 16.6 105.7 105.7 0 0 0 46.3-58.19 209 209 0 0 1-66.79 25.37 105.09 105.09 0 0 0-181.73 71.91 116.12 116.12 0 0 0 2.66 24c-87.28-4.3-164.73-46.3-216.56-109.82A105.48 105.48 0 0 0 68 159.6a106.27 106.27 0 0 1-47.53-13.11v1.43a105.28 105.28 0 0 0 84.21 103.06 105.67 105.67 0 0 1-47.33 1.84 105.06 105.06 0 0 0 98.14 72.94A210.72 210.72 0 0 1 25 370.84a202.17 202.17 0 0 1-25-1.43 298.85 298.85 0 0 0 160.83 46.92" fill="currentColor"></path></svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link p-2" href="https://bootstrap-slack.herokuapp.com/" target="_blank" rel="noopener" aria-label="Slack"><svg class="navbar-nav-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" focusable="false"><title>Slack</title><path fill="currentColor" d="M210.787 234.832l68.31-22.883 22.1 65.977-68.309 22.882z"></path><path d="M490.54 185.6C437.7 9.59 361.6-31.34 185.6 21.46S-31.3 150.4 21.46 326.4 150.4 543.3 326.4 490.54 543.34 361.6 490.54 185.6zM401.7 299.8l-33.15 11.05 11.46 34.38c4.5 13.92-2.87 29.06-16.78 33.56-2.87.82-6.14 1.64-9 1.23a27.32 27.32 0 0 1-24.56-18l-11.46-34.38-68.36 22.92 11.46 34.38c4.5 13.92-2.87 29.06-16.78 33.56-2.87.82-6.14 1.64-9 1.23a27.32 27.32 0 0 1-24.56-18l-11.46-34.43-33.15 11.05c-2.87.82-6.14 1.64-9 1.23a27.32 27.32 0 0 1-24.56-18c-4.5-13.92 2.87-29.06 16.78-33.56l33.12-11.03-22.1-65.9-33.15 11.05c-2.87.82-6.14 1.64-9 1.23a27.32 27.32 0 0 1-24.56-18c-4.48-13.93 2.89-29.07 16.81-33.58l33.15-11.05-11.46-34.38c-4.5-13.92 2.87-29.06 16.78-33.56s29.06 2.87 33.56 16.78l11.46 34.38 68.36-22.92-11.46-34.38c-4.5-13.92 2.87-29.06 16.78-33.56s29.06 2.87 33.56 16.78l11.47 34.42 33.15-11.05c13.92-4.5 29.06 2.87 33.56 16.78s-2.87 29.06-16.78 33.56L329.7 194.6l22.1 65.9 33.15-11.05c13.92-4.5 29.06 2.87 33.56 16.78s-2.88 29.07-16.81 33.57z" fill="currentColor"></path></svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<a class="btn btn-bd-download d-none d-lg-inline-block mb-3 mb-md-0 ml-md-3" href="http://getbootstrap.com/docs/4.1/getting-started/download/">Download</a>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row flex-xl-nowrap">
|
||||
<div class="col-12 col-md-3 col-xl-2 bd-sidebar">
|
||||
<form class="bd-search d-flex align-items-center">
|
||||
<span class="algolia-autocomplete" style="position: relative; display: inline-block; direction: ltr;"><input type="search" class="form-control ds-input" id="search-input" placeholder="Search..." autocomplete="off" data-siteurl="https://getbootstrap.com" data-docs-version="4.1" spellcheck="false" role="combobox" aria-autocomplete="list" aria-expanded="false" aria-owns="algolia-autocomplete-listbox-0" dir="auto" style="position: relative; vertical-align: top;"><pre aria-hidden="true" style="position: absolute; visibility: hidden; white-space: pre; font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; word-spacing: 0px; letter-spacing: normal; text-indent: 0px; text-rendering: auto; text-transform: none;"></pre><span class="ds-dropdown-menu" role="listbox" id="algolia-autocomplete-listbox-0" style="position: absolute; top: 100%; z-index: 100; display: none; left: 0px; right: auto;"><div class="ds-dataset-1"></div></span></span>
|
||||
<button class="btn btn-link bd-search-docs-toggle d-md-none p-0 ml-3" type="button" data-toggle="collapse" data-target="#bd-docs-nav" aria-controls="bd-docs-nav" aria-expanded="false" aria-label="Toggle docs navigation"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30" height="30" focusable="false"><title>Menu</title><path stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M4 7h22M4 15h22M4 23h22"></path></svg>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<nav class="collapse bd-links" id="bd-docs-nav"><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/getting-started/introduction/">
|
||||
Getting started
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/introduction/">
|
||||
Introduction
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/download/">
|
||||
Download
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/contents/">
|
||||
Contents
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/browsers-devices/">
|
||||
Browsers & devices
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/javascript/">
|
||||
JavaScript
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/theming/">
|
||||
Theming
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/build-tools/">
|
||||
Build tools
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/webpack/">
|
||||
Webpack
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/getting-started/accessibility/">
|
||||
Accessibility
|
||||
</a></li></ul>
|
||||
</div><div class="bd-toc-item active">
|
||||
<a class="bd-toc-link" href="">
|
||||
Layout
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li class="active bd-sidenav-active">
|
||||
<a href="overview.html">
|
||||
Overview
|
||||
</a></li><li>
|
||||
<a href="grid.html">
|
||||
Grid
|
||||
</a></li><li>
|
||||
<a href="media.html">
|
||||
Media object
|
||||
</a></li><li>
|
||||
<a href="utilities.html">
|
||||
Utilities for layout
|
||||
</a></li></ul>
|
||||
</div><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/content/reboot/">
|
||||
Content
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/content/reboot/">
|
||||
Reboot
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/content/typography/">
|
||||
Typography
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/content/code/">
|
||||
Code
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/content/images/">
|
||||
Images
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/content/tables/">
|
||||
Tables
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/content/figures/">
|
||||
Figures
|
||||
</a></li></ul>
|
||||
</div><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/components/alerts/">
|
||||
Components
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/alerts/">
|
||||
Alerts
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/badge/">
|
||||
Badge
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/breadcrumb/">
|
||||
Breadcrumb
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/buttons/">
|
||||
Buttons
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/button-group/">
|
||||
Button group
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/card/">
|
||||
Card
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/carousel/">
|
||||
Carousel
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/collapse/">
|
||||
Collapse
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/dropdowns/">
|
||||
Dropdowns
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/forms/">
|
||||
Forms
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/input-group/">
|
||||
Input group
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/jumbotron/">
|
||||
Jumbotron
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/list-group/">
|
||||
List group
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/modal/">
|
||||
Modal
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/navs/">
|
||||
Navs
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/navbar/">
|
||||
Navbar
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/pagination/">
|
||||
Pagination
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/popovers/">
|
||||
Popovers
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/progress/">
|
||||
Progress
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/scrollspy/">
|
||||
Scrollspy
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/components/tooltips/">
|
||||
Tooltips
|
||||
</a></li></ul>
|
||||
</div><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/utilities/borders/">
|
||||
Utilities
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/borders/">
|
||||
Borders
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/clearfix/">
|
||||
Clearfix
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/close-icon/">
|
||||
Close icon
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/colors/">
|
||||
Colors
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/display/">
|
||||
Display
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/embed/">
|
||||
Embed
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/flex/">
|
||||
Flex
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/float/">
|
||||
Float
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/image-replacement/">
|
||||
Image replacement
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/position/">
|
||||
Position
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/screenreaders/">
|
||||
Screenreaders
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/shadows/">
|
||||
Shadows
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/sizing/">
|
||||
Sizing
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/spacing/">
|
||||
Spacing
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/text/">
|
||||
Text
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/vertical-align/">
|
||||
Vertical align
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/utilities/visibility/">
|
||||
Visibility
|
||||
</a></li></ul>
|
||||
</div><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/extend/approach/">
|
||||
Extend
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/extend/approach/">
|
||||
Approach
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/extend/icons/">
|
||||
Icons
|
||||
</a></li></ul>
|
||||
</div><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/migration/">
|
||||
Migration
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"></ul>
|
||||
</div><div class="bd-toc-item">
|
||||
<a class="bd-toc-link" href="http://getbootstrap.com/docs/4.1/about/overview/">
|
||||
About
|
||||
</a>
|
||||
|
||||
<ul class="nav bd-sidenav"><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/about/overview/">
|
||||
Overview
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/about/brand/">
|
||||
Brand
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/about/license/">
|
||||
License
|
||||
</a></li><li>
|
||||
<a href="http://getbootstrap.com/docs/4.1/about/translations/">
|
||||
Translations
|
||||
</a></li></ul>
|
||||
</div></nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="d-none d-xl-block col-xl-2 bd-toc">
|
||||
<ul class="section-nav">
|
||||
<li class="toc-entry toc-h2"><a href="#containers">Containers</a></li>
|
||||
<li class="toc-entry toc-h2"><a href="#responsive-breakpoints">Responsive breakpoints</a></li>
|
||||
<li class="toc-entry toc-h2"><a href="#z-index">Z-index</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<main class="col-12 col-md-9 col-xl-8 py-md-3 pl-md-5 bd-content" role="main">
|
||||
<h1 class="bd-title" id="content">Overview</h1>
|
||||
<p class="bd-lead">Components and options for laying out your Bootstrap project, including wrapping containers, a powerful grid system, a flexible media object, and responsive utility classes.</p>
|
||||
<script async="" src="./assets/carbon.js" id="_carbonads_js"></script><div id="carbonads"><span><span class="carbon-wrap"><a href="http://srv.carbonads.net/ads/click/x/GTND42QIF6BI5KQNCV74YKQMCKAIV5QECABDVZ3JCW7ILK7YCASI453KC6BIC5QMCEYDTK3EHJNCLSIZ?segment=placement:getbootstrapcom;" class="carbon-img" target="_blank" rel="noopener"><img src="./assets/1538328304-Slack-pink_logo.png" alt="" border="0" height="100" width="130" style="max-width: 130px;"></a><a href="http://srv.carbonads.net/ads/click/x/GTND42QIF6BI5KQNCV74YKQMCKAIV5QECABDVZ3JCW7ILK7YCASI453KC6BIC5QMCEYDTK3EHJNCLSIZ?segment=placement:getbootstrapcom;" class="carbon-text" target="_blank" rel="noopener">It's teamwork, but simpler, more pleasant and more productive.</a></span><a href="http://carbonads.net/?utm_source=getbootstrapcom&utm_medium=ad_via_link&utm_campaign=in_unit&utm_term=carbon" class="carbon-poweredby" target="_blank" rel="noopener">ads via Carbon</a><img src="./assets/B21259774.226039675" border="0" height="1" width="1" style="display: none;"></span></div>
|
||||
|
||||
<h2 id="containers"><div>Containers<a class="anchorjs-link " href="#containers" aria-label="Anchor" data-anchorjs-icon="#" style="padding-left: 0.375em;"></a></div></h2>
|
||||
|
||||
<p>Containers are the most basic layout element in Bootstrap and are <strong>required when using our default grid system</strong>. Choose from a responsive, fixed-width container (meaning its <code class="highlighter-rouge">max-width</code> changes at each breakpoint) or fluid-width (meaning it’s <code class="highlighter-rouge">100%</code> wide all the time).</p>
|
||||
|
||||
<p>While containers <em>can</em> be nested, most layouts do not require a nested container.</p>
|
||||
|
||||
<div class="bd-example">
|
||||
<div class="bd-example-container">
|
||||
<div class="bd-example-container-header"></div>
|
||||
<div class="bd-example-container-sidebar"></div>
|
||||
<div class="bd-example-container-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">></span>
|
||||
<span class="c"><!-- Content here --></span>
|
||||
<span class="nt"></div></span></code></pre></figure>
|
||||
|
||||
<p>Use <code class="highlighter-rouge">.container-fluid</code> for a full width container, spanning the entire width of the viewport.</p>
|
||||
|
||||
<div class="bd-example">
|
||||
<div class="bd-example-container bd-example-container-fluid">
|
||||
<div class="bd-example-container-header"></div>
|
||||
<div class="bd-example-container-sidebar"></div>
|
||||
<div class="bd-example-container-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">class=</span><span class="s">"container-fluid"</span><span class="nt">></span>
|
||||
...
|
||||
<span class="nt"></div></span></code></pre></figure>
|
||||
|
||||
<h2 id="responsive-breakpoints"><div>Responsive breakpoints<a class="anchorjs-link " href="#responsive-breakpoints" aria-label="Anchor" data-anchorjs-icon="#" style="padding-left: 0.375em;"></a></div></h2>
|
||||
|
||||
<p>Since Bootstrap is developed to be mobile first, we use a handful of <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries">media queries</a> to create sensible breakpoints for our layouts and interfaces. These breakpoints are mostly based on minimum viewport widths and allow us to scale up elements as the viewport changes.</p>
|
||||
|
||||
<p>Bootstrap primarily uses the following media query ranges—or breakpoints—in our source Sass files for our layout, grid system, and components.</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// Extra small devices (portrait phones, less than 576px)</span>
|
||||
<span class="c1">// No media query for `xs` since this is the default in Bootstrap</span>
|
||||
|
||||
<span class="c1">// Small devices (landscape phones, 576px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">576px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Medium devices (tablets, 768px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">768px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Large devices (desktops, 992px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">992px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Extra large devices (large desktops, 1200px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">1200px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span></code></pre></figure>
|
||||
|
||||
<p>Since we write our source CSS in Sass, all our media queries are available via Sass mixins:</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// No media query necessary for xs breakpoint as it's effectively `@media (min-width: 0) { ... }`</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-up</span><span class="p">(</span><span class="n">sm</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-up</span><span class="p">(</span><span class="n">md</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-up</span><span class="p">(</span><span class="n">lg</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-up</span><span class="p">(</span><span class="n">xl</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Example: Hide starting at `min-width: 0`, and then show at the `sm` breakpoint</span>
|
||||
<span class="nc">.custom-class</span> <span class="p">{</span>
|
||||
<span class="nl">display</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-up</span><span class="p">(</span><span class="n">sm</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nc">.custom-class</span> <span class="p">{</span>
|
||||
<span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span></code></pre></figure>
|
||||
|
||||
<p>We occasionally use media queries that go in the other direction (the given screen size <em>or smaller</em>):</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// Extra small devices (portrait phones, less than 576px)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">575</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Small devices (landscape phones, less than 768px)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">767</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Medium devices (tablets, less than 992px)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">991</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Large devices (desktops, less than 1200px)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">1199</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Extra large devices (large desktops)</span>
|
||||
<span class="c1">// No media query since the extra-large breakpoint has no upper bound on its width</span></code></pre></figure>
|
||||
|
||||
<div class="bd-callout bd-callout-info">
|
||||
<p>Note that since browsers do not currently support <a href="https://www.w3.org/TR/mediaqueries-4/#range-context">range context queries</a>, we work around the limitations of <a href="https://www.w3.org/TR/mediaqueries-4/#mq-min-max"><code class="highlighter-rouge">min-</code> and <code class="highlighter-rouge">max-</code> prefixes</a> and viewports with fractional widths (which can occur under certain conditions on high-dpi devices, for instance) by using values with higher precision for these comparisons.</p>
|
||||
</div>
|
||||
|
||||
<p>Once again, these media queries are also available via Sass mixins:</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="k">@include</span> <span class="nd">media-breakpoint-down</span><span class="p">(</span><span class="n">xs</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-down</span><span class="p">(</span><span class="n">sm</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-down</span><span class="p">(</span><span class="n">md</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-down</span><span class="p">(</span><span class="n">lg</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="c1">// No media query necessary for xl breakpoint as it has no upper bound on its width</span>
|
||||
|
||||
<span class="c1">// Example: Style from medium breakpoint and down</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-down</span><span class="p">(</span><span class="n">md</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nc">.custom-class</span> <span class="p">{</span>
|
||||
<span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span></code></pre></figure>
|
||||
|
||||
<p>There are also media queries and mixins for targeting a single segment of screen sizes using the minimum and maximum breakpoint widths.</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// Extra small devices (portrait phones, less than 576px)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">575</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Small devices (landscape phones, 576px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">576px</span><span class="p">)</span> <span class="nf">and</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">767</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Medium devices (tablets, 768px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">768px</span><span class="p">)</span> <span class="nf">and</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">991</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Large devices (desktops, 992px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">992px</span><span class="p">)</span> <span class="nf">and</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">1199</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
|
||||
<span class="c1">// Extra large devices (large desktops, 1200px and up)</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">1200px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span></code></pre></figure>
|
||||
|
||||
<p>These media queries are also available via Sass mixins:</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="k">@include</span> <span class="nd">media-breakpoint-only</span><span class="p">(</span><span class="n">xs</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-only</span><span class="p">(</span><span class="n">sm</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-only</span><span class="p">(</span><span class="n">md</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-only</span><span class="p">(</span><span class="n">lg</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span>
|
||||
<span class="k">@include</span> <span class="nd">media-breakpoint-only</span><span class="p">(</span><span class="n">xl</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span></code></pre></figure>
|
||||
|
||||
<p>Similarly, media queries may span multiple breakpoint widths:</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="c1">// Example</span>
|
||||
<span class="c1">// Apply styles starting from medium devices and up to extra large devices</span>
|
||||
<span class="k">@media</span> <span class="p">(</span><span class="n">min-width</span><span class="o">:</span> <span class="m">768px</span><span class="p">)</span> <span class="nf">and</span> <span class="p">(</span><span class="n">max-width</span><span class="o">:</span> <span class="m">1199</span><span class="mi">.98px</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span></code></pre></figure>
|
||||
|
||||
<p>The Sass mixin for targeting the same screen size range would be:</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="k">@include</span> <span class="nd">media-breakpoint-between</span><span class="p">(</span><span class="n">md</span><span class="o">,</span> <span class="n">xl</span><span class="p">)</span> <span class="p">{</span> <span class="nc">...</span> <span class="p">}</span></code></pre></figure>
|
||||
|
||||
<h2 id="z-index"><div>Z-index<a class="anchorjs-link " href="#z-index" aria-label="Anchor" data-anchorjs-icon="#" style="padding-left: 0.375em;"></a></div></h2>
|
||||
|
||||
<p>Several Bootstrap components utilize <code class="highlighter-rouge">z-index</code>, the CSS property that helps control layout by providing a third axis to arrange content. We utilize a default z-index scale in Bootstrap that’s been designed to properly layer navigation, tooltips and popovers, modals, and more.</p>
|
||||
|
||||
<p>These higher values start at an arbitrary number, high and specific enough to ideally avoid conflicts. We need a standard set of these across our layered components—tooltips, popovers, navbars, dropdowns, modals—so we can be reasonably consistent in the behaviors. There’s no reason we couldn’t have used <code class="highlighter-rouge">100</code>+ or <code class="highlighter-rouge">500</code>+.</p>
|
||||
|
||||
<p>We don’t encourage customization of these individual values; should you change one, you likely need to change them all.</p>
|
||||
|
||||
<div class="bd-clipboard"><button class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</button></div><figure class="highlight"><pre><code class="language-scss" data-lang="scss"><span class="nv">$zindex-dropdown</span><span class="p">:</span> <span class="m">1000</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span>
|
||||
<span class="nv">$zindex-sticky</span><span class="p">:</span> <span class="m">1020</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span>
|
||||
<span class="nv">$zindex-fixed</span><span class="p">:</span> <span class="m">1030</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span>
|
||||
<span class="nv">$zindex-modal-backdrop</span><span class="p">:</span> <span class="m">1040</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span>
|
||||
<span class="nv">$zindex-modal</span><span class="p">:</span> <span class="m">1050</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span>
|
||||
<span class="nv">$zindex-popover</span><span class="p">:</span> <span class="m">1060</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span>
|
||||
<span class="nv">$zindex-tooltip</span><span class="p">:</span> <span class="m">1070</span> <span class="o">!</span><span class="nb">default</span><span class="p">;</span></code></pre></figure>
|
||||
|
||||
<p>To handle overlapping borders within components (e.g., buttons and inputs in input groups), we use low single digit <code class="highlighter-rouge">z-index</code> values of <code class="highlighter-rouge">1</code>, <code class="highlighter-rouge">2</code>, and <code class="highlighter-rouge">3</code> for default, hover, and active states. On hover/focus/active, we bring a particular element to the forefront with a higher <code class="highlighter-rouge">z-index</code> value to show their border over the sibling elements.</p>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="./assets/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script>window.jQuery || document.write('<script src="/assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
|
||||
|
||||
<script src="./assets/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script><script src="./assets/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script><script src="./assets/docsearch.min.js"></script><script src="./assets/docs.min.js"></script>
|
||||
|
||||
|
||||
</body></html>
|
967
e2e/pages/bootstrap/utilities.html
Normal file
967
e2e/pages/bootstrap/utilities.html
Normal file
File diff suppressed because one or more lines are too long
28
e2e/runner/lib.go
Normal file
28
e2e/runner/lib.go
Normal file
@ -0,0 +1,28 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||||
)
|
||||
|
||||
func Assertions() map[string]core.Function {
|
||||
return map[string]core.Function{
|
||||
"EXPECT": expect,
|
||||
}
|
||||
}
|
||||
|
||||
func expect(_ context.Context, args ...core.Value) (core.Value, error) {
|
||||
err := core.ValidateArgs(args, 2, 2)
|
||||
|
||||
if err != nil {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
if args[0].Compare(args[1]) == 0 {
|
||||
return values.EmptyString, nil
|
||||
}
|
||||
|
||||
return values.NewString(fmt.Sprintf(`expected "%s"", but got "%s"`, args[0], args[1])), nil
|
||||
}
|
196
e2e/runner/runner.go
Normal file
196
e2e/runner/runner.go
Normal file
@ -0,0 +1,196 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/MontFerret/ferret/pkg/compiler"
|
||||
"github.com/MontFerret/ferret/pkg/runtime"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
Settings struct {
|
||||
ServerAddress string
|
||||
CDPAddress string
|
||||
Dir string
|
||||
}
|
||||
|
||||
Result struct {
|
||||
name string
|
||||
duration time.Duration
|
||||
err error
|
||||
}
|
||||
|
||||
Summary struct {
|
||||
passed int
|
||||
failed int
|
||||
duration time.Duration
|
||||
}
|
||||
|
||||
Runner struct {
|
||||
logger zerolog.Logger
|
||||
settings Settings
|
||||
}
|
||||
)
|
||||
|
||||
func New(logger zerolog.Logger, settings Settings) *Runner {
|
||||
return &Runner{
|
||||
logger,
|
||||
settings,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) Run() error {
|
||||
results, err := r.runQueries(r.settings.Dir)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sum := r.report(results)
|
||||
|
||||
var event *zerolog.Event
|
||||
|
||||
if sum.failed == 0 {
|
||||
event = r.logger.Info()
|
||||
} else {
|
||||
event = r.logger.Error()
|
||||
}
|
||||
|
||||
event.
|
||||
Timestamp().
|
||||
Int("passed", sum.passed).
|
||||
Int("failed", sum.failed).
|
||||
Dur("time", sum.duration).
|
||||
Msg("Completed")
|
||||
|
||||
if sum.failed > 0 {
|
||||
return errors.New("failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runner) runQueries(dir string) ([]Result, error) {
|
||||
files, err := ioutil.ReadDir(dir)
|
||||
|
||||
if err != nil {
|
||||
r.logger.Error().
|
||||
Timestamp().
|
||||
Err(err).
|
||||
Str("dir", dir).
|
||||
Msg("failed to read scripts directory")
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := make([]Result, 0, len(files))
|
||||
|
||||
c := compiler.New()
|
||||
c.RegisterFunctions(Assertions())
|
||||
|
||||
// read scripts
|
||||
for _, f := range files {
|
||||
fName := filepath.Join(dir, f.Name())
|
||||
b, err := ioutil.ReadFile(fName)
|
||||
|
||||
if err != nil {
|
||||
results = append(results, Result{
|
||||
name: fName,
|
||||
err: errors.Wrap(err, "failed to read script file"),
|
||||
})
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, r.runQuery(c, fName, string(b)))
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (r *Runner) runQuery(c *compiler.FqlCompiler, name, script string) Result {
|
||||
start := time.Now()
|
||||
|
||||
p, err := c.Compile(script)
|
||||
|
||||
if err != nil {
|
||||
return Result{
|
||||
name: name,
|
||||
duration: time.Duration(0) * time.Millisecond,
|
||||
err: errors.Wrap(err, "failed to compile query"),
|
||||
}
|
||||
}
|
||||
|
||||
out, err := p.Run(
|
||||
context.Background(),
|
||||
runtime.WithBrowser(r.settings.CDPAddress),
|
||||
runtime.WithParam("server", r.settings.ServerAddress),
|
||||
)
|
||||
|
||||
duration := time.Now().Sub(start)
|
||||
|
||||
if err != nil {
|
||||
return Result{
|
||||
name: name,
|
||||
duration: duration,
|
||||
err: errors.Wrap(err, "failed to execute query"),
|
||||
}
|
||||
}
|
||||
|
||||
var result string
|
||||
|
||||
json.Unmarshal(out, &result)
|
||||
|
||||
if result == "" {
|
||||
return Result{
|
||||
name: name,
|
||||
duration: duration,
|
||||
}
|
||||
}
|
||||
|
||||
return Result{
|
||||
name: name,
|
||||
duration: duration,
|
||||
err: errors.New(result),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) report(results []Result) Summary {
|
||||
var failed int
|
||||
var passed int
|
||||
var sumDuration time.Duration
|
||||
|
||||
for _, res := range results {
|
||||
if res.err != nil {
|
||||
r.logger.Error().
|
||||
Timestamp().
|
||||
Err(res.err).
|
||||
Str("file", res.name).
|
||||
Dur("time", res.duration).
|
||||
Msg("Test failed")
|
||||
|
||||
failed++
|
||||
} else {
|
||||
r.logger.Info().
|
||||
Timestamp().
|
||||
Str("file", res.name).
|
||||
Dur("time", res.duration).
|
||||
Msg("Test passed")
|
||||
|
||||
passed++
|
||||
}
|
||||
|
||||
sumDuration += res.duration
|
||||
}
|
||||
|
||||
return Summary{
|
||||
passed: passed,
|
||||
failed: failed,
|
||||
duration: sumDuration,
|
||||
}
|
||||
}
|
36
e2e/server/server.go
Normal file
36
e2e/server/server.go
Normal file
@ -0,0 +1,36 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/labstack/echo"
|
||||
)
|
||||
|
||||
type (
|
||||
Settings struct {
|
||||
Port uint64
|
||||
Dir string
|
||||
}
|
||||
Server struct {
|
||||
engine *echo.Echo
|
||||
settings Settings
|
||||
}
|
||||
)
|
||||
|
||||
func New(settings Settings) *Server {
|
||||
e := echo.New()
|
||||
e.Debug = false
|
||||
e.HideBanner = true
|
||||
|
||||
e.Static("/", settings.Dir)
|
||||
|
||||
return &Server{e, settings}
|
||||
}
|
||||
|
||||
func (s *Server) Start() error {
|
||||
return s.engine.Start(fmt.Sprintf("0.0.0.0:%d", s.settings.Port))
|
||||
}
|
||||
|
||||
func (s *Server) Stop(ctx context.Context) error {
|
||||
return s.engine.Shutdown(ctx)
|
||||
}
|
7
e2e/tests/inner_html.fql
Normal file
7
e2e/tests/inner_html.fql
Normal file
@ -0,0 +1,7 @@
|
||||
LET url = @server + '/bootstrap/overview.html'
|
||||
LET doc = DOCUMENT(url)
|
||||
|
||||
LET expected = '<li class="toc-entry toc-h2"><a href="#containers">Containers</a></li><li class="toc-entry toc-h2"><a href="#responsive-breakpoints">Responsive breakpoints</a></li><li class="toc-entry toc-h2"><a href="#z-index">Z-index</a></li>'
|
||||
LET actual = INNER_HTML(doc, '.section-nav')
|
||||
|
||||
RETURN EXPECT(REGEXP_REPLACE(expected, '\s', ''), REGEXP_REPLACE(TRIM(actual), '(\n|\s)', ''))
|
11
e2e/tests/inner_html_all.fql
Normal file
11
e2e/tests/inner_html_all.fql
Normal file
@ -0,0 +1,11 @@
|
||||
LET url = @server + '/bootstrap/overview.html'
|
||||
LET doc = DOCUMENT(url)
|
||||
|
||||
LET expected = [
|
||||
'<a href="#containers">Containers</a>',
|
||||
'<a href="#responsive-breakpoints">Responsive breakpoints</a>',
|
||||
'<a href="#z-index">Z-index</a>'
|
||||
]
|
||||
LET actual = INNER_HTML_ALL(doc, '.section-nav li')
|
||||
|
||||
RETURN EXPECT(expected, actual)
|
10
e2e/tests/inner_html_dynamic.fql
Normal file
10
e2e/tests/inner_html_dynamic.fql
Normal file
@ -0,0 +1,10 @@
|
||||
// LET url = @server + '/bootstrap/overview.html'
|
||||
// LET doc = DOCUMENT(url, true)
|
||||
// LET selector = '.section-nav'
|
||||
|
||||
// LET expected = '<li class="toc-entry toc-h2"><a href="#containers">Containers</a></li><li class="toc-entry toc-h2"><a href="#responsive-breakpoints">Responsive breakpoints</a></li><li class="toc-entry toc-h2"><a href="#z-index">Z-index</a></li>'
|
||||
// LET actual = INNER_HTML(doc, selector)
|
||||
|
||||
// RETURN EXPECT(REGEXP_REPLACE(expected, '\s', ''), REGEXP_REPLACE(TRIM(actual), '(\n|\s)', ''))
|
||||
|
||||
RETURN ""
|
7
e2e/tests/inner_text.fql
Normal file
7
e2e/tests/inner_text.fql
Normal file
@ -0,0 +1,7 @@
|
||||
LET url = @server + '/bootstrap/overview.html'
|
||||
LET doc = DOCUMENT(url)
|
||||
|
||||
LET expected = "Components and options for laying out your Bootstrap project, including wrapping containers, a powerful grid system, a flexible media object, and responsive utility classes."
|
||||
LET actual = INNER_TEXT(doc, 'body > div > div > main > p.bd-lead')
|
||||
|
||||
RETURN EXPECT(expected, actual)
|
18
e2e/tests/inner_text_all.fql
Normal file
18
e2e/tests/inner_text_all.fql
Normal file
@ -0,0 +1,18 @@
|
||||
LET url = @server + '/bootstrap/grid.html'
|
||||
LET doc = DOCUMENT(url)
|
||||
|
||||
LET expected = [
|
||||
"Containers provide a means to center and horizontally pad your site’s contents. Use .container for a responsive pixel width or .container-fluid for width: 100% across all viewport and device sizes.",
|
||||
"Rows are wrappers for columns. Each column has horizontal padding (called a gutter) for controlling the space between them. This padding is then counteracted on the rows with negative margins. This way, all the content in your columns is visually aligned down the left side.",
|
||||
"In a grid layout, content must be placed within columns and only columns may be immediate children of rows.",
|
||||
"Thanks to flexbox, grid columns without a specified width will automatically layout as equal width columns. For example, four instances of .col-sm will each automatically be 25% wide from the small breakpoint and up. See the auto-layout columns section for more examples.",
|
||||
"Column classes indicate the number of columns you’d like to use out of the possible 12 per row. So, if you want three equal-width columns across, you can use .col-4.",
|
||||
"Column widths are set in percentages, so they’re always fluid and sized relative to their parent element.",
|
||||
"Columns have horizontal padding to create the gutters between individual columns, however, you can remove the margin from rows and padding from columns with .no-gutters on the .row.",
|
||||
"To make the grid responsive, there are five grid breakpoints, one for each responsive breakpoint: all breakpoints (extra small), small, medium, large, and extra large.",
|
||||
"Grid breakpoints are based on minimum width media queries, meaning they apply to that one breakpoint and all those above it (e.g., .col-sm-4 applies to small, medium, large, and extra large devices, but not the first xs breakpoint).",
|
||||
"You can use predefined grid classes (like .col-4) or Sass mixins for more semantic markup."
|
||||
]
|
||||
LET actual = INNER_TEXT_ALL(doc, 'body > div.container-fluid > div > main > ul > li')
|
||||
|
||||
RETURN EXPECT(expected, actual)
|
9
e2e/tests/inner_text_dynamic.fql
Normal file
9
e2e/tests/inner_text_dynamic.fql
Normal file
@ -0,0 +1,9 @@
|
||||
// LET url = @server + '/bootstrap/overview.html'
|
||||
// LET doc = DOCUMENT(url, true)
|
||||
// LET selector = 'body > div > div > main > p.bd-lead'
|
||||
|
||||
// LET expected = "Components and options for laying out your Bootstrap project, including wrapping containers, a powerful grid system, a flexible media object, and responsive utility classes."
|
||||
// LET actual = INNER_TEXT(doc, selector)
|
||||
|
||||
// RETURN EXPECT(expected, actual)
|
||||
RETURN ""
|
4
e2e/tests/page-load.fql
Normal file
4
e2e/tests/page-load.fql
Normal file
@ -0,0 +1,4 @@
|
||||
LET url = @server + '/bootstrap/overview.html'
|
||||
LET doc = DOCUMENT(url)
|
||||
|
||||
RETURN EXPECT(doc.url, url)
|
Loading…
Reference in New Issue
Block a user