diff --git a/assets/css/all.css b/assets/css/all.css new file mode 100644 index 0000000..d9ade75 --- /dev/null +++ b/assets/css/all.css @@ -0,0 +1,4616 @@ +/*! + * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa, +.fas, +.far, +.fal, +.fad, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical, +:root .fa-flip-both { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2.5em; } + +.fa-stack-1x, +.fa-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; } + +.fa-stack-1x { + line-height: inherit; } + +.fa-stack-2x { + font-size: 2em; } + +.fa-inverse { + color: #fff; } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ +.fa-500px:before { + content: "\f26e"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-acquisitions-incorporated:before { + content: "\f6af"; } + +.fa-ad:before { + content: "\f641"; } + +.fa-address-book:before { + content: "\f2b9"; } + +.fa-address-card:before { + content: "\f2bb"; } + +.fa-adjust:before { + content: "\f042"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-air-freshener:before { + content: "\f5d0"; } + +.fa-airbnb:before { + content: "\f834"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-align-center:before { + content: "\f037"; } + +.fa-align-justify:before { + content: "\f039"; } + +.fa-align-left:before { + content: "\f036"; } + +.fa-align-right:before { + content: "\f038"; } + +.fa-alipay:before { + content: "\f642"; } + +.fa-allergies:before { + content: "\f461"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-amazon-pay:before { + content: "\f42c"; } + +.fa-ambulance:before { + content: "\f0f9"; } + +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-anchor:before { + content: "\f13d"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-angle-double-down:before { + content: "\f103"; } + +.fa-angle-double-left:before { + content: "\f100"; } + +.fa-angle-double-right:before { + content: "\f101"; } + +.fa-angle-double-up:before { + content: "\f102"; } + +.fa-angle-down:before { + content: "\f107"; } + +.fa-angle-left:before { + content: "\f104"; } + +.fa-angle-right:before { + content: "\f105"; } + +.fa-angle-up:before { + content: "\f106"; } + +.fa-angry:before { + content: "\f556"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-ankh:before { + content: "\f644"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-apple-alt:before { + content: "\f5d1"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-archive:before { + content: "\f187"; } + +.fa-archway:before { + content: "\f557"; } + +.fa-arrow-alt-circle-down:before { + content: "\f358"; } + +.fa-arrow-alt-circle-left:before { + content: "\f359"; } + +.fa-arrow-alt-circle-right:before { + content: "\f35a"; } + +.fa-arrow-alt-circle-up:before { + content: "\f35b"; } + +.fa-arrow-circle-down:before { + content: "\f0ab"; } + +.fa-arrow-circle-left:before { + content: "\f0a8"; } + +.fa-arrow-circle-right:before { + content: "\f0a9"; } + +.fa-arrow-circle-up:before { + content: "\f0aa"; } + +.fa-arrow-down:before { + content: "\f063"; } + +.fa-arrow-left:before { + content: "\f060"; } + +.fa-arrow-right:before { + content: "\f061"; } + +.fa-arrow-up:before { + content: "\f062"; } + +.fa-arrows-alt:before { + content: "\f0b2"; } + +.fa-arrows-alt-h:before { + content: "\f337"; } + +.fa-arrows-alt-v:before { + content: "\f338"; } + +.fa-artstation:before { + content: "\f77a"; } + +.fa-assistive-listening-systems:before { + content: "\f2a2"; } + +.fa-asterisk:before { + content: "\f069"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-at:before { + content: "\f1fa"; } + +.fa-atlas:before { + content: "\f558"; } + +.fa-atlassian:before { + content: "\f77b"; } + +.fa-atom:before { + content: "\f5d2"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-audio-description:before { + content: "\f29e"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-award:before { + content: "\f559"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-baby:before { + content: "\f77c"; } + +.fa-baby-carriage:before { + content: "\f77d"; } + +.fa-backspace:before { + content: "\f55a"; } + +.fa-backward:before { + content: "\f04a"; } + +.fa-bacon:before { + content: "\f7e5"; } + +.fa-bacteria:before { + content: "\e059"; } + +.fa-bacterium:before { + content: "\e05a"; } + +.fa-bahai:before { + content: "\f666"; } + +.fa-balance-scale:before { + content: "\f24e"; } + +.fa-balance-scale-left:before { + content: "\f515"; } + +.fa-balance-scale-right:before { + content: "\f516"; } + +.fa-ban:before { + content: "\f05e"; } + +.fa-band-aid:before { + content: "\f462"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-barcode:before { + content: "\f02a"; } + +.fa-bars:before { + content: "\f0c9"; } + +.fa-baseball-ball:before { + content: "\f433"; } + +.fa-basketball-ball:before { + content: "\f434"; } + +.fa-bath:before { + content: "\f2cd"; } + +.fa-battery-empty:before { + content: "\f244"; } + +.fa-battery-full:before { + content: "\f240"; } + +.fa-battery-half:before { + content: "\f242"; } + +.fa-battery-quarter:before { + content: "\f243"; } + +.fa-battery-three-quarters:before { + content: "\f241"; } + +.fa-battle-net:before { + content: "\f835"; } + +.fa-bed:before { + content: "\f236"; } + +.fa-beer:before { + content: "\f0fc"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-bell:before { + content: "\f0f3"; } + +.fa-bell-slash:before { + content: "\f1f6"; } + +.fa-bezier-curve:before { + content: "\f55b"; } + +.fa-bible:before { + content: "\f647"; } + +.fa-bicycle:before { + content: "\f206"; } + +.fa-biking:before { + content: "\f84a"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-binoculars:before { + content: "\f1e5"; } + +.fa-biohazard:before { + content: "\f780"; } + +.fa-birthday-cake:before { + content: "\f1fd"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-blender:before { + content: "\f517"; } + +.fa-blender-phone:before { + content: "\f6b6"; } + +.fa-blind:before { + content: "\f29d"; } + +.fa-blog:before { + content: "\f781"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-bold:before { + content: "\f032"; } + +.fa-bolt:before { + content: "\f0e7"; } + +.fa-bomb:before { + content: "\f1e2"; } + +.fa-bone:before { + content: "\f5d7"; } + +.fa-bong:before { + content: "\f55c"; } + +.fa-book:before { + content: "\f02d"; } + +.fa-book-dead:before { + content: "\f6b7"; } + +.fa-book-medical:before { + content: "\f7e6"; } + +.fa-book-open:before { + content: "\f518"; } + +.fa-book-reader:before { + content: "\f5da"; } + +.fa-bookmark:before { + content: "\f02e"; } + +.fa-bootstrap:before { + content: "\f836"; } + +.fa-border-all:before { + content: "\f84c"; } + +.fa-border-none:before { + content: "\f850"; } + +.fa-border-style:before { + content: "\f853"; } + +.fa-bowling-ball:before { + content: "\f436"; } + +.fa-box:before { + content: "\f466"; } + +.fa-box-open:before { + content: "\f49e"; } + +.fa-box-tissue:before { + content: "\e05b"; } + +.fa-boxes:before { + content: "\f468"; } + +.fa-braille:before { + content: "\f2a1"; } + +.fa-brain:before { + content: "\f5dc"; } + +.fa-bread-slice:before { + content: "\f7ec"; } + +.fa-briefcase:before { + content: "\f0b1"; } + +.fa-briefcase-medical:before { + content: "\f469"; } + +.fa-broadcast-tower:before { + content: "\f519"; } + +.fa-broom:before { + content: "\f51a"; } + +.fa-brush:before { + content: "\f55d"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-buffer:before { + content: "\f837"; } + +.fa-bug:before { + content: "\f188"; } + +.fa-building:before { + content: "\f1ad"; } + +.fa-bullhorn:before { + content: "\f0a1"; } + +.fa-bullseye:before { + content: "\f140"; } + +.fa-burn:before { + content: "\f46a"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-bus:before { + content: "\f207"; } + +.fa-bus-alt:before { + content: "\f55e"; } + +.fa-business-time:before { + content: "\f64a"; } + +.fa-buy-n-large:before { + content: "\f8a6"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-calculator:before { + content: "\f1ec"; } + +.fa-calendar:before { + content: "\f133"; } + +.fa-calendar-alt:before { + content: "\f073"; } + +.fa-calendar-check:before { + content: "\f274"; } + +.fa-calendar-day:before { + content: "\f783"; } + +.fa-calendar-minus:before { + content: "\f272"; } + +.fa-calendar-plus:before { + content: "\f271"; } + +.fa-calendar-times:before { + content: "\f273"; } + +.fa-calendar-week:before { + content: "\f784"; } + +.fa-camera:before { + content: "\f030"; } + +.fa-camera-retro:before { + content: "\f083"; } + +.fa-campground:before { + content: "\f6bb"; } + +.fa-canadian-maple-leaf:before { + content: "\f785"; } + +.fa-candy-cane:before { + content: "\f786"; } + +.fa-cannabis:before { + content: "\f55f"; } + +.fa-capsules:before { + content: "\f46b"; } + +.fa-car:before { + content: "\f1b9"; } + +.fa-car-alt:before { + content: "\f5de"; } + +.fa-car-battery:before { + content: "\f5df"; } + +.fa-car-crash:before { + content: "\f5e1"; } + +.fa-car-side:before { + content: "\f5e4"; } + +.fa-caravan:before { + content: "\f8ff"; } + +.fa-caret-down:before { + content: "\f0d7"; } + +.fa-caret-left:before { + content: "\f0d9"; } + +.fa-caret-right:before { + content: "\f0da"; } + +.fa-caret-square-down:before { + content: "\f150"; } + +.fa-caret-square-left:before { + content: "\f191"; } + +.fa-caret-square-right:before { + content: "\f152"; } + +.fa-caret-square-up:before { + content: "\f151"; } + +.fa-caret-up:before { + content: "\f0d8"; } + +.fa-carrot:before { + content: "\f787"; } + +.fa-cart-arrow-down:before { + content: "\f218"; } + +.fa-cart-plus:before { + content: "\f217"; } + +.fa-cash-register:before { + content: "\f788"; } + +.fa-cat:before { + content: "\f6be"; } + +.fa-cc-amazon-pay:before { + content: "\f42d"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-centos:before { + content: "\f789"; } + +.fa-certificate:before { + content: "\f0a3"; } + +.fa-chair:before { + content: "\f6c0"; } + +.fa-chalkboard:before { + content: "\f51b"; } + +.fa-chalkboard-teacher:before { + content: "\f51c"; } + +.fa-charging-station:before { + content: "\f5e7"; } + +.fa-chart-area:before { + content: "\f1fe"; } + +.fa-chart-bar:before { + content: "\f080"; } + +.fa-chart-line:before { + content: "\f201"; } + +.fa-chart-pie:before { + content: "\f200"; } + +.fa-check:before { + content: "\f00c"; } + +.fa-check-circle:before { + content: "\f058"; } + +.fa-check-double:before { + content: "\f560"; } + +.fa-check-square:before { + content: "\f14a"; } + +.fa-cheese:before { + content: "\f7ef"; } + +.fa-chess:before { + content: "\f439"; } + +.fa-chess-bishop:before { + content: "\f43a"; } + +.fa-chess-board:before { + content: "\f43c"; } + +.fa-chess-king:before { + content: "\f43f"; } + +.fa-chess-knight:before { + content: "\f441"; } + +.fa-chess-pawn:before { + content: "\f443"; } + +.fa-chess-queen:before { + content: "\f445"; } + +.fa-chess-rook:before { + content: "\f447"; } + +.fa-chevron-circle-down:before { + content: "\f13a"; } + +.fa-chevron-circle-left:before { + content: "\f137"; } + +.fa-chevron-circle-right:before { + content: "\f138"; } + +.fa-chevron-circle-up:before { + content: "\f139"; } + +.fa-chevron-down:before { + content: "\f078"; } + +.fa-chevron-left:before { + content: "\f053"; } + +.fa-chevron-right:before { + content: "\f054"; } + +.fa-chevron-up:before { + content: "\f077"; } + +.fa-child:before { + content: "\f1ae"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-chromecast:before { + content: "\f838"; } + +.fa-church:before { + content: "\f51d"; } + +.fa-circle:before { + content: "\f111"; } + +.fa-circle-notch:before { + content: "\f1ce"; } + +.fa-city:before { + content: "\f64f"; } + +.fa-clinic-medical:before { + content: "\f7f2"; } + +.fa-clipboard:before { + content: "\f328"; } + +.fa-clipboard-check:before { + content: "\f46c"; } + +.fa-clipboard-list:before { + content: "\f46d"; } + +.fa-clock:before { + content: "\f017"; } + +.fa-clone:before { + content: "\f24d"; } + +.fa-closed-captioning:before { + content: "\f20a"; } + +.fa-cloud:before { + content: "\f0c2"; } + +.fa-cloud-download-alt:before { + content: "\f381"; } + +.fa-cloud-meatball:before { + content: "\f73b"; } + +.fa-cloud-moon:before { + content: "\f6c3"; } + +.fa-cloud-moon-rain:before { + content: "\f73c"; } + +.fa-cloud-rain:before { + content: "\f73d"; } + +.fa-cloud-showers-heavy:before { + content: "\f740"; } + +.fa-cloud-sun:before { + content: "\f6c4"; } + +.fa-cloud-sun-rain:before { + content: "\f743"; } + +.fa-cloud-upload-alt:before { + content: "\f382"; } + +.fa-cloudflare:before { + content: "\e07d"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-cocktail:before { + content: "\f561"; } + +.fa-code:before { + content: "\f121"; } + +.fa-code-branch:before { + content: "\f126"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-coffee:before { + content: "\f0f4"; } + +.fa-cog:before { + content: "\f013"; } + +.fa-cogs:before { + content: "\f085"; } + +.fa-coins:before { + content: "\f51e"; } + +.fa-columns:before { + content: "\f0db"; } + +.fa-comment:before { + content: "\f075"; } + +.fa-comment-alt:before { + content: "\f27a"; } + +.fa-comment-dollar:before { + content: "\f651"; } + +.fa-comment-dots:before { + content: "\f4ad"; } + +.fa-comment-medical:before { + content: "\f7f5"; } + +.fa-comment-slash:before { + content: "\f4b3"; } + +.fa-comments:before { + content: "\f086"; } + +.fa-comments-dollar:before { + content: "\f653"; } + +.fa-compact-disc:before { + content: "\f51f"; } + +.fa-compass:before { + content: "\f14e"; } + +.fa-compress:before { + content: "\f066"; } + +.fa-compress-alt:before { + content: "\f422"; } + +.fa-compress-arrows-alt:before { + content: "\f78c"; } + +.fa-concierge-bell:before { + content: "\f562"; } + +.fa-confluence:before { + content: "\f78d"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-cookie:before { + content: "\f563"; } + +.fa-cookie-bite:before { + content: "\f564"; } + +.fa-copy:before { + content: "\f0c5"; } + +.fa-copyright:before { + content: "\f1f9"; } + +.fa-cotton-bureau:before { + content: "\f89e"; } + +.fa-couch:before { + content: "\f4b8"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-creative-commons-by:before { + content: "\f4e7"; } + +.fa-creative-commons-nc:before { + content: "\f4e8"; } + +.fa-creative-commons-nc-eu:before { + content: "\f4e9"; } + +.fa-creative-commons-nc-jp:before { + content: "\f4ea"; } + +.fa-creative-commons-nd:before { + content: "\f4eb"; } + +.fa-creative-commons-pd:before { + content: "\f4ec"; } + +.fa-creative-commons-pd-alt:before { + content: "\f4ed"; } + +.fa-creative-commons-remix:before { + content: "\f4ee"; } + +.fa-creative-commons-sa:before { + content: "\f4ef"; } + +.fa-creative-commons-sampling:before { + content: "\f4f0"; } + +.fa-creative-commons-sampling-plus:before { + content: "\f4f1"; } + +.fa-creative-commons-share:before { + content: "\f4f2"; } + +.fa-creative-commons-zero:before { + content: "\f4f3"; } + +.fa-credit-card:before { + content: "\f09d"; } + +.fa-critical-role:before { + content: "\f6c9"; } + +.fa-crop:before { + content: "\f125"; } + +.fa-crop-alt:before { + content: "\f565"; } + +.fa-cross:before { + content: "\f654"; } + +.fa-crosshairs:before { + content: "\f05b"; } + +.fa-crow:before { + content: "\f520"; } + +.fa-crown:before { + content: "\f521"; } + +.fa-crutch:before { + content: "\f7f7"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-cube:before { + content: "\f1b2"; } + +.fa-cubes:before { + content: "\f1b3"; } + +.fa-cut:before { + content: "\f0c4"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-d-and-d-beyond:before { + content: "\f6ca"; } + +.fa-dailymotion:before { + content: "\e052"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-database:before { + content: "\f1c0"; } + +.fa-deaf:before { + content: "\f2a4"; } + +.fa-deezer:before { + content: "\e077"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-democrat:before { + content: "\f747"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-desktop:before { + content: "\f108"; } + +.fa-dev:before { + content: "\f6cc"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-dharmachakra:before { + content: "\f655"; } + +.fa-dhl:before { + content: "\f790"; } + +.fa-diagnoses:before { + content: "\f470"; } + +.fa-diaspora:before { + content: "\f791"; } + +.fa-dice:before { + content: "\f522"; } + +.fa-dice-d20:before { + content: "\f6cf"; } + +.fa-dice-d6:before { + content: "\f6d1"; } + +.fa-dice-five:before { + content: "\f523"; } + +.fa-dice-four:before { + content: "\f524"; } + +.fa-dice-one:before { + content: "\f525"; } + +.fa-dice-six:before { + content: "\f526"; } + +.fa-dice-three:before { + content: "\f527"; } + +.fa-dice-two:before { + content: "\f528"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-digital-tachograph:before { + content: "\f566"; } + +.fa-directions:before { + content: "\f5eb"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-disease:before { + content: "\f7fa"; } + +.fa-divide:before { + content: "\f529"; } + +.fa-dizzy:before { + content: "\f567"; } + +.fa-dna:before { + content: "\f471"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-dog:before { + content: "\f6d3"; } + +.fa-dollar-sign:before { + content: "\f155"; } + +.fa-dolly:before { + content: "\f472"; } + +.fa-dolly-flatbed:before { + content: "\f474"; } + +.fa-donate:before { + content: "\f4b9"; } + +.fa-door-closed:before { + content: "\f52a"; } + +.fa-door-open:before { + content: "\f52b"; } + +.fa-dot-circle:before { + content: "\f192"; } + +.fa-dove:before { + content: "\f4ba"; } + +.fa-download:before { + content: "\f019"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-drafting-compass:before { + content: "\f568"; } + +.fa-dragon:before { + content: "\f6d5"; } + +.fa-draw-polygon:before { + content: "\f5ee"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-drum:before { + content: "\f569"; } + +.fa-drum-steelpan:before { + content: "\f56a"; } + +.fa-drumstick-bite:before { + content: "\f6d7"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-dumbbell:before { + content: "\f44b"; } + +.fa-dumpster:before { + content: "\f793"; } + +.fa-dumpster-fire:before { + content: "\f794"; } + +.fa-dungeon:before { + content: "\f6d9"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-ebay:before { + content: "\f4f4"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-edge-legacy:before { + content: "\e078"; } + +.fa-edit:before { + content: "\f044"; } + +.fa-egg:before { + content: "\f7fb"; } + +.fa-eject:before { + content: "\f052"; } + +.fa-elementor:before { + content: "\f430"; } + +.fa-ellipsis-h:before { + content: "\f141"; } + +.fa-ellipsis-v:before { + content: "\f142"; } + +.fa-ello:before { + content: "\f5f1"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envelope:before { + content: "\f0e0"; } + +.fa-envelope-open:before { + content: "\f2b6"; } + +.fa-envelope-open-text:before { + content: "\f658"; } + +.fa-envelope-square:before { + content: "\f199"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-equals:before { + content: "\f52c"; } + +.fa-eraser:before { + content: "\f12d"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-ethereum:before { + content: "\f42e"; } + +.fa-ethernet:before { + content: "\f796"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-euro-sign:before { + content: "\f153"; } + +.fa-evernote:before { + content: "\f839"; } + +.fa-exchange-alt:before { + content: "\f362"; } + +.fa-exclamation:before { + content: "\f12a"; } + +.fa-exclamation-circle:before { + content: "\f06a"; } + +.fa-exclamation-triangle:before { + content: "\f071"; } + +.fa-expand:before { + content: "\f065"; } + +.fa-expand-alt:before { + content: "\f424"; } + +.fa-expand-arrows-alt:before { + content: "\f31e"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-external-link-alt:before { + content: "\f35d"; } + +.fa-external-link-square-alt:before { + content: "\f360"; } + +.fa-eye:before { + content: "\f06e"; } + +.fa-eye-dropper:before { + content: "\f1fb"; } + +.fa-eye-slash:before { + content: "\f070"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-fan:before { + content: "\f863"; } + +.fa-fantasy-flight-games:before { + content: "\f6dc"; } + +.fa-fast-backward:before { + content: "\f049"; } + +.fa-fast-forward:before { + content: "\f050"; } + +.fa-faucet:before { + content: "\e005"; } + +.fa-fax:before { + content: "\f1ac"; } + +.fa-feather:before { + content: "\f52d"; } + +.fa-feather-alt:before { + content: "\f56b"; } + +.fa-fedex:before { + content: "\f797"; } + +.fa-fedora:before { + content: "\f798"; } + +.fa-female:before { + content: "\f182"; } + +.fa-fighter-jet:before { + content: "\f0fb"; } + +.fa-figma:before { + content: "\f799"; } + +.fa-file:before { + content: "\f15b"; } + +.fa-file-alt:before { + content: "\f15c"; } + +.fa-file-archive:before { + content: "\f1c6"; } + +.fa-file-audio:before { + content: "\f1c7"; } + +.fa-file-code:before { + content: "\f1c9"; } + +.fa-file-contract:before { + content: "\f56c"; } + +.fa-file-csv:before { + content: "\f6dd"; } + +.fa-file-download:before { + content: "\f56d"; } + +.fa-file-excel:before { + content: "\f1c3"; } + +.fa-file-export:before { + content: "\f56e"; } + +.fa-file-image:before { + content: "\f1c5"; } + +.fa-file-import:before { + content: "\f56f"; } + +.fa-file-invoice:before { + content: "\f570"; } + +.fa-file-invoice-dollar:before { + content: "\f571"; } + +.fa-file-medical:before { + content: "\f477"; } + +.fa-file-medical-alt:before { + content: "\f478"; } + +.fa-file-pdf:before { + content: "\f1c1"; } + +.fa-file-powerpoint:before { + content: "\f1c4"; } + +.fa-file-prescription:before { + content: "\f572"; } + +.fa-file-signature:before { + content: "\f573"; } + +.fa-file-upload:before { + content: "\f574"; } + +.fa-file-video:before { + content: "\f1c8"; } + +.fa-file-word:before { + content: "\f1c2"; } + +.fa-fill:before { + content: "\f575"; } + +.fa-fill-drip:before { + content: "\f576"; } + +.fa-film:before { + content: "\f008"; } + +.fa-filter:before { + content: "\f0b0"; } + +.fa-fingerprint:before { + content: "\f577"; } + +.fa-fire:before { + content: "\f06d"; } + +.fa-fire-alt:before { + content: "\f7e4"; } + +.fa-fire-extinguisher:before { + content: "\f134"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-firefox-browser:before { + content: "\e007"; } + +.fa-first-aid:before { + content: "\f479"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-first-order-alt:before { + content: "\f50a"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-fish:before { + content: "\f578"; } + +.fa-fist-raised:before { + content: "\f6de"; } + +.fa-flag:before { + content: "\f024"; } + +.fa-flag-checkered:before { + content: "\f11e"; } + +.fa-flag-usa:before { + content: "\f74d"; } + +.fa-flask:before { + content: "\f0c3"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-flipboard:before { + content: "\f44d"; } + +.fa-flushed:before { + content: "\f579"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-folder:before { + content: "\f07b"; } + +.fa-folder-minus:before { + content: "\f65d"; } + +.fa-folder-open:before { + content: "\f07c"; } + +.fa-folder-plus:before { + content: "\f65e"; } + +.fa-font:before { + content: "\f031"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-font-awesome-flag:before { + content: "\f425"; } + +.fa-font-awesome-logo-full:before { + content: "\f4e6"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-football-ball:before { + content: "\f44e"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-forward:before { + content: "\f04e"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-frog:before { + content: "\f52e"; } + +.fa-frown:before { + content: "\f119"; } + +.fa-frown-open:before { + content: "\f57a"; } + +.fa-fulcrum:before { + content: "\f50b"; } + +.fa-funnel-dollar:before { + content: "\f662"; } + +.fa-futbol:before { + content: "\f1e3"; } + +.fa-galactic-republic:before { + content: "\f50c"; } + +.fa-galactic-senate:before { + content: "\f50d"; } + +.fa-gamepad:before { + content: "\f11b"; } + +.fa-gas-pump:before { + content: "\f52f"; } + +.fa-gavel:before { + content: "\f0e3"; } + +.fa-gem:before { + content: "\f3a5"; } + +.fa-genderless:before { + content: "\f22d"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-ghost:before { + content: "\f6e2"; } + +.fa-gift:before { + content: "\f06b"; } + +.fa-gifts:before { + content: "\f79c"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-git-alt:before { + content: "\f841"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-glass-cheers:before { + content: "\f79f"; } + +.fa-glass-martini:before { + content: "\f000"; } + +.fa-glass-martini-alt:before { + content: "\f57b"; } + +.fa-glass-whiskey:before { + content: "\f7a0"; } + +.fa-glasses:before { + content: "\f530"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-globe:before { + content: "\f0ac"; } + +.fa-globe-africa:before { + content: "\f57c"; } + +.fa-globe-americas:before { + content: "\f57d"; } + +.fa-globe-asia:before { + content: "\f57e"; } + +.fa-globe-europe:before { + content: "\f7a2"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-golf-ball:before { + content: "\f450"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-google-pay:before { + content: "\e079"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-gopuram:before { + content: "\f664"; } + +.fa-graduation-cap:before { + content: "\f19d"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-greater-than:before { + content: "\f531"; } + +.fa-greater-than-equal:before { + content: "\f532"; } + +.fa-grimace:before { + content: "\f57f"; } + +.fa-grin:before { + content: "\f580"; } + +.fa-grin-alt:before { + content: "\f581"; } + +.fa-grin-beam:before { + content: "\f582"; } + +.fa-grin-beam-sweat:before { + content: "\f583"; } + +.fa-grin-hearts:before { + content: "\f584"; } + +.fa-grin-squint:before { + content: "\f585"; } + +.fa-grin-squint-tears:before { + content: "\f586"; } + +.fa-grin-stars:before { + content: "\f587"; } + +.fa-grin-tears:before { + content: "\f588"; } + +.fa-grin-tongue:before { + content: "\f589"; } + +.fa-grin-tongue-squint:before { + content: "\f58a"; } + +.fa-grin-tongue-wink:before { + content: "\f58b"; } + +.fa-grin-wink:before { + content: "\f58c"; } + +.fa-grip-horizontal:before { + content: "\f58d"; } + +.fa-grip-lines:before { + content: "\f7a4"; } + +.fa-grip-lines-vertical:before { + content: "\f7a5"; } + +.fa-grip-vertical:before { + content: "\f58e"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-guilded:before { + content: "\e07e"; } + +.fa-guitar:before { + content: "\f7a6"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-h-square:before { + content: "\f0fd"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-hackerrank:before { + content: "\f5f7"; } + +.fa-hamburger:before { + content: "\f805"; } + +.fa-hammer:before { + content: "\f6e3"; } + +.fa-hamsa:before { + content: "\f665"; } + +.fa-hand-holding:before { + content: "\f4bd"; } + +.fa-hand-holding-heart:before { + content: "\f4be"; } + +.fa-hand-holding-medical:before { + content: "\e05c"; } + +.fa-hand-holding-usd:before { + content: "\f4c0"; } + +.fa-hand-holding-water:before { + content: "\f4c1"; } + +.fa-hand-lizard:before { + content: "\f258"; } + +.fa-hand-middle-finger:before { + content: "\f806"; } + +.fa-hand-paper:before { + content: "\f256"; } + +.fa-hand-peace:before { + content: "\f25b"; } + +.fa-hand-point-down:before { + content: "\f0a7"; } + +.fa-hand-point-left:before { + content: "\f0a5"; } + +.fa-hand-point-right:before { + content: "\f0a4"; } + +.fa-hand-point-up:before { + content: "\f0a6"; } + +.fa-hand-pointer:before { + content: "\f25a"; } + +.fa-hand-rock:before { + content: "\f255"; } + +.fa-hand-scissors:before { + content: "\f257"; } + +.fa-hand-sparkles:before { + content: "\e05d"; } + +.fa-hand-spock:before { + content: "\f259"; } + +.fa-hands:before { + content: "\f4c2"; } + +.fa-hands-helping:before { + content: "\f4c4"; } + +.fa-hands-wash:before { + content: "\e05e"; } + +.fa-handshake:before { + content: "\f2b5"; } + +.fa-handshake-alt-slash:before { + content: "\e05f"; } + +.fa-handshake-slash:before { + content: "\e060"; } + +.fa-hanukiah:before { + content: "\f6e6"; } + +.fa-hard-hat:before { + content: "\f807"; } + +.fa-hashtag:before { + content: "\f292"; } + +.fa-hat-cowboy:before { + content: "\f8c0"; } + +.fa-hat-cowboy-side:before { + content: "\f8c1"; } + +.fa-hat-wizard:before { + content: "\f6e8"; } + +.fa-hdd:before { + content: "\f0a0"; } + +.fa-head-side-cough:before { + content: "\e061"; } + +.fa-head-side-cough-slash:before { + content: "\e062"; } + +.fa-head-side-mask:before { + content: "\e063"; } + +.fa-head-side-virus:before { + content: "\e064"; } + +.fa-heading:before { + content: "\f1dc"; } + +.fa-headphones:before { + content: "\f025"; } + +.fa-headphones-alt:before { + content: "\f58f"; } + +.fa-headset:before { + content: "\f590"; } + +.fa-heart:before { + content: "\f004"; } + +.fa-heart-broken:before { + content: "\f7a9"; } + +.fa-heartbeat:before { + content: "\f21e"; } + +.fa-helicopter:before { + content: "\f533"; } + +.fa-highlighter:before { + content: "\f591"; } + +.fa-hiking:before { + content: "\f6ec"; } + +.fa-hippo:before { + content: "\f6ed"; } + +.fa-hips:before { + content: "\f452"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-history:before { + content: "\f1da"; } + +.fa-hive:before { + content: "\e07f"; } + +.fa-hockey-puck:before { + content: "\f453"; } + +.fa-holly-berry:before { + content: "\f7aa"; } + +.fa-home:before { + content: "\f015"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-hornbill:before { + content: "\f592"; } + +.fa-horse:before { + content: "\f6f0"; } + +.fa-horse-head:before { + content: "\f7ab"; } + +.fa-hospital:before { + content: "\f0f8"; } + +.fa-hospital-alt:before { + content: "\f47d"; } + +.fa-hospital-symbol:before { + content: "\f47e"; } + +.fa-hospital-user:before { + content: "\f80d"; } + +.fa-hot-tub:before { + content: "\f593"; } + +.fa-hotdog:before { + content: "\f80f"; } + +.fa-hotel:before { + content: "\f594"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-hourglass:before { + content: "\f254"; } + +.fa-hourglass-end:before { + content: "\f253"; } + +.fa-hourglass-half:before { + content: "\f252"; } + +.fa-hourglass-start:before { + content: "\f251"; } + +.fa-house-damage:before { + content: "\f6f1"; } + +.fa-house-user:before { + content: "\e065"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-hryvnia:before { + content: "\f6f2"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-i-cursor:before { + content: "\f246"; } + +.fa-ice-cream:before { + content: "\f810"; } + +.fa-icicles:before { + content: "\f7ad"; } + +.fa-icons:before { + content: "\f86d"; } + +.fa-id-badge:before { + content: "\f2c1"; } + +.fa-id-card:before { + content: "\f2c2"; } + +.fa-id-card-alt:before { + content: "\f47f"; } + +.fa-ideal:before { + content: "\e013"; } + +.fa-igloo:before { + content: "\f7ae"; } + +.fa-image:before { + content: "\f03e"; } + +.fa-images:before { + content: "\f302"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-inbox:before { + content: "\f01c"; } + +.fa-indent:before { + content: "\f03c"; } + +.fa-industry:before { + content: "\f275"; } + +.fa-infinity:before { + content: "\f534"; } + +.fa-info:before { + content: "\f129"; } + +.fa-info-circle:before { + content: "\f05a"; } + +.fa-innosoft:before { + content: "\e080"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-instagram-square:before { + content: "\e055"; } + +.fa-instalod:before { + content: "\e081"; } + +.fa-intercom:before { + content: "\f7af"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-invision:before { + content: "\f7b0"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-italic:before { + content: "\f033"; } + +.fa-itch-io:before { + content: "\f83a"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-java:before { + content: "\f4e4"; } + +.fa-jedi:before { + content: "\f669"; } + +.fa-jedi-order:before { + content: "\f50e"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-jira:before { + content: "\f7b1"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-joint:before { + content: "\f595"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-journal-whills:before { + content: "\f66a"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-kaaba:before { + content: "\f66b"; } + +.fa-kaggle:before { + content: "\f5fa"; } + +.fa-key:before { + content: "\f084"; } + +.fa-keybase:before { + content: "\f4f5"; } + +.fa-keyboard:before { + content: "\f11c"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-khanda:before { + content: "\f66d"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-kiss:before { + content: "\f596"; } + +.fa-kiss-beam:before { + content: "\f597"; } + +.fa-kiss-wink-heart:before { + content: "\f598"; } + +.fa-kiwi-bird:before { + content: "\f535"; } + +.fa-korvue:before { + content: "\f42f"; } + +.fa-landmark:before { + content: "\f66f"; } + +.fa-language:before { + content: "\f1ab"; } + +.fa-laptop:before { + content: "\f109"; } + +.fa-laptop-code:before { + content: "\f5fc"; } + +.fa-laptop-house:before { + content: "\e066"; } + +.fa-laptop-medical:before { + content: "\f812"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-laugh:before { + content: "\f599"; } + +.fa-laugh-beam:before { + content: "\f59a"; } + +.fa-laugh-squint:before { + content: "\f59b"; } + +.fa-laugh-wink:before { + content: "\f59c"; } + +.fa-layer-group:before { + content: "\f5fd"; } + +.fa-leaf:before { + content: "\f06c"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-lemon:before { + content: "\f094"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-less-than:before { + content: "\f536"; } + +.fa-less-than-equal:before { + content: "\f537"; } + +.fa-level-down-alt:before { + content: "\f3be"; } + +.fa-level-up-alt:before { + content: "\f3bf"; } + +.fa-life-ring:before { + content: "\f1cd"; } + +.fa-lightbulb:before { + content: "\f0eb"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-link:before { + content: "\f0c1"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-lira-sign:before { + content: "\f195"; } + +.fa-list:before { + content: "\f03a"; } + +.fa-list-alt:before { + content: "\f022"; } + +.fa-list-ol:before { + content: "\f0cb"; } + +.fa-list-ul:before { + content: "\f0ca"; } + +.fa-location-arrow:before { + content: "\f124"; } + +.fa-lock:before { + content: "\f023"; } + +.fa-lock-open:before { + content: "\f3c1"; } + +.fa-long-arrow-alt-down:before { + content: "\f309"; } + +.fa-long-arrow-alt-left:before { + content: "\f30a"; } + +.fa-long-arrow-alt-right:before { + content: "\f30b"; } + +.fa-long-arrow-alt-up:before { + content: "\f30c"; } + +.fa-low-vision:before { + content: "\f2a8"; } + +.fa-luggage-cart:before { + content: "\f59d"; } + +.fa-lungs:before { + content: "\f604"; } + +.fa-lungs-virus:before { + content: "\e067"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-magic:before { + content: "\f0d0"; } + +.fa-magnet:before { + content: "\f076"; } + +.fa-mail-bulk:before { + content: "\f674"; } + +.fa-mailchimp:before { + content: "\f59e"; } + +.fa-male:before { + content: "\f183"; } + +.fa-mandalorian:before { + content: "\f50f"; } + +.fa-map:before { + content: "\f279"; } + +.fa-map-marked:before { + content: "\f59f"; } + +.fa-map-marked-alt:before { + content: "\f5a0"; } + +.fa-map-marker:before { + content: "\f041"; } + +.fa-map-marker-alt:before { + content: "\f3c5"; } + +.fa-map-pin:before { + content: "\f276"; } + +.fa-map-signs:before { + content: "\f277"; } + +.fa-markdown:before { + content: "\f60f"; } + +.fa-marker:before { + content: "\f5a1"; } + +.fa-mars:before { + content: "\f222"; } + +.fa-mars-double:before { + content: "\f227"; } + +.fa-mars-stroke:before { + content: "\f229"; } + +.fa-mars-stroke-h:before { + content: "\f22b"; } + +.fa-mars-stroke-v:before { + content: "\f22a"; } + +.fa-mask:before { + content: "\f6fa"; } + +.fa-mastodon:before { + content: "\f4f6"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-mdb:before { + content: "\f8ca"; } + +.fa-medal:before { + content: "\f5a2"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f3c7"; } + +.fa-medkit:before { + content: "\f0fa"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-megaport:before { + content: "\f5a3"; } + +.fa-meh:before { + content: "\f11a"; } + +.fa-meh-blank:before { + content: "\f5a4"; } + +.fa-meh-rolling-eyes:before { + content: "\f5a5"; } + +.fa-memory:before { + content: "\f538"; } + +.fa-mendeley:before { + content: "\f7b3"; } + +.fa-menorah:before { + content: "\f676"; } + +.fa-mercury:before { + content: "\f223"; } + +.fa-meteor:before { + content: "\f753"; } + +.fa-microblog:before { + content: "\e01a"; } + +.fa-microchip:before { + content: "\f2db"; } + +.fa-microphone:before { + content: "\f130"; } + +.fa-microphone-alt:before { + content: "\f3c9"; } + +.fa-microphone-alt-slash:before { + content: "\f539"; } + +.fa-microphone-slash:before { + content: "\f131"; } + +.fa-microscope:before { + content: "\f610"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-minus:before { + content: "\f068"; } + +.fa-minus-circle:before { + content: "\f056"; } + +.fa-minus-square:before { + content: "\f146"; } + +.fa-mitten:before { + content: "\f7b5"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-mixer:before { + content: "\e056"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-mobile:before { + content: "\f10b"; } + +.fa-mobile-alt:before { + content: "\f3cd"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-money-bill:before { + content: "\f0d6"; } + +.fa-money-bill-alt:before { + content: "\f3d1"; } + +.fa-money-bill-wave:before { + content: "\f53a"; } + +.fa-money-bill-wave-alt:before { + content: "\f53b"; } + +.fa-money-check:before { + content: "\f53c"; } + +.fa-money-check-alt:before { + content: "\f53d"; } + +.fa-monument:before { + content: "\f5a6"; } + +.fa-moon:before { + content: "\f186"; } + +.fa-mortar-pestle:before { + content: "\f5a7"; } + +.fa-mosque:before { + content: "\f678"; } + +.fa-motorcycle:before { + content: "\f21c"; } + +.fa-mountain:before { + content: "\f6fc"; } + +.fa-mouse:before { + content: "\f8cc"; } + +.fa-mouse-pointer:before { + content: "\f245"; } + +.fa-mug-hot:before { + content: "\f7b6"; } + +.fa-music:before { + content: "\f001"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-neos:before { + content: "\f612"; } + +.fa-network-wired:before { + content: "\f6ff"; } + +.fa-neuter:before { + content: "\f22c"; } + +.fa-newspaper:before { + content: "\f1ea"; } + +.fa-nimblr:before { + content: "\f5a8"; } + +.fa-node:before { + content: "\f419"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-not-equal:before { + content: "\f53e"; } + +.fa-notes-medical:before { + content: "\f481"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-object-group:before { + content: "\f247"; } + +.fa-object-ungroup:before { + content: "\f248"; } + +.fa-octopus-deploy:before { + content: "\e082"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-oil-can:before { + content: "\f613"; } + +.fa-old-republic:before { + content: "\f510"; } + +.fa-om:before { + content: "\f679"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-orcid:before { + content: "\f8d2"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-otter:before { + content: "\f700"; } + +.fa-outdent:before { + content: "\f03b"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-pager:before { + content: "\f815"; } + +.fa-paint-brush:before { + content: "\f1fc"; } + +.fa-paint-roller:before { + content: "\f5aa"; } + +.fa-palette:before { + content: "\f53f"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-pallet:before { + content: "\f482"; } + +.fa-paper-plane:before { + content: "\f1d8"; } + +.fa-paperclip:before { + content: "\f0c6"; } + +.fa-parachute-box:before { + content: "\f4cd"; } + +.fa-paragraph:before { + content: "\f1dd"; } + +.fa-parking:before { + content: "\f540"; } + +.fa-passport:before { + content: "\f5ab"; } + +.fa-pastafarianism:before { + content: "\f67b"; } + +.fa-paste:before { + content: "\f0ea"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-pause:before { + content: "\f04c"; } + +.fa-pause-circle:before { + content: "\f28b"; } + +.fa-paw:before { + content: "\f1b0"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-peace:before { + content: "\f67c"; } + +.fa-pen:before { + content: "\f304"; } + +.fa-pen-alt:before { + content: "\f305"; } + +.fa-pen-fancy:before { + content: "\f5ac"; } + +.fa-pen-nib:before { + content: "\f5ad"; } + +.fa-pen-square:before { + content: "\f14b"; } + +.fa-pencil-alt:before { + content: "\f303"; } + +.fa-pencil-ruler:before { + content: "\f5ae"; } + +.fa-penny-arcade:before { + content: "\f704"; } + +.fa-people-arrows:before { + content: "\e068"; } + +.fa-people-carry:before { + content: "\f4ce"; } + +.fa-pepper-hot:before { + content: "\f816"; } + +.fa-perbyte:before { + content: "\e083"; } + +.fa-percent:before { + content: "\f295"; } + +.fa-percentage:before { + content: "\f541"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-person-booth:before { + content: "\f756"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-phoenix-squadron:before { + content: "\f511"; } + +.fa-phone:before { + content: "\f095"; } + +.fa-phone-alt:before { + content: "\f879"; } + +.fa-phone-slash:before { + content: "\f3dd"; } + +.fa-phone-square:before { + content: "\f098"; } + +.fa-phone-square-alt:before { + content: "\f87b"; } + +.fa-phone-volume:before { + content: "\f2a0"; } + +.fa-photo-video:before { + content: "\f87c"; } + +.fa-php:before { + content: "\f457"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-pied-piper-hat:before { + content: "\f4e5"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-pied-piper-square:before { + content: "\e01e"; } + +.fa-piggy-bank:before { + content: "\f4d3"; } + +.fa-pills:before { + content: "\f484"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-pizza-slice:before { + content: "\f818"; } + +.fa-place-of-worship:before { + content: "\f67f"; } + +.fa-plane:before { + content: "\f072"; } + +.fa-plane-arrival:before { + content: "\f5af"; } + +.fa-plane-departure:before { + content: "\f5b0"; } + +.fa-plane-slash:before { + content: "\e069"; } + +.fa-play:before { + content: "\f04b"; } + +.fa-play-circle:before { + content: "\f144"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-plug:before { + content: "\f1e6"; } + +.fa-plus:before { + content: "\f067"; } + +.fa-plus-circle:before { + content: "\f055"; } + +.fa-plus-square:before { + content: "\f0fe"; } + +.fa-podcast:before { + content: "\f2ce"; } + +.fa-poll:before { + content: "\f681"; } + +.fa-poll-h:before { + content: "\f682"; } + +.fa-poo:before { + content: "\f2fe"; } + +.fa-poo-storm:before { + content: "\f75a"; } + +.fa-poop:before { + content: "\f619"; } + +.fa-portrait:before { + content: "\f3e0"; } + +.fa-pound-sign:before { + content: "\f154"; } + +.fa-power-off:before { + content: "\f011"; } + +.fa-pray:before { + content: "\f683"; } + +.fa-praying-hands:before { + content: "\f684"; } + +.fa-prescription:before { + content: "\f5b1"; } + +.fa-prescription-bottle:before { + content: "\f485"; } + +.fa-prescription-bottle-alt:before { + content: "\f486"; } + +.fa-print:before { + content: "\f02f"; } + +.fa-procedures:before { + content: "\f487"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-project-diagram:before { + content: "\f542"; } + +.fa-pump-medical:before { + content: "\e06a"; } + +.fa-pump-soap:before { + content: "\e06b"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-puzzle-piece:before { + content: "\f12e"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-qrcode:before { + content: "\f029"; } + +.fa-question:before { + content: "\f128"; } + +.fa-question-circle:before { + content: "\f059"; } + +.fa-quidditch:before { + content: "\f458"; } + +.fa-quinscape:before { + content: "\f459"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-quote-left:before { + content: "\f10d"; } + +.fa-quote-right:before { + content: "\f10e"; } + +.fa-quran:before { + content: "\f687"; } + +.fa-r-project:before { + content: "\f4f7"; } + +.fa-radiation:before { + content: "\f7b9"; } + +.fa-radiation-alt:before { + content: "\f7ba"; } + +.fa-rainbow:before { + content: "\f75b"; } + +.fa-random:before { + content: "\f074"; } + +.fa-raspberry-pi:before { + content: "\f7bb"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-reacteurope:before { + content: "\f75d"; } + +.fa-readme:before { + content: "\f4d5"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-receipt:before { + content: "\f543"; } + +.fa-record-vinyl:before { + content: "\f8d9"; } + +.fa-recycle:before { + content: "\f1b8"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-redhat:before { + content: "\f7bc"; } + +.fa-redo:before { + content: "\f01e"; } + +.fa-redo-alt:before { + content: "\f2f9"; } + +.fa-registered:before { + content: "\f25d"; } + +.fa-remove-format:before { + content: "\f87d"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-reply:before { + content: "\f3e5"; } + +.fa-reply-all:before { + content: "\f122"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-republican:before { + content: "\f75e"; } + +.fa-researchgate:before { + content: "\f4f8"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-restroom:before { + content: "\f7bd"; } + +.fa-retweet:before { + content: "\f079"; } + +.fa-rev:before { + content: "\f5b2"; } + +.fa-ribbon:before { + content: "\f4d6"; } + +.fa-ring:before { + content: "\f70b"; } + +.fa-road:before { + content: "\f018"; } + +.fa-robot:before { + content: "\f544"; } + +.fa-rocket:before { + content: "\f135"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-route:before { + content: "\f4d7"; } + +.fa-rss:before { + content: "\f09e"; } + +.fa-rss-square:before { + content: "\f143"; } + +.fa-ruble-sign:before { + content: "\f158"; } + +.fa-ruler:before { + content: "\f545"; } + +.fa-ruler-combined:before { + content: "\f546"; } + +.fa-ruler-horizontal:before { + content: "\f547"; } + +.fa-ruler-vertical:before { + content: "\f548"; } + +.fa-running:before { + content: "\f70c"; } + +.fa-rupee-sign:before { + content: "\f156"; } + +.fa-rust:before { + content: "\e07a"; } + +.fa-sad-cry:before { + content: "\f5b3"; } + +.fa-sad-tear:before { + content: "\f5b4"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-salesforce:before { + content: "\f83b"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-satellite:before { + content: "\f7bf"; } + +.fa-satellite-dish:before { + content: "\f7c0"; } + +.fa-save:before { + content: "\f0c7"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-school:before { + content: "\f549"; } + +.fa-screwdriver:before { + content: "\f54a"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-scroll:before { + content: "\f70e"; } + +.fa-sd-card:before { + content: "\f7c2"; } + +.fa-search:before { + content: "\f002"; } + +.fa-search-dollar:before { + content: "\f688"; } + +.fa-search-location:before { + content: "\f689"; } + +.fa-search-minus:before { + content: "\f010"; } + +.fa-search-plus:before { + content: "\f00e"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-seedling:before { + content: "\f4d8"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-server:before { + content: "\f233"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-shapes:before { + content: "\f61f"; } + +.fa-share:before { + content: "\f064"; } + +.fa-share-alt:before { + content: "\f1e0"; } + +.fa-share-alt-square:before { + content: "\f1e1"; } + +.fa-share-square:before { + content: "\f14d"; } + +.fa-shekel-sign:before { + content: "\f20b"; } + +.fa-shield-alt:before { + content: "\f3ed"; } + +.fa-shield-virus:before { + content: "\e06c"; } + +.fa-ship:before { + content: "\f21a"; } + +.fa-shipping-fast:before { + content: "\f48b"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-shoe-prints:before { + content: "\f54b"; } + +.fa-shopify:before { + content: "\e057"; } + +.fa-shopping-bag:before { + content: "\f290"; } + +.fa-shopping-basket:before { + content: "\f291"; } + +.fa-shopping-cart:before { + content: "\f07a"; } + +.fa-shopware:before { + content: "\f5b5"; } + +.fa-shower:before { + content: "\f2cc"; } + +.fa-shuttle-van:before { + content: "\f5b6"; } + +.fa-sign:before { + content: "\f4d9"; } + +.fa-sign-in-alt:before { + content: "\f2f6"; } + +.fa-sign-language:before { + content: "\f2a7"; } + +.fa-sign-out-alt:before { + content: "\f2f5"; } + +.fa-signal:before { + content: "\f012"; } + +.fa-signature:before { + content: "\f5b7"; } + +.fa-sim-card:before { + content: "\f7c4"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-sink:before { + content: "\e06d"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-sitemap:before { + content: "\f0e8"; } + +.fa-sith:before { + content: "\f512"; } + +.fa-skating:before { + content: "\f7c5"; } + +.fa-sketch:before { + content: "\f7c6"; } + +.fa-skiing:before { + content: "\f7c9"; } + +.fa-skiing-nordic:before { + content: "\f7ca"; } + +.fa-skull:before { + content: "\f54c"; } + +.fa-skull-crossbones:before { + content: "\f714"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f3ef"; } + +.fa-slash:before { + content: "\f715"; } + +.fa-sleigh:before { + content: "\f7cc"; } + +.fa-sliders-h:before { + content: "\f1de"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-smile:before { + content: "\f118"; } + +.fa-smile-beam:before { + content: "\f5b8"; } + +.fa-smile-wink:before { + content: "\f4da"; } + +.fa-smog:before { + content: "\f75f"; } + +.fa-smoking:before { + content: "\f48d"; } + +.fa-smoking-ban:before { + content: "\f54d"; } + +.fa-sms:before { + content: "\f7cd"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ac"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-snowboarding:before { + content: "\f7ce"; } + +.fa-snowflake:before { + content: "\f2dc"; } + +.fa-snowman:before { + content: "\f7d0"; } + +.fa-snowplow:before { + content: "\f7d2"; } + +.fa-soap:before { + content: "\e06e"; } + +.fa-socks:before { + content: "\f696"; } + +.fa-solar-panel:before { + content: "\f5ba"; } + +.fa-sort:before { + content: "\f0dc"; } + +.fa-sort-alpha-down:before { + content: "\f15d"; } + +.fa-sort-alpha-down-alt:before { + content: "\f881"; } + +.fa-sort-alpha-up:before { + content: "\f15e"; } + +.fa-sort-alpha-up-alt:before { + content: "\f882"; } + +.fa-sort-amount-down:before { + content: "\f160"; } + +.fa-sort-amount-down-alt:before { + content: "\f884"; } + +.fa-sort-amount-up:before { + content: "\f161"; } + +.fa-sort-amount-up-alt:before { + content: "\f885"; } + +.fa-sort-down:before { + content: "\f0dd"; } + +.fa-sort-numeric-down:before { + content: "\f162"; } + +.fa-sort-numeric-down-alt:before { + content: "\f886"; } + +.fa-sort-numeric-up:before { + content: "\f163"; } + +.fa-sort-numeric-up-alt:before { + content: "\f887"; } + +.fa-sort-up:before { + content: "\f0de"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-sourcetree:before { + content: "\f7d3"; } + +.fa-spa:before { + content: "\f5bb"; } + +.fa-space-shuttle:before { + content: "\f197"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-speaker-deck:before { + content: "\f83c"; } + +.fa-spell-check:before { + content: "\f891"; } + +.fa-spider:before { + content: "\f717"; } + +.fa-spinner:before { + content: "\f110"; } + +.fa-splotch:before { + content: "\f5bc"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-spray-can:before { + content: "\f5bd"; } + +.fa-square:before { + content: "\f0c8"; } + +.fa-square-full:before { + content: "\f45c"; } + +.fa-square-root-alt:before { + content: "\f698"; } + +.fa-squarespace:before { + content: "\f5be"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-stackpath:before { + content: "\f842"; } + +.fa-stamp:before { + content: "\f5bf"; } + +.fa-star:before { + content: "\f005"; } + +.fa-star-and-crescent:before { + content: "\f699"; } + +.fa-star-half:before { + content: "\f089"; } + +.fa-star-half-alt:before { + content: "\f5c0"; } + +.fa-star-of-david:before { + content: "\f69a"; } + +.fa-star-of-life:before { + content: "\f621"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } + +.fa-step-backward:before { + content: "\f048"; } + +.fa-step-forward:before { + content: "\f051"; } + +.fa-stethoscope:before { + content: "\f0f1"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-sticky-note:before { + content: "\f249"; } + +.fa-stop:before { + content: "\f04d"; } + +.fa-stop-circle:before { + content: "\f28d"; } + +.fa-stopwatch:before { + content: "\f2f2"; } + +.fa-stopwatch-20:before { + content: "\e06f"; } + +.fa-store:before { + content: "\f54e"; } + +.fa-store-alt:before { + content: "\f54f"; } + +.fa-store-alt-slash:before { + content: "\e070"; } + +.fa-store-slash:before { + content: "\e071"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-stream:before { + content: "\f550"; } + +.fa-street-view:before { + content: "\f21d"; } + +.fa-strikethrough:before { + content: "\f0cc"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-stroopwafel:before { + content: "\f551"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-subscript:before { + content: "\f12c"; } + +.fa-subway:before { + content: "\f239"; } + +.fa-suitcase:before { + content: "\f0f2"; } + +.fa-suitcase-rolling:before { + content: "\f5c1"; } + +.fa-sun:before { + content: "\f185"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-superscript:before { + content: "\f12b"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-surprise:before { + content: "\f5c2"; } + +.fa-suse:before { + content: "\f7d6"; } + +.fa-swatchbook:before { + content: "\f5c3"; } + +.fa-swift:before { + content: "\f8e1"; } + +.fa-swimmer:before { + content: "\f5c4"; } + +.fa-swimming-pool:before { + content: "\f5c5"; } + +.fa-symfony:before { + content: "\f83d"; } + +.fa-synagogue:before { + content: "\f69b"; } + +.fa-sync:before { + content: "\f021"; } + +.fa-sync-alt:before { + content: "\f2f1"; } + +.fa-syringe:before { + content: "\f48e"; } + +.fa-table:before { + content: "\f0ce"; } + +.fa-table-tennis:before { + content: "\f45d"; } + +.fa-tablet:before { + content: "\f10a"; } + +.fa-tablet-alt:before { + content: "\f3fa"; } + +.fa-tablets:before { + content: "\f490"; } + +.fa-tachometer-alt:before { + content: "\f3fd"; } + +.fa-tag:before { + content: "\f02b"; } + +.fa-tags:before { + content: "\f02c"; } + +.fa-tape:before { + content: "\f4db"; } + +.fa-tasks:before { + content: "\f0ae"; } + +.fa-taxi:before { + content: "\f1ba"; } + +.fa-teamspeak:before { + content: "\f4f9"; } + +.fa-teeth:before { + content: "\f62e"; } + +.fa-teeth-open:before { + content: "\f62f"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f3fe"; } + +.fa-temperature-high:before { + content: "\f769"; } + +.fa-temperature-low:before { + content: "\f76b"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-tenge:before { + content: "\f7d7"; } + +.fa-terminal:before { + content: "\f120"; } + +.fa-text-height:before { + content: "\f034"; } + +.fa-text-width:before { + content: "\f035"; } + +.fa-th:before { + content: "\f00a"; } + +.fa-th-large:before { + content: "\f009"; } + +.fa-th-list:before { + content: "\f00b"; } + +.fa-the-red-yeti:before { + content: "\f69d"; } + +.fa-theater-masks:before { + content: "\f630"; } + +.fa-themeco:before { + content: "\f5c6"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-thermometer:before { + content: "\f491"; } + +.fa-thermometer-empty:before { + content: "\f2cb"; } + +.fa-thermometer-full:before { + content: "\f2c7"; } + +.fa-thermometer-half:before { + content: "\f2c9"; } + +.fa-thermometer-quarter:before { + content: "\f2ca"; } + +.fa-thermometer-three-quarters:before { + content: "\f2c8"; } + +.fa-think-peaks:before { + content: "\f731"; } + +.fa-thumbs-down:before { + content: "\f165"; } + +.fa-thumbs-up:before { + content: "\f164"; } + +.fa-thumbtack:before { + content: "\f08d"; } + +.fa-ticket-alt:before { + content: "\f3ff"; } + +.fa-tiktok:before { + content: "\e07b"; } + +.fa-times:before { + content: "\f00d"; } + +.fa-times-circle:before { + content: "\f057"; } + +.fa-tint:before { + content: "\f043"; } + +.fa-tint-slash:before { + content: "\f5c7"; } + +.fa-tired:before { + content: "\f5c8"; } + +.fa-toggle-off:before { + content: "\f204"; } + +.fa-toggle-on:before { + content: "\f205"; } + +.fa-toilet:before { + content: "\f7d8"; } + +.fa-toilet-paper:before { + content: "\f71e"; } + +.fa-toilet-paper-slash:before { + content: "\e072"; } + +.fa-toolbox:before { + content: "\f552"; } + +.fa-tools:before { + content: "\f7d9"; } + +.fa-tooth:before { + content: "\f5c9"; } + +.fa-torah:before { + content: "\f6a0"; } + +.fa-torii-gate:before { + content: "\f6a1"; } + +.fa-tractor:before { + content: "\f722"; } + +.fa-trade-federation:before { + content: "\f513"; } + +.fa-trademark:before { + content: "\f25c"; } + +.fa-traffic-light:before { + content: "\f637"; } + +.fa-trailer:before { + content: "\e041"; } + +.fa-train:before { + content: "\f238"; } + +.fa-tram:before { + content: "\f7da"; } + +.fa-transgender:before { + content: "\f224"; } + +.fa-transgender-alt:before { + content: "\f225"; } + +.fa-trash:before { + content: "\f1f8"; } + +.fa-trash-alt:before { + content: "\f2ed"; } + +.fa-trash-restore:before { + content: "\f829"; } + +.fa-trash-restore-alt:before { + content: "\f82a"; } + +.fa-tree:before { + content: "\f1bb"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-trophy:before { + content: "\f091"; } + +.fa-truck:before { + content: "\f0d1"; } + +.fa-truck-loading:before { + content: "\f4de"; } + +.fa-truck-monster:before { + content: "\f63b"; } + +.fa-truck-moving:before { + content: "\f4df"; } + +.fa-truck-pickup:before { + content: "\f63c"; } + +.fa-tshirt:before { + content: "\f553"; } + +.fa-tty:before { + content: "\f1e4"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-tv:before { + content: "\f26c"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-ubuntu:before { + content: "\f7df"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-umbraco:before { + content: "\f8e8"; } + +.fa-umbrella:before { + content: "\f0e9"; } + +.fa-umbrella-beach:before { + content: "\f5ca"; } + +.fa-uncharted:before { + content: "\e084"; } + +.fa-underline:before { + content: "\f0cd"; } + +.fa-undo:before { + content: "\f0e2"; } + +.fa-undo-alt:before { + content: "\f2ea"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-unity:before { + content: "\e049"; } + +.fa-universal-access:before { + content: "\f29a"; } + +.fa-university:before { + content: "\f19c"; } + +.fa-unlink:before { + content: "\f127"; } + +.fa-unlock:before { + content: "\f09c"; } + +.fa-unlock-alt:before { + content: "\f13e"; } + +.fa-unsplash:before { + content: "\e07c"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-upload:before { + content: "\f093"; } + +.fa-ups:before { + content: "\f7e0"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-user:before { + content: "\f007"; } + +.fa-user-alt:before { + content: "\f406"; } + +.fa-user-alt-slash:before { + content: "\f4fa"; } + +.fa-user-astronaut:before { + content: "\f4fb"; } + +.fa-user-check:before { + content: "\f4fc"; } + +.fa-user-circle:before { + content: "\f2bd"; } + +.fa-user-clock:before { + content: "\f4fd"; } + +.fa-user-cog:before { + content: "\f4fe"; } + +.fa-user-edit:before { + content: "\f4ff"; } + +.fa-user-friends:before { + content: "\f500"; } + +.fa-user-graduate:before { + content: "\f501"; } + +.fa-user-injured:before { + content: "\f728"; } + +.fa-user-lock:before { + content: "\f502"; } + +.fa-user-md:before { + content: "\f0f0"; } + +.fa-user-minus:before { + content: "\f503"; } + +.fa-user-ninja:before { + content: "\f504"; } + +.fa-user-nurse:before { + content: "\f82f"; } + +.fa-user-plus:before { + content: "\f234"; } + +.fa-user-secret:before { + content: "\f21b"; } + +.fa-user-shield:before { + content: "\f505"; } + +.fa-user-slash:before { + content: "\f506"; } + +.fa-user-tag:before { + content: "\f507"; } + +.fa-user-tie:before { + content: "\f508"; } + +.fa-user-times:before { + content: "\f235"; } + +.fa-users:before { + content: "\f0c0"; } + +.fa-users-cog:before { + content: "\f509"; } + +.fa-users-slash:before { + content: "\e073"; } + +.fa-usps:before { + content: "\f7e1"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-utensil-spoon:before { + content: "\f2e5"; } + +.fa-utensils:before { + content: "\f2e7"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-vector-square:before { + content: "\f5cb"; } + +.fa-venus:before { + content: "\f221"; } + +.fa-venus-double:before { + content: "\f226"; } + +.fa-venus-mars:before { + content: "\f228"; } + +.fa-vest:before { + content: "\e085"; } + +.fa-vest-patches:before { + content: "\e086"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-vial:before { + content: "\f492"; } + +.fa-vials:before { + content: "\f493"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-video:before { + content: "\f03d"; } + +.fa-video-slash:before { + content: "\f4e2"; } + +.fa-vihara:before { + content: "\f6a7"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-virus:before { + content: "\e074"; } + +.fa-virus-slash:before { + content: "\e075"; } + +.fa-viruses:before { + content: "\e076"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-voicemail:before { + content: "\f897"; } + +.fa-volleyball-ball:before { + content: "\f45f"; } + +.fa-volume-down:before { + content: "\f027"; } + +.fa-volume-mute:before { + content: "\f6a9"; } + +.fa-volume-off:before { + content: "\f026"; } + +.fa-volume-up:before { + content: "\f028"; } + +.fa-vote-yea:before { + content: "\f772"; } + +.fa-vr-cardboard:before { + content: "\f729"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-walking:before { + content: "\f554"; } + +.fa-wallet:before { + content: "\f555"; } + +.fa-warehouse:before { + content: "\f494"; } + +.fa-watchman-monitoring:before { + content: "\e087"; } + +.fa-water:before { + content: "\f773"; } + +.fa-wave-square:before { + content: "\f83e"; } + +.fa-waze:before { + content: "\f83f"; } + +.fa-weebly:before { + content: "\f5cc"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-weight:before { + content: "\f496"; } + +.fa-weight-hanging:before { + content: "\f5cd"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-wheelchair:before { + content: "\f193"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-wifi:before { + content: "\f1eb"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-wind:before { + content: "\f72e"; } + +.fa-window-close:before { + content: "\f410"; } + +.fa-window-maximize:before { + content: "\f2d0"; } + +.fa-window-minimize:before { + content: "\f2d1"; } + +.fa-window-restore:before { + content: "\f2d2"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-wine-bottle:before { + content: "\f72f"; } + +.fa-wine-glass:before { + content: "\f4e3"; } + +.fa-wine-glass-alt:before { + content: "\f5ce"; } + +.fa-wix:before { + content: "\f5cf"; } + +.fa-wizards-of-the-coast:before { + content: "\f730"; } + +.fa-wodu:before { + content: "\e088"; } + +.fa-wolf-pack-battalion:before { + content: "\f514"; } + +.fa-won-sign:before { + content: "\f159"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-wpressr:before { + content: "\f3e4"; } + +.fa-wrench:before { + content: "\f0ad"; } + +.fa-x-ray:before { + content: "\f497"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-yammer:before { + content: "\f840"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-yarn:before { + content: "\f7e3"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-yen-sign:before { + content: "\f157"; } + +.fa-yin-yang:before { + content: "\f6ad"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-youtube:before { + content: "\f167"; } + +.fa-youtube-square:before { + content: "\f431"; } + +.fa-zhihu:before { + content: "\f63f"; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } +@font-face { + font-family: 'Font Awesome 5 Brands'; + font-style: normal; + font-weight: 400; + font-display: block; + src: url("../webfonts/fa-brands-400.eot"); + src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } + +.fab { + font-family: 'Font Awesome 5 Brands'; + font-weight: 400; } +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 400; + font-display: block; + src: url("../webfonts/fa-regular-400.eot"); + src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } + +.far { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; } +@font-face { + font-family: 'Font Awesome 5 Free'; + font-style: normal; + font-weight: 900; + font-display: block; + src: url("../webfonts/fa-solid-900.eot"); + src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } + +.fa, +.fas { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; } diff --git a/assets/css/fontawesome.css b/assets/css/fontawesome.css new file mode 100644 index 0000000..74de602 --- /dev/null +++ b/assets/css/fontawesome.css @@ -0,0 +1,4582 @@ +/*! + * Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa, +.fas, +.far, +.fal, +.fad, +.fab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; } + +.fa-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.fa-xs { + font-size: .75em; } + +.fa-sm { + font-size: .875em; } + +.fa-1x { + font-size: 1em; } + +.fa-2x { + font-size: 2em; } + +.fa-3x { + font-size: 3em; } + +.fa-4x { + font-size: 4em; } + +.fa-5x { + font-size: 5em; } + +.fa-6x { + font-size: 6em; } + +.fa-7x { + font-size: 7em; } + +.fa-8x { + font-size: 8em; } + +.fa-9x { + font-size: 9em; } + +.fa-10x { + font-size: 10em; } + +.fa-fw { + text-align: center; + width: 1.25em; } + +.fa-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .fa-ul > li { + position: relative; } + +.fa-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.fa-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.fa-pull-left { + float: left; } + +.fa-pull-right { + float: right; } + +.fa.fa-pull-left, +.fas.fa-pull-left, +.far.fa-pull-left, +.fal.fa-pull-left, +.fab.fa-pull-left { + margin-right: .3em; } + +.fa.fa-pull-right, +.fas.fa-pull-right, +.far.fa-pull-right, +.fal.fa-pull-right, +.fab.fa-pull-right { + margin-left: .3em; } + +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; } + +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); } + +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical, +:root .fa-flip-both { + -webkit-filter: none; + filter: none; } + +.fa-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2.5em; } + +.fa-stack-1x, +.fa-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; } + +.fa-stack-1x { + line-height: inherit; } + +.fa-stack-2x { + font-size: 2em; } + +.fa-inverse { + color: #fff; } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ +.fa-500px:before { + content: "\f26e"; } + +.fa-accessible-icon:before { + content: "\f368"; } + +.fa-accusoft:before { + content: "\f369"; } + +.fa-acquisitions-incorporated:before { + content: "\f6af"; } + +.fa-ad:before { + content: "\f641"; } + +.fa-address-book:before { + content: "\f2b9"; } + +.fa-address-card:before { + content: "\f2bb"; } + +.fa-adjust:before { + content: "\f042"; } + +.fa-adn:before { + content: "\f170"; } + +.fa-adversal:before { + content: "\f36a"; } + +.fa-affiliatetheme:before { + content: "\f36b"; } + +.fa-air-freshener:before { + content: "\f5d0"; } + +.fa-airbnb:before { + content: "\f834"; } + +.fa-algolia:before { + content: "\f36c"; } + +.fa-align-center:before { + content: "\f037"; } + +.fa-align-justify:before { + content: "\f039"; } + +.fa-align-left:before { + content: "\f036"; } + +.fa-align-right:before { + content: "\f038"; } + +.fa-alipay:before { + content: "\f642"; } + +.fa-allergies:before { + content: "\f461"; } + +.fa-amazon:before { + content: "\f270"; } + +.fa-amazon-pay:before { + content: "\f42c"; } + +.fa-ambulance:before { + content: "\f0f9"; } + +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; } + +.fa-amilia:before { + content: "\f36d"; } + +.fa-anchor:before { + content: "\f13d"; } + +.fa-android:before { + content: "\f17b"; } + +.fa-angellist:before { + content: "\f209"; } + +.fa-angle-double-down:before { + content: "\f103"; } + +.fa-angle-double-left:before { + content: "\f100"; } + +.fa-angle-double-right:before { + content: "\f101"; } + +.fa-angle-double-up:before { + content: "\f102"; } + +.fa-angle-down:before { + content: "\f107"; } + +.fa-angle-left:before { + content: "\f104"; } + +.fa-angle-right:before { + content: "\f105"; } + +.fa-angle-up:before { + content: "\f106"; } + +.fa-angry:before { + content: "\f556"; } + +.fa-angrycreative:before { + content: "\f36e"; } + +.fa-angular:before { + content: "\f420"; } + +.fa-ankh:before { + content: "\f644"; } + +.fa-app-store:before { + content: "\f36f"; } + +.fa-app-store-ios:before { + content: "\f370"; } + +.fa-apper:before { + content: "\f371"; } + +.fa-apple:before { + content: "\f179"; } + +.fa-apple-alt:before { + content: "\f5d1"; } + +.fa-apple-pay:before { + content: "\f415"; } + +.fa-archive:before { + content: "\f187"; } + +.fa-archway:before { + content: "\f557"; } + +.fa-arrow-alt-circle-down:before { + content: "\f358"; } + +.fa-arrow-alt-circle-left:before { + content: "\f359"; } + +.fa-arrow-alt-circle-right:before { + content: "\f35a"; } + +.fa-arrow-alt-circle-up:before { + content: "\f35b"; } + +.fa-arrow-circle-down:before { + content: "\f0ab"; } + +.fa-arrow-circle-left:before { + content: "\f0a8"; } + +.fa-arrow-circle-right:before { + content: "\f0a9"; } + +.fa-arrow-circle-up:before { + content: "\f0aa"; } + +.fa-arrow-down:before { + content: "\f063"; } + +.fa-arrow-left:before { + content: "\f060"; } + +.fa-arrow-right:before { + content: "\f061"; } + +.fa-arrow-up:before { + content: "\f062"; } + +.fa-arrows-alt:before { + content: "\f0b2"; } + +.fa-arrows-alt-h:before { + content: "\f337"; } + +.fa-arrows-alt-v:before { + content: "\f338"; } + +.fa-artstation:before { + content: "\f77a"; } + +.fa-assistive-listening-systems:before { + content: "\f2a2"; } + +.fa-asterisk:before { + content: "\f069"; } + +.fa-asymmetrik:before { + content: "\f372"; } + +.fa-at:before { + content: "\f1fa"; } + +.fa-atlas:before { + content: "\f558"; } + +.fa-atlassian:before { + content: "\f77b"; } + +.fa-atom:before { + content: "\f5d2"; } + +.fa-audible:before { + content: "\f373"; } + +.fa-audio-description:before { + content: "\f29e"; } + +.fa-autoprefixer:before { + content: "\f41c"; } + +.fa-avianex:before { + content: "\f374"; } + +.fa-aviato:before { + content: "\f421"; } + +.fa-award:before { + content: "\f559"; } + +.fa-aws:before { + content: "\f375"; } + +.fa-baby:before { + content: "\f77c"; } + +.fa-baby-carriage:before { + content: "\f77d"; } + +.fa-backspace:before { + content: "\f55a"; } + +.fa-backward:before { + content: "\f04a"; } + +.fa-bacon:before { + content: "\f7e5"; } + +.fa-bacteria:before { + content: "\e059"; } + +.fa-bacterium:before { + content: "\e05a"; } + +.fa-bahai:before { + content: "\f666"; } + +.fa-balance-scale:before { + content: "\f24e"; } + +.fa-balance-scale-left:before { + content: "\f515"; } + +.fa-balance-scale-right:before { + content: "\f516"; } + +.fa-ban:before { + content: "\f05e"; } + +.fa-band-aid:before { + content: "\f462"; } + +.fa-bandcamp:before { + content: "\f2d5"; } + +.fa-barcode:before { + content: "\f02a"; } + +.fa-bars:before { + content: "\f0c9"; } + +.fa-baseball-ball:before { + content: "\f433"; } + +.fa-basketball-ball:before { + content: "\f434"; } + +.fa-bath:before { + content: "\f2cd"; } + +.fa-battery-empty:before { + content: "\f244"; } + +.fa-battery-full:before { + content: "\f240"; } + +.fa-battery-half:before { + content: "\f242"; } + +.fa-battery-quarter:before { + content: "\f243"; } + +.fa-battery-three-quarters:before { + content: "\f241"; } + +.fa-battle-net:before { + content: "\f835"; } + +.fa-bed:before { + content: "\f236"; } + +.fa-beer:before { + content: "\f0fc"; } + +.fa-behance:before { + content: "\f1b4"; } + +.fa-behance-square:before { + content: "\f1b5"; } + +.fa-bell:before { + content: "\f0f3"; } + +.fa-bell-slash:before { + content: "\f1f6"; } + +.fa-bezier-curve:before { + content: "\f55b"; } + +.fa-bible:before { + content: "\f647"; } + +.fa-bicycle:before { + content: "\f206"; } + +.fa-biking:before { + content: "\f84a"; } + +.fa-bimobject:before { + content: "\f378"; } + +.fa-binoculars:before { + content: "\f1e5"; } + +.fa-biohazard:before { + content: "\f780"; } + +.fa-birthday-cake:before { + content: "\f1fd"; } + +.fa-bitbucket:before { + content: "\f171"; } + +.fa-bitcoin:before { + content: "\f379"; } + +.fa-bity:before { + content: "\f37a"; } + +.fa-black-tie:before { + content: "\f27e"; } + +.fa-blackberry:before { + content: "\f37b"; } + +.fa-blender:before { + content: "\f517"; } + +.fa-blender-phone:before { + content: "\f6b6"; } + +.fa-blind:before { + content: "\f29d"; } + +.fa-blog:before { + content: "\f781"; } + +.fa-blogger:before { + content: "\f37c"; } + +.fa-blogger-b:before { + content: "\f37d"; } + +.fa-bluetooth:before { + content: "\f293"; } + +.fa-bluetooth-b:before { + content: "\f294"; } + +.fa-bold:before { + content: "\f032"; } + +.fa-bolt:before { + content: "\f0e7"; } + +.fa-bomb:before { + content: "\f1e2"; } + +.fa-bone:before { + content: "\f5d7"; } + +.fa-bong:before { + content: "\f55c"; } + +.fa-book:before { + content: "\f02d"; } + +.fa-book-dead:before { + content: "\f6b7"; } + +.fa-book-medical:before { + content: "\f7e6"; } + +.fa-book-open:before { + content: "\f518"; } + +.fa-book-reader:before { + content: "\f5da"; } + +.fa-bookmark:before { + content: "\f02e"; } + +.fa-bootstrap:before { + content: "\f836"; } + +.fa-border-all:before { + content: "\f84c"; } + +.fa-border-none:before { + content: "\f850"; } + +.fa-border-style:before { + content: "\f853"; } + +.fa-bowling-ball:before { + content: "\f436"; } + +.fa-box:before { + content: "\f466"; } + +.fa-box-open:before { + content: "\f49e"; } + +.fa-box-tissue:before { + content: "\e05b"; } + +.fa-boxes:before { + content: "\f468"; } + +.fa-braille:before { + content: "\f2a1"; } + +.fa-brain:before { + content: "\f5dc"; } + +.fa-bread-slice:before { + content: "\f7ec"; } + +.fa-briefcase:before { + content: "\f0b1"; } + +.fa-briefcase-medical:before { + content: "\f469"; } + +.fa-broadcast-tower:before { + content: "\f519"; } + +.fa-broom:before { + content: "\f51a"; } + +.fa-brush:before { + content: "\f55d"; } + +.fa-btc:before { + content: "\f15a"; } + +.fa-buffer:before { + content: "\f837"; } + +.fa-bug:before { + content: "\f188"; } + +.fa-building:before { + content: "\f1ad"; } + +.fa-bullhorn:before { + content: "\f0a1"; } + +.fa-bullseye:before { + content: "\f140"; } + +.fa-burn:before { + content: "\f46a"; } + +.fa-buromobelexperte:before { + content: "\f37f"; } + +.fa-bus:before { + content: "\f207"; } + +.fa-bus-alt:before { + content: "\f55e"; } + +.fa-business-time:before { + content: "\f64a"; } + +.fa-buy-n-large:before { + content: "\f8a6"; } + +.fa-buysellads:before { + content: "\f20d"; } + +.fa-calculator:before { + content: "\f1ec"; } + +.fa-calendar:before { + content: "\f133"; } + +.fa-calendar-alt:before { + content: "\f073"; } + +.fa-calendar-check:before { + content: "\f274"; } + +.fa-calendar-day:before { + content: "\f783"; } + +.fa-calendar-minus:before { + content: "\f272"; } + +.fa-calendar-plus:before { + content: "\f271"; } + +.fa-calendar-times:before { + content: "\f273"; } + +.fa-calendar-week:before { + content: "\f784"; } + +.fa-camera:before { + content: "\f030"; } + +.fa-camera-retro:before { + content: "\f083"; } + +.fa-campground:before { + content: "\f6bb"; } + +.fa-canadian-maple-leaf:before { + content: "\f785"; } + +.fa-candy-cane:before { + content: "\f786"; } + +.fa-cannabis:before { + content: "\f55f"; } + +.fa-capsules:before { + content: "\f46b"; } + +.fa-car:before { + content: "\f1b9"; } + +.fa-car-alt:before { + content: "\f5de"; } + +.fa-car-battery:before { + content: "\f5df"; } + +.fa-car-crash:before { + content: "\f5e1"; } + +.fa-car-side:before { + content: "\f5e4"; } + +.fa-caravan:before { + content: "\f8ff"; } + +.fa-caret-down:before { + content: "\f0d7"; } + +.fa-caret-left:before { + content: "\f0d9"; } + +.fa-caret-right:before { + content: "\f0da"; } + +.fa-caret-square-down:before { + content: "\f150"; } + +.fa-caret-square-left:before { + content: "\f191"; } + +.fa-caret-square-right:before { + content: "\f152"; } + +.fa-caret-square-up:before { + content: "\f151"; } + +.fa-caret-up:before { + content: "\f0d8"; } + +.fa-carrot:before { + content: "\f787"; } + +.fa-cart-arrow-down:before { + content: "\f218"; } + +.fa-cart-plus:before { + content: "\f217"; } + +.fa-cash-register:before { + content: "\f788"; } + +.fa-cat:before { + content: "\f6be"; } + +.fa-cc-amazon-pay:before { + content: "\f42d"; } + +.fa-cc-amex:before { + content: "\f1f3"; } + +.fa-cc-apple-pay:before { + content: "\f416"; } + +.fa-cc-diners-club:before { + content: "\f24c"; } + +.fa-cc-discover:before { + content: "\f1f2"; } + +.fa-cc-jcb:before { + content: "\f24b"; } + +.fa-cc-mastercard:before { + content: "\f1f1"; } + +.fa-cc-paypal:before { + content: "\f1f4"; } + +.fa-cc-stripe:before { + content: "\f1f5"; } + +.fa-cc-visa:before { + content: "\f1f0"; } + +.fa-centercode:before { + content: "\f380"; } + +.fa-centos:before { + content: "\f789"; } + +.fa-certificate:before { + content: "\f0a3"; } + +.fa-chair:before { + content: "\f6c0"; } + +.fa-chalkboard:before { + content: "\f51b"; } + +.fa-chalkboard-teacher:before { + content: "\f51c"; } + +.fa-charging-station:before { + content: "\f5e7"; } + +.fa-chart-area:before { + content: "\f1fe"; } + +.fa-chart-bar:before { + content: "\f080"; } + +.fa-chart-line:before { + content: "\f201"; } + +.fa-chart-pie:before { + content: "\f200"; } + +.fa-check:before { + content: "\f00c"; } + +.fa-check-circle:before { + content: "\f058"; } + +.fa-check-double:before { + content: "\f560"; } + +.fa-check-square:before { + content: "\f14a"; } + +.fa-cheese:before { + content: "\f7ef"; } + +.fa-chess:before { + content: "\f439"; } + +.fa-chess-bishop:before { + content: "\f43a"; } + +.fa-chess-board:before { + content: "\f43c"; } + +.fa-chess-king:before { + content: "\f43f"; } + +.fa-chess-knight:before { + content: "\f441"; } + +.fa-chess-pawn:before { + content: "\f443"; } + +.fa-chess-queen:before { + content: "\f445"; } + +.fa-chess-rook:before { + content: "\f447"; } + +.fa-chevron-circle-down:before { + content: "\f13a"; } + +.fa-chevron-circle-left:before { + content: "\f137"; } + +.fa-chevron-circle-right:before { + content: "\f138"; } + +.fa-chevron-circle-up:before { + content: "\f139"; } + +.fa-chevron-down:before { + content: "\f078"; } + +.fa-chevron-left:before { + content: "\f053"; } + +.fa-chevron-right:before { + content: "\f054"; } + +.fa-chevron-up:before { + content: "\f077"; } + +.fa-child:before { + content: "\f1ae"; } + +.fa-chrome:before { + content: "\f268"; } + +.fa-chromecast:before { + content: "\f838"; } + +.fa-church:before { + content: "\f51d"; } + +.fa-circle:before { + content: "\f111"; } + +.fa-circle-notch:before { + content: "\f1ce"; } + +.fa-city:before { + content: "\f64f"; } + +.fa-clinic-medical:before { + content: "\f7f2"; } + +.fa-clipboard:before { + content: "\f328"; } + +.fa-clipboard-check:before { + content: "\f46c"; } + +.fa-clipboard-list:before { + content: "\f46d"; } + +.fa-clock:before { + content: "\f017"; } + +.fa-clone:before { + content: "\f24d"; } + +.fa-closed-captioning:before { + content: "\f20a"; } + +.fa-cloud:before { + content: "\f0c2"; } + +.fa-cloud-download-alt:before { + content: "\f381"; } + +.fa-cloud-meatball:before { + content: "\f73b"; } + +.fa-cloud-moon:before { + content: "\f6c3"; } + +.fa-cloud-moon-rain:before { + content: "\f73c"; } + +.fa-cloud-rain:before { + content: "\f73d"; } + +.fa-cloud-showers-heavy:before { + content: "\f740"; } + +.fa-cloud-sun:before { + content: "\f6c4"; } + +.fa-cloud-sun-rain:before { + content: "\f743"; } + +.fa-cloud-upload-alt:before { + content: "\f382"; } + +.fa-cloudflare:before { + content: "\e07d"; } + +.fa-cloudscale:before { + content: "\f383"; } + +.fa-cloudsmith:before { + content: "\f384"; } + +.fa-cloudversify:before { + content: "\f385"; } + +.fa-cocktail:before { + content: "\f561"; } + +.fa-code:before { + content: "\f121"; } + +.fa-code-branch:before { + content: "\f126"; } + +.fa-codepen:before { + content: "\f1cb"; } + +.fa-codiepie:before { + content: "\f284"; } + +.fa-coffee:before { + content: "\f0f4"; } + +.fa-cog:before { + content: "\f013"; } + +.fa-cogs:before { + content: "\f085"; } + +.fa-coins:before { + content: "\f51e"; } + +.fa-columns:before { + content: "\f0db"; } + +.fa-comment:before { + content: "\f075"; } + +.fa-comment-alt:before { + content: "\f27a"; } + +.fa-comment-dollar:before { + content: "\f651"; } + +.fa-comment-dots:before { + content: "\f4ad"; } + +.fa-comment-medical:before { + content: "\f7f5"; } + +.fa-comment-slash:before { + content: "\f4b3"; } + +.fa-comments:before { + content: "\f086"; } + +.fa-comments-dollar:before { + content: "\f653"; } + +.fa-compact-disc:before { + content: "\f51f"; } + +.fa-compass:before { + content: "\f14e"; } + +.fa-compress:before { + content: "\f066"; } + +.fa-compress-alt:before { + content: "\f422"; } + +.fa-compress-arrows-alt:before { + content: "\f78c"; } + +.fa-concierge-bell:before { + content: "\f562"; } + +.fa-confluence:before { + content: "\f78d"; } + +.fa-connectdevelop:before { + content: "\f20e"; } + +.fa-contao:before { + content: "\f26d"; } + +.fa-cookie:before { + content: "\f563"; } + +.fa-cookie-bite:before { + content: "\f564"; } + +.fa-copy:before { + content: "\f0c5"; } + +.fa-copyright:before { + content: "\f1f9"; } + +.fa-cotton-bureau:before { + content: "\f89e"; } + +.fa-couch:before { + content: "\f4b8"; } + +.fa-cpanel:before { + content: "\f388"; } + +.fa-creative-commons:before { + content: "\f25e"; } + +.fa-creative-commons-by:before { + content: "\f4e7"; } + +.fa-creative-commons-nc:before { + content: "\f4e8"; } + +.fa-creative-commons-nc-eu:before { + content: "\f4e9"; } + +.fa-creative-commons-nc-jp:before { + content: "\f4ea"; } + +.fa-creative-commons-nd:before { + content: "\f4eb"; } + +.fa-creative-commons-pd:before { + content: "\f4ec"; } + +.fa-creative-commons-pd-alt:before { + content: "\f4ed"; } + +.fa-creative-commons-remix:before { + content: "\f4ee"; } + +.fa-creative-commons-sa:before { + content: "\f4ef"; } + +.fa-creative-commons-sampling:before { + content: "\f4f0"; } + +.fa-creative-commons-sampling-plus:before { + content: "\f4f1"; } + +.fa-creative-commons-share:before { + content: "\f4f2"; } + +.fa-creative-commons-zero:before { + content: "\f4f3"; } + +.fa-credit-card:before { + content: "\f09d"; } + +.fa-critical-role:before { + content: "\f6c9"; } + +.fa-crop:before { + content: "\f125"; } + +.fa-crop-alt:before { + content: "\f565"; } + +.fa-cross:before { + content: "\f654"; } + +.fa-crosshairs:before { + content: "\f05b"; } + +.fa-crow:before { + content: "\f520"; } + +.fa-crown:before { + content: "\f521"; } + +.fa-crutch:before { + content: "\f7f7"; } + +.fa-css3:before { + content: "\f13c"; } + +.fa-css3-alt:before { + content: "\f38b"; } + +.fa-cube:before { + content: "\f1b2"; } + +.fa-cubes:before { + content: "\f1b3"; } + +.fa-cut:before { + content: "\f0c4"; } + +.fa-cuttlefish:before { + content: "\f38c"; } + +.fa-d-and-d:before { + content: "\f38d"; } + +.fa-d-and-d-beyond:before { + content: "\f6ca"; } + +.fa-dailymotion:before { + content: "\e052"; } + +.fa-dashcube:before { + content: "\f210"; } + +.fa-database:before { + content: "\f1c0"; } + +.fa-deaf:before { + content: "\f2a4"; } + +.fa-deezer:before { + content: "\e077"; } + +.fa-delicious:before { + content: "\f1a5"; } + +.fa-democrat:before { + content: "\f747"; } + +.fa-deploydog:before { + content: "\f38e"; } + +.fa-deskpro:before { + content: "\f38f"; } + +.fa-desktop:before { + content: "\f108"; } + +.fa-dev:before { + content: "\f6cc"; } + +.fa-deviantart:before { + content: "\f1bd"; } + +.fa-dharmachakra:before { + content: "\f655"; } + +.fa-dhl:before { + content: "\f790"; } + +.fa-diagnoses:before { + content: "\f470"; } + +.fa-diaspora:before { + content: "\f791"; } + +.fa-dice:before { + content: "\f522"; } + +.fa-dice-d20:before { + content: "\f6cf"; } + +.fa-dice-d6:before { + content: "\f6d1"; } + +.fa-dice-five:before { + content: "\f523"; } + +.fa-dice-four:before { + content: "\f524"; } + +.fa-dice-one:before { + content: "\f525"; } + +.fa-dice-six:before { + content: "\f526"; } + +.fa-dice-three:before { + content: "\f527"; } + +.fa-dice-two:before { + content: "\f528"; } + +.fa-digg:before { + content: "\f1a6"; } + +.fa-digital-ocean:before { + content: "\f391"; } + +.fa-digital-tachograph:before { + content: "\f566"; } + +.fa-directions:before { + content: "\f5eb"; } + +.fa-discord:before { + content: "\f392"; } + +.fa-discourse:before { + content: "\f393"; } + +.fa-disease:before { + content: "\f7fa"; } + +.fa-divide:before { + content: "\f529"; } + +.fa-dizzy:before { + content: "\f567"; } + +.fa-dna:before { + content: "\f471"; } + +.fa-dochub:before { + content: "\f394"; } + +.fa-docker:before { + content: "\f395"; } + +.fa-dog:before { + content: "\f6d3"; } + +.fa-dollar-sign:before { + content: "\f155"; } + +.fa-dolly:before { + content: "\f472"; } + +.fa-dolly-flatbed:before { + content: "\f474"; } + +.fa-donate:before { + content: "\f4b9"; } + +.fa-door-closed:before { + content: "\f52a"; } + +.fa-door-open:before { + content: "\f52b"; } + +.fa-dot-circle:before { + content: "\f192"; } + +.fa-dove:before { + content: "\f4ba"; } + +.fa-download:before { + content: "\f019"; } + +.fa-draft2digital:before { + content: "\f396"; } + +.fa-drafting-compass:before { + content: "\f568"; } + +.fa-dragon:before { + content: "\f6d5"; } + +.fa-draw-polygon:before { + content: "\f5ee"; } + +.fa-dribbble:before { + content: "\f17d"; } + +.fa-dribbble-square:before { + content: "\f397"; } + +.fa-dropbox:before { + content: "\f16b"; } + +.fa-drum:before { + content: "\f569"; } + +.fa-drum-steelpan:before { + content: "\f56a"; } + +.fa-drumstick-bite:before { + content: "\f6d7"; } + +.fa-drupal:before { + content: "\f1a9"; } + +.fa-dumbbell:before { + content: "\f44b"; } + +.fa-dumpster:before { + content: "\f793"; } + +.fa-dumpster-fire:before { + content: "\f794"; } + +.fa-dungeon:before { + content: "\f6d9"; } + +.fa-dyalog:before { + content: "\f399"; } + +.fa-earlybirds:before { + content: "\f39a"; } + +.fa-ebay:before { + content: "\f4f4"; } + +.fa-edge:before { + content: "\f282"; } + +.fa-edge-legacy:before { + content: "\e078"; } + +.fa-edit:before { + content: "\f044"; } + +.fa-egg:before { + content: "\f7fb"; } + +.fa-eject:before { + content: "\f052"; } + +.fa-elementor:before { + content: "\f430"; } + +.fa-ellipsis-h:before { + content: "\f141"; } + +.fa-ellipsis-v:before { + content: "\f142"; } + +.fa-ello:before { + content: "\f5f1"; } + +.fa-ember:before { + content: "\f423"; } + +.fa-empire:before { + content: "\f1d1"; } + +.fa-envelope:before { + content: "\f0e0"; } + +.fa-envelope-open:before { + content: "\f2b6"; } + +.fa-envelope-open-text:before { + content: "\f658"; } + +.fa-envelope-square:before { + content: "\f199"; } + +.fa-envira:before { + content: "\f299"; } + +.fa-equals:before { + content: "\f52c"; } + +.fa-eraser:before { + content: "\f12d"; } + +.fa-erlang:before { + content: "\f39d"; } + +.fa-ethereum:before { + content: "\f42e"; } + +.fa-ethernet:before { + content: "\f796"; } + +.fa-etsy:before { + content: "\f2d7"; } + +.fa-euro-sign:before { + content: "\f153"; } + +.fa-evernote:before { + content: "\f839"; } + +.fa-exchange-alt:before { + content: "\f362"; } + +.fa-exclamation:before { + content: "\f12a"; } + +.fa-exclamation-circle:before { + content: "\f06a"; } + +.fa-exclamation-triangle:before { + content: "\f071"; } + +.fa-expand:before { + content: "\f065"; } + +.fa-expand-alt:before { + content: "\f424"; } + +.fa-expand-arrows-alt:before { + content: "\f31e"; } + +.fa-expeditedssl:before { + content: "\f23e"; } + +.fa-external-link-alt:before { + content: "\f35d"; } + +.fa-external-link-square-alt:before { + content: "\f360"; } + +.fa-eye:before { + content: "\f06e"; } + +.fa-eye-dropper:before { + content: "\f1fb"; } + +.fa-eye-slash:before { + content: "\f070"; } + +.fa-facebook:before { + content: "\f09a"; } + +.fa-facebook-f:before { + content: "\f39e"; } + +.fa-facebook-messenger:before { + content: "\f39f"; } + +.fa-facebook-square:before { + content: "\f082"; } + +.fa-fan:before { + content: "\f863"; } + +.fa-fantasy-flight-games:before { + content: "\f6dc"; } + +.fa-fast-backward:before { + content: "\f049"; } + +.fa-fast-forward:before { + content: "\f050"; } + +.fa-faucet:before { + content: "\e005"; } + +.fa-fax:before { + content: "\f1ac"; } + +.fa-feather:before { + content: "\f52d"; } + +.fa-feather-alt:before { + content: "\f56b"; } + +.fa-fedex:before { + content: "\f797"; } + +.fa-fedora:before { + content: "\f798"; } + +.fa-female:before { + content: "\f182"; } + +.fa-fighter-jet:before { + content: "\f0fb"; } + +.fa-figma:before { + content: "\f799"; } + +.fa-file:before { + content: "\f15b"; } + +.fa-file-alt:before { + content: "\f15c"; } + +.fa-file-archive:before { + content: "\f1c6"; } + +.fa-file-audio:before { + content: "\f1c7"; } + +.fa-file-code:before { + content: "\f1c9"; } + +.fa-file-contract:before { + content: "\f56c"; } + +.fa-file-csv:before { + content: "\f6dd"; } + +.fa-file-download:before { + content: "\f56d"; } + +.fa-file-excel:before { + content: "\f1c3"; } + +.fa-file-export:before { + content: "\f56e"; } + +.fa-file-image:before { + content: "\f1c5"; } + +.fa-file-import:before { + content: "\f56f"; } + +.fa-file-invoice:before { + content: "\f570"; } + +.fa-file-invoice-dollar:before { + content: "\f571"; } + +.fa-file-medical:before { + content: "\f477"; } + +.fa-file-medical-alt:before { + content: "\f478"; } + +.fa-file-pdf:before { + content: "\f1c1"; } + +.fa-file-powerpoint:before { + content: "\f1c4"; } + +.fa-file-prescription:before { + content: "\f572"; } + +.fa-file-signature:before { + content: "\f573"; } + +.fa-file-upload:before { + content: "\f574"; } + +.fa-file-video:before { + content: "\f1c8"; } + +.fa-file-word:before { + content: "\f1c2"; } + +.fa-fill:before { + content: "\f575"; } + +.fa-fill-drip:before { + content: "\f576"; } + +.fa-film:before { + content: "\f008"; } + +.fa-filter:before { + content: "\f0b0"; } + +.fa-fingerprint:before { + content: "\f577"; } + +.fa-fire:before { + content: "\f06d"; } + +.fa-fire-alt:before { + content: "\f7e4"; } + +.fa-fire-extinguisher:before { + content: "\f134"; } + +.fa-firefox:before { + content: "\f269"; } + +.fa-firefox-browser:before { + content: "\e007"; } + +.fa-first-aid:before { + content: "\f479"; } + +.fa-first-order:before { + content: "\f2b0"; } + +.fa-first-order-alt:before { + content: "\f50a"; } + +.fa-firstdraft:before { + content: "\f3a1"; } + +.fa-fish:before { + content: "\f578"; } + +.fa-fist-raised:before { + content: "\f6de"; } + +.fa-flag:before { + content: "\f024"; } + +.fa-flag-checkered:before { + content: "\f11e"; } + +.fa-flag-usa:before { + content: "\f74d"; } + +.fa-flask:before { + content: "\f0c3"; } + +.fa-flickr:before { + content: "\f16e"; } + +.fa-flipboard:before { + content: "\f44d"; } + +.fa-flushed:before { + content: "\f579"; } + +.fa-fly:before { + content: "\f417"; } + +.fa-folder:before { + content: "\f07b"; } + +.fa-folder-minus:before { + content: "\f65d"; } + +.fa-folder-open:before { + content: "\f07c"; } + +.fa-folder-plus:before { + content: "\f65e"; } + +.fa-font:before { + content: "\f031"; } + +.fa-font-awesome:before { + content: "\f2b4"; } + +.fa-font-awesome-alt:before { + content: "\f35c"; } + +.fa-font-awesome-flag:before { + content: "\f425"; } + +.fa-font-awesome-logo-full:before { + content: "\f4e6"; } + +.fa-fonticons:before { + content: "\f280"; } + +.fa-fonticons-fi:before { + content: "\f3a2"; } + +.fa-football-ball:before { + content: "\f44e"; } + +.fa-fort-awesome:before { + content: "\f286"; } + +.fa-fort-awesome-alt:before { + content: "\f3a3"; } + +.fa-forumbee:before { + content: "\f211"; } + +.fa-forward:before { + content: "\f04e"; } + +.fa-foursquare:before { + content: "\f180"; } + +.fa-free-code-camp:before { + content: "\f2c5"; } + +.fa-freebsd:before { + content: "\f3a4"; } + +.fa-frog:before { + content: "\f52e"; } + +.fa-frown:before { + content: "\f119"; } + +.fa-frown-open:before { + content: "\f57a"; } + +.fa-fulcrum:before { + content: "\f50b"; } + +.fa-funnel-dollar:before { + content: "\f662"; } + +.fa-futbol:before { + content: "\f1e3"; } + +.fa-galactic-republic:before { + content: "\f50c"; } + +.fa-galactic-senate:before { + content: "\f50d"; } + +.fa-gamepad:before { + content: "\f11b"; } + +.fa-gas-pump:before { + content: "\f52f"; } + +.fa-gavel:before { + content: "\f0e3"; } + +.fa-gem:before { + content: "\f3a5"; } + +.fa-genderless:before { + content: "\f22d"; } + +.fa-get-pocket:before { + content: "\f265"; } + +.fa-gg:before { + content: "\f260"; } + +.fa-gg-circle:before { + content: "\f261"; } + +.fa-ghost:before { + content: "\f6e2"; } + +.fa-gift:before { + content: "\f06b"; } + +.fa-gifts:before { + content: "\f79c"; } + +.fa-git:before { + content: "\f1d3"; } + +.fa-git-alt:before { + content: "\f841"; } + +.fa-git-square:before { + content: "\f1d2"; } + +.fa-github:before { + content: "\f09b"; } + +.fa-github-alt:before { + content: "\f113"; } + +.fa-github-square:before { + content: "\f092"; } + +.fa-gitkraken:before { + content: "\f3a6"; } + +.fa-gitlab:before { + content: "\f296"; } + +.fa-gitter:before { + content: "\f426"; } + +.fa-glass-cheers:before { + content: "\f79f"; } + +.fa-glass-martini:before { + content: "\f000"; } + +.fa-glass-martini-alt:before { + content: "\f57b"; } + +.fa-glass-whiskey:before { + content: "\f7a0"; } + +.fa-glasses:before { + content: "\f530"; } + +.fa-glide:before { + content: "\f2a5"; } + +.fa-glide-g:before { + content: "\f2a6"; } + +.fa-globe:before { + content: "\f0ac"; } + +.fa-globe-africa:before { + content: "\f57c"; } + +.fa-globe-americas:before { + content: "\f57d"; } + +.fa-globe-asia:before { + content: "\f57e"; } + +.fa-globe-europe:before { + content: "\f7a2"; } + +.fa-gofore:before { + content: "\f3a7"; } + +.fa-golf-ball:before { + content: "\f450"; } + +.fa-goodreads:before { + content: "\f3a8"; } + +.fa-goodreads-g:before { + content: "\f3a9"; } + +.fa-google:before { + content: "\f1a0"; } + +.fa-google-drive:before { + content: "\f3aa"; } + +.fa-google-pay:before { + content: "\e079"; } + +.fa-google-play:before { + content: "\f3ab"; } + +.fa-google-plus:before { + content: "\f2b3"; } + +.fa-google-plus-g:before { + content: "\f0d5"; } + +.fa-google-plus-square:before { + content: "\f0d4"; } + +.fa-google-wallet:before { + content: "\f1ee"; } + +.fa-gopuram:before { + content: "\f664"; } + +.fa-graduation-cap:before { + content: "\f19d"; } + +.fa-gratipay:before { + content: "\f184"; } + +.fa-grav:before { + content: "\f2d6"; } + +.fa-greater-than:before { + content: "\f531"; } + +.fa-greater-than-equal:before { + content: "\f532"; } + +.fa-grimace:before { + content: "\f57f"; } + +.fa-grin:before { + content: "\f580"; } + +.fa-grin-alt:before { + content: "\f581"; } + +.fa-grin-beam:before { + content: "\f582"; } + +.fa-grin-beam-sweat:before { + content: "\f583"; } + +.fa-grin-hearts:before { + content: "\f584"; } + +.fa-grin-squint:before { + content: "\f585"; } + +.fa-grin-squint-tears:before { + content: "\f586"; } + +.fa-grin-stars:before { + content: "\f587"; } + +.fa-grin-tears:before { + content: "\f588"; } + +.fa-grin-tongue:before { + content: "\f589"; } + +.fa-grin-tongue-squint:before { + content: "\f58a"; } + +.fa-grin-tongue-wink:before { + content: "\f58b"; } + +.fa-grin-wink:before { + content: "\f58c"; } + +.fa-grip-horizontal:before { + content: "\f58d"; } + +.fa-grip-lines:before { + content: "\f7a4"; } + +.fa-grip-lines-vertical:before { + content: "\f7a5"; } + +.fa-grip-vertical:before { + content: "\f58e"; } + +.fa-gripfire:before { + content: "\f3ac"; } + +.fa-grunt:before { + content: "\f3ad"; } + +.fa-guilded:before { + content: "\e07e"; } + +.fa-guitar:before { + content: "\f7a6"; } + +.fa-gulp:before { + content: "\f3ae"; } + +.fa-h-square:before { + content: "\f0fd"; } + +.fa-hacker-news:before { + content: "\f1d4"; } + +.fa-hacker-news-square:before { + content: "\f3af"; } + +.fa-hackerrank:before { + content: "\f5f7"; } + +.fa-hamburger:before { + content: "\f805"; } + +.fa-hammer:before { + content: "\f6e3"; } + +.fa-hamsa:before { + content: "\f665"; } + +.fa-hand-holding:before { + content: "\f4bd"; } + +.fa-hand-holding-heart:before { + content: "\f4be"; } + +.fa-hand-holding-medical:before { + content: "\e05c"; } + +.fa-hand-holding-usd:before { + content: "\f4c0"; } + +.fa-hand-holding-water:before { + content: "\f4c1"; } + +.fa-hand-lizard:before { + content: "\f258"; } + +.fa-hand-middle-finger:before { + content: "\f806"; } + +.fa-hand-paper:before { + content: "\f256"; } + +.fa-hand-peace:before { + content: "\f25b"; } + +.fa-hand-point-down:before { + content: "\f0a7"; } + +.fa-hand-point-left:before { + content: "\f0a5"; } + +.fa-hand-point-right:before { + content: "\f0a4"; } + +.fa-hand-point-up:before { + content: "\f0a6"; } + +.fa-hand-pointer:before { + content: "\f25a"; } + +.fa-hand-rock:before { + content: "\f255"; } + +.fa-hand-scissors:before { + content: "\f257"; } + +.fa-hand-sparkles:before { + content: "\e05d"; } + +.fa-hand-spock:before { + content: "\f259"; } + +.fa-hands:before { + content: "\f4c2"; } + +.fa-hands-helping:before { + content: "\f4c4"; } + +.fa-hands-wash:before { + content: "\e05e"; } + +.fa-handshake:before { + content: "\f2b5"; } + +.fa-handshake-alt-slash:before { + content: "\e05f"; } + +.fa-handshake-slash:before { + content: "\e060"; } + +.fa-hanukiah:before { + content: "\f6e6"; } + +.fa-hard-hat:before { + content: "\f807"; } + +.fa-hashtag:before { + content: "\f292"; } + +.fa-hat-cowboy:before { + content: "\f8c0"; } + +.fa-hat-cowboy-side:before { + content: "\f8c1"; } + +.fa-hat-wizard:before { + content: "\f6e8"; } + +.fa-hdd:before { + content: "\f0a0"; } + +.fa-head-side-cough:before { + content: "\e061"; } + +.fa-head-side-cough-slash:before { + content: "\e062"; } + +.fa-head-side-mask:before { + content: "\e063"; } + +.fa-head-side-virus:before { + content: "\e064"; } + +.fa-heading:before { + content: "\f1dc"; } + +.fa-headphones:before { + content: "\f025"; } + +.fa-headphones-alt:before { + content: "\f58f"; } + +.fa-headset:before { + content: "\f590"; } + +.fa-heart:before { + content: "\f004"; } + +.fa-heart-broken:before { + content: "\f7a9"; } + +.fa-heartbeat:before { + content: "\f21e"; } + +.fa-helicopter:before { + content: "\f533"; } + +.fa-highlighter:before { + content: "\f591"; } + +.fa-hiking:before { + content: "\f6ec"; } + +.fa-hippo:before { + content: "\f6ed"; } + +.fa-hips:before { + content: "\f452"; } + +.fa-hire-a-helper:before { + content: "\f3b0"; } + +.fa-history:before { + content: "\f1da"; } + +.fa-hive:before { + content: "\e07f"; } + +.fa-hockey-puck:before { + content: "\f453"; } + +.fa-holly-berry:before { + content: "\f7aa"; } + +.fa-home:before { + content: "\f015"; } + +.fa-hooli:before { + content: "\f427"; } + +.fa-hornbill:before { + content: "\f592"; } + +.fa-horse:before { + content: "\f6f0"; } + +.fa-horse-head:before { + content: "\f7ab"; } + +.fa-hospital:before { + content: "\f0f8"; } + +.fa-hospital-alt:before { + content: "\f47d"; } + +.fa-hospital-symbol:before { + content: "\f47e"; } + +.fa-hospital-user:before { + content: "\f80d"; } + +.fa-hot-tub:before { + content: "\f593"; } + +.fa-hotdog:before { + content: "\f80f"; } + +.fa-hotel:before { + content: "\f594"; } + +.fa-hotjar:before { + content: "\f3b1"; } + +.fa-hourglass:before { + content: "\f254"; } + +.fa-hourglass-end:before { + content: "\f253"; } + +.fa-hourglass-half:before { + content: "\f252"; } + +.fa-hourglass-start:before { + content: "\f251"; } + +.fa-house-damage:before { + content: "\f6f1"; } + +.fa-house-user:before { + content: "\e065"; } + +.fa-houzz:before { + content: "\f27c"; } + +.fa-hryvnia:before { + content: "\f6f2"; } + +.fa-html5:before { + content: "\f13b"; } + +.fa-hubspot:before { + content: "\f3b2"; } + +.fa-i-cursor:before { + content: "\f246"; } + +.fa-ice-cream:before { + content: "\f810"; } + +.fa-icicles:before { + content: "\f7ad"; } + +.fa-icons:before { + content: "\f86d"; } + +.fa-id-badge:before { + content: "\f2c1"; } + +.fa-id-card:before { + content: "\f2c2"; } + +.fa-id-card-alt:before { + content: "\f47f"; } + +.fa-ideal:before { + content: "\e013"; } + +.fa-igloo:before { + content: "\f7ae"; } + +.fa-image:before { + content: "\f03e"; } + +.fa-images:before { + content: "\f302"; } + +.fa-imdb:before { + content: "\f2d8"; } + +.fa-inbox:before { + content: "\f01c"; } + +.fa-indent:before { + content: "\f03c"; } + +.fa-industry:before { + content: "\f275"; } + +.fa-infinity:before { + content: "\f534"; } + +.fa-info:before { + content: "\f129"; } + +.fa-info-circle:before { + content: "\f05a"; } + +.fa-innosoft:before { + content: "\e080"; } + +.fa-instagram:before { + content: "\f16d"; } + +.fa-instagram-square:before { + content: "\e055"; } + +.fa-instalod:before { + content: "\e081"; } + +.fa-intercom:before { + content: "\f7af"; } + +.fa-internet-explorer:before { + content: "\f26b"; } + +.fa-invision:before { + content: "\f7b0"; } + +.fa-ioxhost:before { + content: "\f208"; } + +.fa-italic:before { + content: "\f033"; } + +.fa-itch-io:before { + content: "\f83a"; } + +.fa-itunes:before { + content: "\f3b4"; } + +.fa-itunes-note:before { + content: "\f3b5"; } + +.fa-java:before { + content: "\f4e4"; } + +.fa-jedi:before { + content: "\f669"; } + +.fa-jedi-order:before { + content: "\f50e"; } + +.fa-jenkins:before { + content: "\f3b6"; } + +.fa-jira:before { + content: "\f7b1"; } + +.fa-joget:before { + content: "\f3b7"; } + +.fa-joint:before { + content: "\f595"; } + +.fa-joomla:before { + content: "\f1aa"; } + +.fa-journal-whills:before { + content: "\f66a"; } + +.fa-js:before { + content: "\f3b8"; } + +.fa-js-square:before { + content: "\f3b9"; } + +.fa-jsfiddle:before { + content: "\f1cc"; } + +.fa-kaaba:before { + content: "\f66b"; } + +.fa-kaggle:before { + content: "\f5fa"; } + +.fa-key:before { + content: "\f084"; } + +.fa-keybase:before { + content: "\f4f5"; } + +.fa-keyboard:before { + content: "\f11c"; } + +.fa-keycdn:before { + content: "\f3ba"; } + +.fa-khanda:before { + content: "\f66d"; } + +.fa-kickstarter:before { + content: "\f3bb"; } + +.fa-kickstarter-k:before { + content: "\f3bc"; } + +.fa-kiss:before { + content: "\f596"; } + +.fa-kiss-beam:before { + content: "\f597"; } + +.fa-kiss-wink-heart:before { + content: "\f598"; } + +.fa-kiwi-bird:before { + content: "\f535"; } + +.fa-korvue:before { + content: "\f42f"; } + +.fa-landmark:before { + content: "\f66f"; } + +.fa-language:before { + content: "\f1ab"; } + +.fa-laptop:before { + content: "\f109"; } + +.fa-laptop-code:before { + content: "\f5fc"; } + +.fa-laptop-house:before { + content: "\e066"; } + +.fa-laptop-medical:before { + content: "\f812"; } + +.fa-laravel:before { + content: "\f3bd"; } + +.fa-lastfm:before { + content: "\f202"; } + +.fa-lastfm-square:before { + content: "\f203"; } + +.fa-laugh:before { + content: "\f599"; } + +.fa-laugh-beam:before { + content: "\f59a"; } + +.fa-laugh-squint:before { + content: "\f59b"; } + +.fa-laugh-wink:before { + content: "\f59c"; } + +.fa-layer-group:before { + content: "\f5fd"; } + +.fa-leaf:before { + content: "\f06c"; } + +.fa-leanpub:before { + content: "\f212"; } + +.fa-lemon:before { + content: "\f094"; } + +.fa-less:before { + content: "\f41d"; } + +.fa-less-than:before { + content: "\f536"; } + +.fa-less-than-equal:before { + content: "\f537"; } + +.fa-level-down-alt:before { + content: "\f3be"; } + +.fa-level-up-alt:before { + content: "\f3bf"; } + +.fa-life-ring:before { + content: "\f1cd"; } + +.fa-lightbulb:before { + content: "\f0eb"; } + +.fa-line:before { + content: "\f3c0"; } + +.fa-link:before { + content: "\f0c1"; } + +.fa-linkedin:before { + content: "\f08c"; } + +.fa-linkedin-in:before { + content: "\f0e1"; } + +.fa-linode:before { + content: "\f2b8"; } + +.fa-linux:before { + content: "\f17c"; } + +.fa-lira-sign:before { + content: "\f195"; } + +.fa-list:before { + content: "\f03a"; } + +.fa-list-alt:before { + content: "\f022"; } + +.fa-list-ol:before { + content: "\f0cb"; } + +.fa-list-ul:before { + content: "\f0ca"; } + +.fa-location-arrow:before { + content: "\f124"; } + +.fa-lock:before { + content: "\f023"; } + +.fa-lock-open:before { + content: "\f3c1"; } + +.fa-long-arrow-alt-down:before { + content: "\f309"; } + +.fa-long-arrow-alt-left:before { + content: "\f30a"; } + +.fa-long-arrow-alt-right:before { + content: "\f30b"; } + +.fa-long-arrow-alt-up:before { + content: "\f30c"; } + +.fa-low-vision:before { + content: "\f2a8"; } + +.fa-luggage-cart:before { + content: "\f59d"; } + +.fa-lungs:before { + content: "\f604"; } + +.fa-lungs-virus:before { + content: "\e067"; } + +.fa-lyft:before { + content: "\f3c3"; } + +.fa-magento:before { + content: "\f3c4"; } + +.fa-magic:before { + content: "\f0d0"; } + +.fa-magnet:before { + content: "\f076"; } + +.fa-mail-bulk:before { + content: "\f674"; } + +.fa-mailchimp:before { + content: "\f59e"; } + +.fa-male:before { + content: "\f183"; } + +.fa-mandalorian:before { + content: "\f50f"; } + +.fa-map:before { + content: "\f279"; } + +.fa-map-marked:before { + content: "\f59f"; } + +.fa-map-marked-alt:before { + content: "\f5a0"; } + +.fa-map-marker:before { + content: "\f041"; } + +.fa-map-marker-alt:before { + content: "\f3c5"; } + +.fa-map-pin:before { + content: "\f276"; } + +.fa-map-signs:before { + content: "\f277"; } + +.fa-markdown:before { + content: "\f60f"; } + +.fa-marker:before { + content: "\f5a1"; } + +.fa-mars:before { + content: "\f222"; } + +.fa-mars-double:before { + content: "\f227"; } + +.fa-mars-stroke:before { + content: "\f229"; } + +.fa-mars-stroke-h:before { + content: "\f22b"; } + +.fa-mars-stroke-v:before { + content: "\f22a"; } + +.fa-mask:before { + content: "\f6fa"; } + +.fa-mastodon:before { + content: "\f4f6"; } + +.fa-maxcdn:before { + content: "\f136"; } + +.fa-mdb:before { + content: "\f8ca"; } + +.fa-medal:before { + content: "\f5a2"; } + +.fa-medapps:before { + content: "\f3c6"; } + +.fa-medium:before { + content: "\f23a"; } + +.fa-medium-m:before { + content: "\f3c7"; } + +.fa-medkit:before { + content: "\f0fa"; } + +.fa-medrt:before { + content: "\f3c8"; } + +.fa-meetup:before { + content: "\f2e0"; } + +.fa-megaport:before { + content: "\f5a3"; } + +.fa-meh:before { + content: "\f11a"; } + +.fa-meh-blank:before { + content: "\f5a4"; } + +.fa-meh-rolling-eyes:before { + content: "\f5a5"; } + +.fa-memory:before { + content: "\f538"; } + +.fa-mendeley:before { + content: "\f7b3"; } + +.fa-menorah:before { + content: "\f676"; } + +.fa-mercury:before { + content: "\f223"; } + +.fa-meteor:before { + content: "\f753"; } + +.fa-microblog:before { + content: "\e01a"; } + +.fa-microchip:before { + content: "\f2db"; } + +.fa-microphone:before { + content: "\f130"; } + +.fa-microphone-alt:before { + content: "\f3c9"; } + +.fa-microphone-alt-slash:before { + content: "\f539"; } + +.fa-microphone-slash:before { + content: "\f131"; } + +.fa-microscope:before { + content: "\f610"; } + +.fa-microsoft:before { + content: "\f3ca"; } + +.fa-minus:before { + content: "\f068"; } + +.fa-minus-circle:before { + content: "\f056"; } + +.fa-minus-square:before { + content: "\f146"; } + +.fa-mitten:before { + content: "\f7b5"; } + +.fa-mix:before { + content: "\f3cb"; } + +.fa-mixcloud:before { + content: "\f289"; } + +.fa-mixer:before { + content: "\e056"; } + +.fa-mizuni:before { + content: "\f3cc"; } + +.fa-mobile:before { + content: "\f10b"; } + +.fa-mobile-alt:before { + content: "\f3cd"; } + +.fa-modx:before { + content: "\f285"; } + +.fa-monero:before { + content: "\f3d0"; } + +.fa-money-bill:before { + content: "\f0d6"; } + +.fa-money-bill-alt:before { + content: "\f3d1"; } + +.fa-money-bill-wave:before { + content: "\f53a"; } + +.fa-money-bill-wave-alt:before { + content: "\f53b"; } + +.fa-money-check:before { + content: "\f53c"; } + +.fa-money-check-alt:before { + content: "\f53d"; } + +.fa-monument:before { + content: "\f5a6"; } + +.fa-moon:before { + content: "\f186"; } + +.fa-mortar-pestle:before { + content: "\f5a7"; } + +.fa-mosque:before { + content: "\f678"; } + +.fa-motorcycle:before { + content: "\f21c"; } + +.fa-mountain:before { + content: "\f6fc"; } + +.fa-mouse:before { + content: "\f8cc"; } + +.fa-mouse-pointer:before { + content: "\f245"; } + +.fa-mug-hot:before { + content: "\f7b6"; } + +.fa-music:before { + content: "\f001"; } + +.fa-napster:before { + content: "\f3d2"; } + +.fa-neos:before { + content: "\f612"; } + +.fa-network-wired:before { + content: "\f6ff"; } + +.fa-neuter:before { + content: "\f22c"; } + +.fa-newspaper:before { + content: "\f1ea"; } + +.fa-nimblr:before { + content: "\f5a8"; } + +.fa-node:before { + content: "\f419"; } + +.fa-node-js:before { + content: "\f3d3"; } + +.fa-not-equal:before { + content: "\f53e"; } + +.fa-notes-medical:before { + content: "\f481"; } + +.fa-npm:before { + content: "\f3d4"; } + +.fa-ns8:before { + content: "\f3d5"; } + +.fa-nutritionix:before { + content: "\f3d6"; } + +.fa-object-group:before { + content: "\f247"; } + +.fa-object-ungroup:before { + content: "\f248"; } + +.fa-octopus-deploy:before { + content: "\e082"; } + +.fa-odnoklassniki:before { + content: "\f263"; } + +.fa-odnoklassniki-square:before { + content: "\f264"; } + +.fa-oil-can:before { + content: "\f613"; } + +.fa-old-republic:before { + content: "\f510"; } + +.fa-om:before { + content: "\f679"; } + +.fa-opencart:before { + content: "\f23d"; } + +.fa-openid:before { + content: "\f19b"; } + +.fa-opera:before { + content: "\f26a"; } + +.fa-optin-monster:before { + content: "\f23c"; } + +.fa-orcid:before { + content: "\f8d2"; } + +.fa-osi:before { + content: "\f41a"; } + +.fa-otter:before { + content: "\f700"; } + +.fa-outdent:before { + content: "\f03b"; } + +.fa-page4:before { + content: "\f3d7"; } + +.fa-pagelines:before { + content: "\f18c"; } + +.fa-pager:before { + content: "\f815"; } + +.fa-paint-brush:before { + content: "\f1fc"; } + +.fa-paint-roller:before { + content: "\f5aa"; } + +.fa-palette:before { + content: "\f53f"; } + +.fa-palfed:before { + content: "\f3d8"; } + +.fa-pallet:before { + content: "\f482"; } + +.fa-paper-plane:before { + content: "\f1d8"; } + +.fa-paperclip:before { + content: "\f0c6"; } + +.fa-parachute-box:before { + content: "\f4cd"; } + +.fa-paragraph:before { + content: "\f1dd"; } + +.fa-parking:before { + content: "\f540"; } + +.fa-passport:before { + content: "\f5ab"; } + +.fa-pastafarianism:before { + content: "\f67b"; } + +.fa-paste:before { + content: "\f0ea"; } + +.fa-patreon:before { + content: "\f3d9"; } + +.fa-pause:before { + content: "\f04c"; } + +.fa-pause-circle:before { + content: "\f28b"; } + +.fa-paw:before { + content: "\f1b0"; } + +.fa-paypal:before { + content: "\f1ed"; } + +.fa-peace:before { + content: "\f67c"; } + +.fa-pen:before { + content: "\f304"; } + +.fa-pen-alt:before { + content: "\f305"; } + +.fa-pen-fancy:before { + content: "\f5ac"; } + +.fa-pen-nib:before { + content: "\f5ad"; } + +.fa-pen-square:before { + content: "\f14b"; } + +.fa-pencil-alt:before { + content: "\f303"; } + +.fa-pencil-ruler:before { + content: "\f5ae"; } + +.fa-penny-arcade:before { + content: "\f704"; } + +.fa-people-arrows:before { + content: "\e068"; } + +.fa-people-carry:before { + content: "\f4ce"; } + +.fa-pepper-hot:before { + content: "\f816"; } + +.fa-perbyte:before { + content: "\e083"; } + +.fa-percent:before { + content: "\f295"; } + +.fa-percentage:before { + content: "\f541"; } + +.fa-periscope:before { + content: "\f3da"; } + +.fa-person-booth:before { + content: "\f756"; } + +.fa-phabricator:before { + content: "\f3db"; } + +.fa-phoenix-framework:before { + content: "\f3dc"; } + +.fa-phoenix-squadron:before { + content: "\f511"; } + +.fa-phone:before { + content: "\f095"; } + +.fa-phone-alt:before { + content: "\f879"; } + +.fa-phone-slash:before { + content: "\f3dd"; } + +.fa-phone-square:before { + content: "\f098"; } + +.fa-phone-square-alt:before { + content: "\f87b"; } + +.fa-phone-volume:before { + content: "\f2a0"; } + +.fa-photo-video:before { + content: "\f87c"; } + +.fa-php:before { + content: "\f457"; } + +.fa-pied-piper:before { + content: "\f2ae"; } + +.fa-pied-piper-alt:before { + content: "\f1a8"; } + +.fa-pied-piper-hat:before { + content: "\f4e5"; } + +.fa-pied-piper-pp:before { + content: "\f1a7"; } + +.fa-pied-piper-square:before { + content: "\e01e"; } + +.fa-piggy-bank:before { + content: "\f4d3"; } + +.fa-pills:before { + content: "\f484"; } + +.fa-pinterest:before { + content: "\f0d2"; } + +.fa-pinterest-p:before { + content: "\f231"; } + +.fa-pinterest-square:before { + content: "\f0d3"; } + +.fa-pizza-slice:before { + content: "\f818"; } + +.fa-place-of-worship:before { + content: "\f67f"; } + +.fa-plane:before { + content: "\f072"; } + +.fa-plane-arrival:before { + content: "\f5af"; } + +.fa-plane-departure:before { + content: "\f5b0"; } + +.fa-plane-slash:before { + content: "\e069"; } + +.fa-play:before { + content: "\f04b"; } + +.fa-play-circle:before { + content: "\f144"; } + +.fa-playstation:before { + content: "\f3df"; } + +.fa-plug:before { + content: "\f1e6"; } + +.fa-plus:before { + content: "\f067"; } + +.fa-plus-circle:before { + content: "\f055"; } + +.fa-plus-square:before { + content: "\f0fe"; } + +.fa-podcast:before { + content: "\f2ce"; } + +.fa-poll:before { + content: "\f681"; } + +.fa-poll-h:before { + content: "\f682"; } + +.fa-poo:before { + content: "\f2fe"; } + +.fa-poo-storm:before { + content: "\f75a"; } + +.fa-poop:before { + content: "\f619"; } + +.fa-portrait:before { + content: "\f3e0"; } + +.fa-pound-sign:before { + content: "\f154"; } + +.fa-power-off:before { + content: "\f011"; } + +.fa-pray:before { + content: "\f683"; } + +.fa-praying-hands:before { + content: "\f684"; } + +.fa-prescription:before { + content: "\f5b1"; } + +.fa-prescription-bottle:before { + content: "\f485"; } + +.fa-prescription-bottle-alt:before { + content: "\f486"; } + +.fa-print:before { + content: "\f02f"; } + +.fa-procedures:before { + content: "\f487"; } + +.fa-product-hunt:before { + content: "\f288"; } + +.fa-project-diagram:before { + content: "\f542"; } + +.fa-pump-medical:before { + content: "\e06a"; } + +.fa-pump-soap:before { + content: "\e06b"; } + +.fa-pushed:before { + content: "\f3e1"; } + +.fa-puzzle-piece:before { + content: "\f12e"; } + +.fa-python:before { + content: "\f3e2"; } + +.fa-qq:before { + content: "\f1d6"; } + +.fa-qrcode:before { + content: "\f029"; } + +.fa-question:before { + content: "\f128"; } + +.fa-question-circle:before { + content: "\f059"; } + +.fa-quidditch:before { + content: "\f458"; } + +.fa-quinscape:before { + content: "\f459"; } + +.fa-quora:before { + content: "\f2c4"; } + +.fa-quote-left:before { + content: "\f10d"; } + +.fa-quote-right:before { + content: "\f10e"; } + +.fa-quran:before { + content: "\f687"; } + +.fa-r-project:before { + content: "\f4f7"; } + +.fa-radiation:before { + content: "\f7b9"; } + +.fa-radiation-alt:before { + content: "\f7ba"; } + +.fa-rainbow:before { + content: "\f75b"; } + +.fa-random:before { + content: "\f074"; } + +.fa-raspberry-pi:before { + content: "\f7bb"; } + +.fa-ravelry:before { + content: "\f2d9"; } + +.fa-react:before { + content: "\f41b"; } + +.fa-reacteurope:before { + content: "\f75d"; } + +.fa-readme:before { + content: "\f4d5"; } + +.fa-rebel:before { + content: "\f1d0"; } + +.fa-receipt:before { + content: "\f543"; } + +.fa-record-vinyl:before { + content: "\f8d9"; } + +.fa-recycle:before { + content: "\f1b8"; } + +.fa-red-river:before { + content: "\f3e3"; } + +.fa-reddit:before { + content: "\f1a1"; } + +.fa-reddit-alien:before { + content: "\f281"; } + +.fa-reddit-square:before { + content: "\f1a2"; } + +.fa-redhat:before { + content: "\f7bc"; } + +.fa-redo:before { + content: "\f01e"; } + +.fa-redo-alt:before { + content: "\f2f9"; } + +.fa-registered:before { + content: "\f25d"; } + +.fa-remove-format:before { + content: "\f87d"; } + +.fa-renren:before { + content: "\f18b"; } + +.fa-reply:before { + content: "\f3e5"; } + +.fa-reply-all:before { + content: "\f122"; } + +.fa-replyd:before { + content: "\f3e6"; } + +.fa-republican:before { + content: "\f75e"; } + +.fa-researchgate:before { + content: "\f4f8"; } + +.fa-resolving:before { + content: "\f3e7"; } + +.fa-restroom:before { + content: "\f7bd"; } + +.fa-retweet:before { + content: "\f079"; } + +.fa-rev:before { + content: "\f5b2"; } + +.fa-ribbon:before { + content: "\f4d6"; } + +.fa-ring:before { + content: "\f70b"; } + +.fa-road:before { + content: "\f018"; } + +.fa-robot:before { + content: "\f544"; } + +.fa-rocket:before { + content: "\f135"; } + +.fa-rocketchat:before { + content: "\f3e8"; } + +.fa-rockrms:before { + content: "\f3e9"; } + +.fa-route:before { + content: "\f4d7"; } + +.fa-rss:before { + content: "\f09e"; } + +.fa-rss-square:before { + content: "\f143"; } + +.fa-ruble-sign:before { + content: "\f158"; } + +.fa-ruler:before { + content: "\f545"; } + +.fa-ruler-combined:before { + content: "\f546"; } + +.fa-ruler-horizontal:before { + content: "\f547"; } + +.fa-ruler-vertical:before { + content: "\f548"; } + +.fa-running:before { + content: "\f70c"; } + +.fa-rupee-sign:before { + content: "\f156"; } + +.fa-rust:before { + content: "\e07a"; } + +.fa-sad-cry:before { + content: "\f5b3"; } + +.fa-sad-tear:before { + content: "\f5b4"; } + +.fa-safari:before { + content: "\f267"; } + +.fa-salesforce:before { + content: "\f83b"; } + +.fa-sass:before { + content: "\f41e"; } + +.fa-satellite:before { + content: "\f7bf"; } + +.fa-satellite-dish:before { + content: "\f7c0"; } + +.fa-save:before { + content: "\f0c7"; } + +.fa-schlix:before { + content: "\f3ea"; } + +.fa-school:before { + content: "\f549"; } + +.fa-screwdriver:before { + content: "\f54a"; } + +.fa-scribd:before { + content: "\f28a"; } + +.fa-scroll:before { + content: "\f70e"; } + +.fa-sd-card:before { + content: "\f7c2"; } + +.fa-search:before { + content: "\f002"; } + +.fa-search-dollar:before { + content: "\f688"; } + +.fa-search-location:before { + content: "\f689"; } + +.fa-search-minus:before { + content: "\f010"; } + +.fa-search-plus:before { + content: "\f00e"; } + +.fa-searchengin:before { + content: "\f3eb"; } + +.fa-seedling:before { + content: "\f4d8"; } + +.fa-sellcast:before { + content: "\f2da"; } + +.fa-sellsy:before { + content: "\f213"; } + +.fa-server:before { + content: "\f233"; } + +.fa-servicestack:before { + content: "\f3ec"; } + +.fa-shapes:before { + content: "\f61f"; } + +.fa-share:before { + content: "\f064"; } + +.fa-share-alt:before { + content: "\f1e0"; } + +.fa-share-alt-square:before { + content: "\f1e1"; } + +.fa-share-square:before { + content: "\f14d"; } + +.fa-shekel-sign:before { + content: "\f20b"; } + +.fa-shield-alt:before { + content: "\f3ed"; } + +.fa-shield-virus:before { + content: "\e06c"; } + +.fa-ship:before { + content: "\f21a"; } + +.fa-shipping-fast:before { + content: "\f48b"; } + +.fa-shirtsinbulk:before { + content: "\f214"; } + +.fa-shoe-prints:before { + content: "\f54b"; } + +.fa-shopify:before { + content: "\e057"; } + +.fa-shopping-bag:before { + content: "\f290"; } + +.fa-shopping-basket:before { + content: "\f291"; } + +.fa-shopping-cart:before { + content: "\f07a"; } + +.fa-shopware:before { + content: "\f5b5"; } + +.fa-shower:before { + content: "\f2cc"; } + +.fa-shuttle-van:before { + content: "\f5b6"; } + +.fa-sign:before { + content: "\f4d9"; } + +.fa-sign-in-alt:before { + content: "\f2f6"; } + +.fa-sign-language:before { + content: "\f2a7"; } + +.fa-sign-out-alt:before { + content: "\f2f5"; } + +.fa-signal:before { + content: "\f012"; } + +.fa-signature:before { + content: "\f5b7"; } + +.fa-sim-card:before { + content: "\f7c4"; } + +.fa-simplybuilt:before { + content: "\f215"; } + +.fa-sink:before { + content: "\e06d"; } + +.fa-sistrix:before { + content: "\f3ee"; } + +.fa-sitemap:before { + content: "\f0e8"; } + +.fa-sith:before { + content: "\f512"; } + +.fa-skating:before { + content: "\f7c5"; } + +.fa-sketch:before { + content: "\f7c6"; } + +.fa-skiing:before { + content: "\f7c9"; } + +.fa-skiing-nordic:before { + content: "\f7ca"; } + +.fa-skull:before { + content: "\f54c"; } + +.fa-skull-crossbones:before { + content: "\f714"; } + +.fa-skyatlas:before { + content: "\f216"; } + +.fa-skype:before { + content: "\f17e"; } + +.fa-slack:before { + content: "\f198"; } + +.fa-slack-hash:before { + content: "\f3ef"; } + +.fa-slash:before { + content: "\f715"; } + +.fa-sleigh:before { + content: "\f7cc"; } + +.fa-sliders-h:before { + content: "\f1de"; } + +.fa-slideshare:before { + content: "\f1e7"; } + +.fa-smile:before { + content: "\f118"; } + +.fa-smile-beam:before { + content: "\f5b8"; } + +.fa-smile-wink:before { + content: "\f4da"; } + +.fa-smog:before { + content: "\f75f"; } + +.fa-smoking:before { + content: "\f48d"; } + +.fa-smoking-ban:before { + content: "\f54d"; } + +.fa-sms:before { + content: "\f7cd"; } + +.fa-snapchat:before { + content: "\f2ab"; } + +.fa-snapchat-ghost:before { + content: "\f2ac"; } + +.fa-snapchat-square:before { + content: "\f2ad"; } + +.fa-snowboarding:before { + content: "\f7ce"; } + +.fa-snowflake:before { + content: "\f2dc"; } + +.fa-snowman:before { + content: "\f7d0"; } + +.fa-snowplow:before { + content: "\f7d2"; } + +.fa-soap:before { + content: "\e06e"; } + +.fa-socks:before { + content: "\f696"; } + +.fa-solar-panel:before { + content: "\f5ba"; } + +.fa-sort:before { + content: "\f0dc"; } + +.fa-sort-alpha-down:before { + content: "\f15d"; } + +.fa-sort-alpha-down-alt:before { + content: "\f881"; } + +.fa-sort-alpha-up:before { + content: "\f15e"; } + +.fa-sort-alpha-up-alt:before { + content: "\f882"; } + +.fa-sort-amount-down:before { + content: "\f160"; } + +.fa-sort-amount-down-alt:before { + content: "\f884"; } + +.fa-sort-amount-up:before { + content: "\f161"; } + +.fa-sort-amount-up-alt:before { + content: "\f885"; } + +.fa-sort-down:before { + content: "\f0dd"; } + +.fa-sort-numeric-down:before { + content: "\f162"; } + +.fa-sort-numeric-down-alt:before { + content: "\f886"; } + +.fa-sort-numeric-up:before { + content: "\f163"; } + +.fa-sort-numeric-up-alt:before { + content: "\f887"; } + +.fa-sort-up:before { + content: "\f0de"; } + +.fa-soundcloud:before { + content: "\f1be"; } + +.fa-sourcetree:before { + content: "\f7d3"; } + +.fa-spa:before { + content: "\f5bb"; } + +.fa-space-shuttle:before { + content: "\f197"; } + +.fa-speakap:before { + content: "\f3f3"; } + +.fa-speaker-deck:before { + content: "\f83c"; } + +.fa-spell-check:before { + content: "\f891"; } + +.fa-spider:before { + content: "\f717"; } + +.fa-spinner:before { + content: "\f110"; } + +.fa-splotch:before { + content: "\f5bc"; } + +.fa-spotify:before { + content: "\f1bc"; } + +.fa-spray-can:before { + content: "\f5bd"; } + +.fa-square:before { + content: "\f0c8"; } + +.fa-square-full:before { + content: "\f45c"; } + +.fa-square-root-alt:before { + content: "\f698"; } + +.fa-squarespace:before { + content: "\f5be"; } + +.fa-stack-exchange:before { + content: "\f18d"; } + +.fa-stack-overflow:before { + content: "\f16c"; } + +.fa-stackpath:before { + content: "\f842"; } + +.fa-stamp:before { + content: "\f5bf"; } + +.fa-star:before { + content: "\f005"; } + +.fa-star-and-crescent:before { + content: "\f699"; } + +.fa-star-half:before { + content: "\f089"; } + +.fa-star-half-alt:before { + content: "\f5c0"; } + +.fa-star-of-david:before { + content: "\f69a"; } + +.fa-star-of-life:before { + content: "\f621"; } + +.fa-staylinked:before { + content: "\f3f5"; } + +.fa-steam:before { + content: "\f1b6"; } + +.fa-steam-square:before { + content: "\f1b7"; } + +.fa-steam-symbol:before { + content: "\f3f6"; } + +.fa-step-backward:before { + content: "\f048"; } + +.fa-step-forward:before { + content: "\f051"; } + +.fa-stethoscope:before { + content: "\f0f1"; } + +.fa-sticker-mule:before { + content: "\f3f7"; } + +.fa-sticky-note:before { + content: "\f249"; } + +.fa-stop:before { + content: "\f04d"; } + +.fa-stop-circle:before { + content: "\f28d"; } + +.fa-stopwatch:before { + content: "\f2f2"; } + +.fa-stopwatch-20:before { + content: "\e06f"; } + +.fa-store:before { + content: "\f54e"; } + +.fa-store-alt:before { + content: "\f54f"; } + +.fa-store-alt-slash:before { + content: "\e070"; } + +.fa-store-slash:before { + content: "\e071"; } + +.fa-strava:before { + content: "\f428"; } + +.fa-stream:before { + content: "\f550"; } + +.fa-street-view:before { + content: "\f21d"; } + +.fa-strikethrough:before { + content: "\f0cc"; } + +.fa-stripe:before { + content: "\f429"; } + +.fa-stripe-s:before { + content: "\f42a"; } + +.fa-stroopwafel:before { + content: "\f551"; } + +.fa-studiovinari:before { + content: "\f3f8"; } + +.fa-stumbleupon:before { + content: "\f1a4"; } + +.fa-stumbleupon-circle:before { + content: "\f1a3"; } + +.fa-subscript:before { + content: "\f12c"; } + +.fa-subway:before { + content: "\f239"; } + +.fa-suitcase:before { + content: "\f0f2"; } + +.fa-suitcase-rolling:before { + content: "\f5c1"; } + +.fa-sun:before { + content: "\f185"; } + +.fa-superpowers:before { + content: "\f2dd"; } + +.fa-superscript:before { + content: "\f12b"; } + +.fa-supple:before { + content: "\f3f9"; } + +.fa-surprise:before { + content: "\f5c2"; } + +.fa-suse:before { + content: "\f7d6"; } + +.fa-swatchbook:before { + content: "\f5c3"; } + +.fa-swift:before { + content: "\f8e1"; } + +.fa-swimmer:before { + content: "\f5c4"; } + +.fa-swimming-pool:before { + content: "\f5c5"; } + +.fa-symfony:before { + content: "\f83d"; } + +.fa-synagogue:before { + content: "\f69b"; } + +.fa-sync:before { + content: "\f021"; } + +.fa-sync-alt:before { + content: "\f2f1"; } + +.fa-syringe:before { + content: "\f48e"; } + +.fa-table:before { + content: "\f0ce"; } + +.fa-table-tennis:before { + content: "\f45d"; } + +.fa-tablet:before { + content: "\f10a"; } + +.fa-tablet-alt:before { + content: "\f3fa"; } + +.fa-tablets:before { + content: "\f490"; } + +.fa-tachometer-alt:before { + content: "\f3fd"; } + +.fa-tag:before { + content: "\f02b"; } + +.fa-tags:before { + content: "\f02c"; } + +.fa-tape:before { + content: "\f4db"; } + +.fa-tasks:before { + content: "\f0ae"; } + +.fa-taxi:before { + content: "\f1ba"; } + +.fa-teamspeak:before { + content: "\f4f9"; } + +.fa-teeth:before { + content: "\f62e"; } + +.fa-teeth-open:before { + content: "\f62f"; } + +.fa-telegram:before { + content: "\f2c6"; } + +.fa-telegram-plane:before { + content: "\f3fe"; } + +.fa-temperature-high:before { + content: "\f769"; } + +.fa-temperature-low:before { + content: "\f76b"; } + +.fa-tencent-weibo:before { + content: "\f1d5"; } + +.fa-tenge:before { + content: "\f7d7"; } + +.fa-terminal:before { + content: "\f120"; } + +.fa-text-height:before { + content: "\f034"; } + +.fa-text-width:before { + content: "\f035"; } + +.fa-th:before { + content: "\f00a"; } + +.fa-th-large:before { + content: "\f009"; } + +.fa-th-list:before { + content: "\f00b"; } + +.fa-the-red-yeti:before { + content: "\f69d"; } + +.fa-theater-masks:before { + content: "\f630"; } + +.fa-themeco:before { + content: "\f5c6"; } + +.fa-themeisle:before { + content: "\f2b2"; } + +.fa-thermometer:before { + content: "\f491"; } + +.fa-thermometer-empty:before { + content: "\f2cb"; } + +.fa-thermometer-full:before { + content: "\f2c7"; } + +.fa-thermometer-half:before { + content: "\f2c9"; } + +.fa-thermometer-quarter:before { + content: "\f2ca"; } + +.fa-thermometer-three-quarters:before { + content: "\f2c8"; } + +.fa-think-peaks:before { + content: "\f731"; } + +.fa-thumbs-down:before { + content: "\f165"; } + +.fa-thumbs-up:before { + content: "\f164"; } + +.fa-thumbtack:before { + content: "\f08d"; } + +.fa-ticket-alt:before { + content: "\f3ff"; } + +.fa-tiktok:before { + content: "\e07b"; } + +.fa-times:before { + content: "\f00d"; } + +.fa-times-circle:before { + content: "\f057"; } + +.fa-tint:before { + content: "\f043"; } + +.fa-tint-slash:before { + content: "\f5c7"; } + +.fa-tired:before { + content: "\f5c8"; } + +.fa-toggle-off:before { + content: "\f204"; } + +.fa-toggle-on:before { + content: "\f205"; } + +.fa-toilet:before { + content: "\f7d8"; } + +.fa-toilet-paper:before { + content: "\f71e"; } + +.fa-toilet-paper-slash:before { + content: "\e072"; } + +.fa-toolbox:before { + content: "\f552"; } + +.fa-tools:before { + content: "\f7d9"; } + +.fa-tooth:before { + content: "\f5c9"; } + +.fa-torah:before { + content: "\f6a0"; } + +.fa-torii-gate:before { + content: "\f6a1"; } + +.fa-tractor:before { + content: "\f722"; } + +.fa-trade-federation:before { + content: "\f513"; } + +.fa-trademark:before { + content: "\f25c"; } + +.fa-traffic-light:before { + content: "\f637"; } + +.fa-trailer:before { + content: "\e041"; } + +.fa-train:before { + content: "\f238"; } + +.fa-tram:before { + content: "\f7da"; } + +.fa-transgender:before { + content: "\f224"; } + +.fa-transgender-alt:before { + content: "\f225"; } + +.fa-trash:before { + content: "\f1f8"; } + +.fa-trash-alt:before { + content: "\f2ed"; } + +.fa-trash-restore:before { + content: "\f829"; } + +.fa-trash-restore-alt:before { + content: "\f82a"; } + +.fa-tree:before { + content: "\f1bb"; } + +.fa-trello:before { + content: "\f181"; } + +.fa-trophy:before { + content: "\f091"; } + +.fa-truck:before { + content: "\f0d1"; } + +.fa-truck-loading:before { + content: "\f4de"; } + +.fa-truck-monster:before { + content: "\f63b"; } + +.fa-truck-moving:before { + content: "\f4df"; } + +.fa-truck-pickup:before { + content: "\f63c"; } + +.fa-tshirt:before { + content: "\f553"; } + +.fa-tty:before { + content: "\f1e4"; } + +.fa-tumblr:before { + content: "\f173"; } + +.fa-tumblr-square:before { + content: "\f174"; } + +.fa-tv:before { + content: "\f26c"; } + +.fa-twitch:before { + content: "\f1e8"; } + +.fa-twitter:before { + content: "\f099"; } + +.fa-twitter-square:before { + content: "\f081"; } + +.fa-typo3:before { + content: "\f42b"; } + +.fa-uber:before { + content: "\f402"; } + +.fa-ubuntu:before { + content: "\f7df"; } + +.fa-uikit:before { + content: "\f403"; } + +.fa-umbraco:before { + content: "\f8e8"; } + +.fa-umbrella:before { + content: "\f0e9"; } + +.fa-umbrella-beach:before { + content: "\f5ca"; } + +.fa-uncharted:before { + content: "\e084"; } + +.fa-underline:before { + content: "\f0cd"; } + +.fa-undo:before { + content: "\f0e2"; } + +.fa-undo-alt:before { + content: "\f2ea"; } + +.fa-uniregistry:before { + content: "\f404"; } + +.fa-unity:before { + content: "\e049"; } + +.fa-universal-access:before { + content: "\f29a"; } + +.fa-university:before { + content: "\f19c"; } + +.fa-unlink:before { + content: "\f127"; } + +.fa-unlock:before { + content: "\f09c"; } + +.fa-unlock-alt:before { + content: "\f13e"; } + +.fa-unsplash:before { + content: "\e07c"; } + +.fa-untappd:before { + content: "\f405"; } + +.fa-upload:before { + content: "\f093"; } + +.fa-ups:before { + content: "\f7e0"; } + +.fa-usb:before { + content: "\f287"; } + +.fa-user:before { + content: "\f007"; } + +.fa-user-alt:before { + content: "\f406"; } + +.fa-user-alt-slash:before { + content: "\f4fa"; } + +.fa-user-astronaut:before { + content: "\f4fb"; } + +.fa-user-check:before { + content: "\f4fc"; } + +.fa-user-circle:before { + content: "\f2bd"; } + +.fa-user-clock:before { + content: "\f4fd"; } + +.fa-user-cog:before { + content: "\f4fe"; } + +.fa-user-edit:before { + content: "\f4ff"; } + +.fa-user-friends:before { + content: "\f500"; } + +.fa-user-graduate:before { + content: "\f501"; } + +.fa-user-injured:before { + content: "\f728"; } + +.fa-user-lock:before { + content: "\f502"; } + +.fa-user-md:before { + content: "\f0f0"; } + +.fa-user-minus:before { + content: "\f503"; } + +.fa-user-ninja:before { + content: "\f504"; } + +.fa-user-nurse:before { + content: "\f82f"; } + +.fa-user-plus:before { + content: "\f234"; } + +.fa-user-secret:before { + content: "\f21b"; } + +.fa-user-shield:before { + content: "\f505"; } + +.fa-user-slash:before { + content: "\f506"; } + +.fa-user-tag:before { + content: "\f507"; } + +.fa-user-tie:before { + content: "\f508"; } + +.fa-user-times:before { + content: "\f235"; } + +.fa-users:before { + content: "\f0c0"; } + +.fa-users-cog:before { + content: "\f509"; } + +.fa-users-slash:before { + content: "\e073"; } + +.fa-usps:before { + content: "\f7e1"; } + +.fa-ussunnah:before { + content: "\f407"; } + +.fa-utensil-spoon:before { + content: "\f2e5"; } + +.fa-utensils:before { + content: "\f2e7"; } + +.fa-vaadin:before { + content: "\f408"; } + +.fa-vector-square:before { + content: "\f5cb"; } + +.fa-venus:before { + content: "\f221"; } + +.fa-venus-double:before { + content: "\f226"; } + +.fa-venus-mars:before { + content: "\f228"; } + +.fa-vest:before { + content: "\e085"; } + +.fa-vest-patches:before { + content: "\e086"; } + +.fa-viacoin:before { + content: "\f237"; } + +.fa-viadeo:before { + content: "\f2a9"; } + +.fa-viadeo-square:before { + content: "\f2aa"; } + +.fa-vial:before { + content: "\f492"; } + +.fa-vials:before { + content: "\f493"; } + +.fa-viber:before { + content: "\f409"; } + +.fa-video:before { + content: "\f03d"; } + +.fa-video-slash:before { + content: "\f4e2"; } + +.fa-vihara:before { + content: "\f6a7"; } + +.fa-vimeo:before { + content: "\f40a"; } + +.fa-vimeo-square:before { + content: "\f194"; } + +.fa-vimeo-v:before { + content: "\f27d"; } + +.fa-vine:before { + content: "\f1ca"; } + +.fa-virus:before { + content: "\e074"; } + +.fa-virus-slash:before { + content: "\e075"; } + +.fa-viruses:before { + content: "\e076"; } + +.fa-vk:before { + content: "\f189"; } + +.fa-vnv:before { + content: "\f40b"; } + +.fa-voicemail:before { + content: "\f897"; } + +.fa-volleyball-ball:before { + content: "\f45f"; } + +.fa-volume-down:before { + content: "\f027"; } + +.fa-volume-mute:before { + content: "\f6a9"; } + +.fa-volume-off:before { + content: "\f026"; } + +.fa-volume-up:before { + content: "\f028"; } + +.fa-vote-yea:before { + content: "\f772"; } + +.fa-vr-cardboard:before { + content: "\f729"; } + +.fa-vuejs:before { + content: "\f41f"; } + +.fa-walking:before { + content: "\f554"; } + +.fa-wallet:before { + content: "\f555"; } + +.fa-warehouse:before { + content: "\f494"; } + +.fa-watchman-monitoring:before { + content: "\e087"; } + +.fa-water:before { + content: "\f773"; } + +.fa-wave-square:before { + content: "\f83e"; } + +.fa-waze:before { + content: "\f83f"; } + +.fa-weebly:before { + content: "\f5cc"; } + +.fa-weibo:before { + content: "\f18a"; } + +.fa-weight:before { + content: "\f496"; } + +.fa-weight-hanging:before { + content: "\f5cd"; } + +.fa-weixin:before { + content: "\f1d7"; } + +.fa-whatsapp:before { + content: "\f232"; } + +.fa-whatsapp-square:before { + content: "\f40c"; } + +.fa-wheelchair:before { + content: "\f193"; } + +.fa-whmcs:before { + content: "\f40d"; } + +.fa-wifi:before { + content: "\f1eb"; } + +.fa-wikipedia-w:before { + content: "\f266"; } + +.fa-wind:before { + content: "\f72e"; } + +.fa-window-close:before { + content: "\f410"; } + +.fa-window-maximize:before { + content: "\f2d0"; } + +.fa-window-minimize:before { + content: "\f2d1"; } + +.fa-window-restore:before { + content: "\f2d2"; } + +.fa-windows:before { + content: "\f17a"; } + +.fa-wine-bottle:before { + content: "\f72f"; } + +.fa-wine-glass:before { + content: "\f4e3"; } + +.fa-wine-glass-alt:before { + content: "\f5ce"; } + +.fa-wix:before { + content: "\f5cf"; } + +.fa-wizards-of-the-coast:before { + content: "\f730"; } + +.fa-wodu:before { + content: "\e088"; } + +.fa-wolf-pack-battalion:before { + content: "\f514"; } + +.fa-won-sign:before { + content: "\f159"; } + +.fa-wordpress:before { + content: "\f19a"; } + +.fa-wordpress-simple:before { + content: "\f411"; } + +.fa-wpbeginner:before { + content: "\f297"; } + +.fa-wpexplorer:before { + content: "\f2de"; } + +.fa-wpforms:before { + content: "\f298"; } + +.fa-wpressr:before { + content: "\f3e4"; } + +.fa-wrench:before { + content: "\f0ad"; } + +.fa-x-ray:before { + content: "\f497"; } + +.fa-xbox:before { + content: "\f412"; } + +.fa-xing:before { + content: "\f168"; } + +.fa-xing-square:before { + content: "\f169"; } + +.fa-y-combinator:before { + content: "\f23b"; } + +.fa-yahoo:before { + content: "\f19e"; } + +.fa-yammer:before { + content: "\f840"; } + +.fa-yandex:before { + content: "\f413"; } + +.fa-yandex-international:before { + content: "\f414"; } + +.fa-yarn:before { + content: "\f7e3"; } + +.fa-yelp:before { + content: "\f1e9"; } + +.fa-yen-sign:before { + content: "\f157"; } + +.fa-yin-yang:before { + content: "\f6ad"; } + +.fa-yoast:before { + content: "\f2b1"; } + +.fa-youtube:before { + content: "\f167"; } + +.fa-youtube-square:before { + content: "\f431"; } + +.fa-zhihu:before { + content: "\f63f"; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } diff --git a/assets/webfonts/fa-brands-400.eot b/assets/webfonts/fa-brands-400.eot new file mode 100644 index 0000000..cba6c6c Binary files /dev/null and b/assets/webfonts/fa-brands-400.eot differ diff --git a/assets/webfonts/fa-brands-400.svg b/assets/webfonts/fa-brands-400.svg new file mode 100644 index 0000000..b9881a4 --- /dev/null +++ b/assets/webfonts/fa-brands-400.svg @@ -0,0 +1,3717 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/webfonts/fa-brands-400.ttf b/assets/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000..8d75ded Binary files /dev/null and b/assets/webfonts/fa-brands-400.ttf differ diff --git a/assets/webfonts/fa-brands-400.woff b/assets/webfonts/fa-brands-400.woff new file mode 100644 index 0000000..3375bef Binary files /dev/null and b/assets/webfonts/fa-brands-400.woff differ diff --git a/assets/webfonts/fa-brands-400.woff2 b/assets/webfonts/fa-brands-400.woff2 new file mode 100644 index 0000000..402f81c Binary files /dev/null and b/assets/webfonts/fa-brands-400.woff2 differ diff --git a/assets/webfonts/fa-regular-400.eot b/assets/webfonts/fa-regular-400.eot new file mode 100644 index 0000000..a4e5989 Binary files /dev/null and b/assets/webfonts/fa-regular-400.eot differ diff --git a/assets/webfonts/fa-regular-400.svg b/assets/webfonts/fa-regular-400.svg new file mode 100644 index 0000000..463af27 --- /dev/null +++ b/assets/webfonts/fa-regular-400.svg @@ -0,0 +1,801 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/webfonts/fa-regular-400.ttf b/assets/webfonts/fa-regular-400.ttf new file mode 100644 index 0000000..7157aaf Binary files /dev/null and b/assets/webfonts/fa-regular-400.ttf differ diff --git a/assets/webfonts/fa-regular-400.woff b/assets/webfonts/fa-regular-400.woff new file mode 100644 index 0000000..ad077c6 Binary files /dev/null and b/assets/webfonts/fa-regular-400.woff differ diff --git a/assets/webfonts/fa-regular-400.woff2 b/assets/webfonts/fa-regular-400.woff2 new file mode 100644 index 0000000..5632894 Binary files /dev/null and b/assets/webfonts/fa-regular-400.woff2 differ diff --git a/assets/webfonts/fa-solid-900.eot b/assets/webfonts/fa-solid-900.eot new file mode 100644 index 0000000..e994171 Binary files /dev/null and b/assets/webfonts/fa-solid-900.eot differ diff --git a/assets/webfonts/fa-solid-900.svg b/assets/webfonts/fa-solid-900.svg new file mode 100644 index 0000000..00296e9 --- /dev/null +++ b/assets/webfonts/fa-solid-900.svg @@ -0,0 +1,5034 @@ + + + + +Created by FontForge 20201107 at Wed Aug 4 12:25:29 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/webfonts/fa-solid-900.ttf b/assets/webfonts/fa-solid-900.ttf new file mode 100644 index 0000000..25abf38 Binary files /dev/null and b/assets/webfonts/fa-solid-900.ttf differ diff --git a/assets/webfonts/fa-solid-900.woff b/assets/webfonts/fa-solid-900.woff new file mode 100644 index 0000000..23ee663 Binary files /dev/null and b/assets/webfonts/fa-solid-900.woff differ diff --git a/assets/webfonts/fa-solid-900.woff2 b/assets/webfonts/fa-solid-900.woff2 new file mode 100644 index 0000000..2217164 Binary files /dev/null and b/assets/webfonts/fa-solid-900.woff2 differ diff --git a/inc/craftnce-plugins.php b/inc/craftnce-plugins.php deleted file mode 100644 index af0676b..0000000 --- a/inc/craftnce-plugins.php +++ /dev/null @@ -1,40 +0,0 @@ - 'Better Font Awesome', // The plugin name. - 'slug' => 'better-font-awesome', // The plugin slug (typically the folder name). - 'required' => false, // If false, the plugin is only 'recommended' instead of required. - 'version' => '2.0.1', - 'force_activation' => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch. - 'force_deactivation' => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins. - ), - ); - - $config = array( - 'id' => 'craftnce', // Unique ID for hashing notices for multiple instances of TGMPA. - 'default_path' => '', // Default absolute path to bundled plugins. - 'menu' => 'tgmpa-install-plugins', // Menu slug. - 'has_notices' => true, // Show admin notices or not. - 'dismissable' => true, // If false, a user cannot dismiss the nag message. - 'dismiss_msg' => '', // If 'dismissable' is false, this message will be output at top of nag. - 'is_automatic' => false, // Automatically activate plugins after installation or not. - 'message' => '', // Message to output right before the plugins table. - ); - - tgmpa( $plugins, $config ); -} \ No newline at end of file diff --git a/lib/class-tgm-plugin-activation.php b/lib/class-tgm-plugin-activation.php deleted file mode 100644 index 9e6d4e4..0000000 --- a/lib/class-tgm-plugin-activation.php +++ /dev/null @@ -1,3760 +0,0 @@ -wp_version = $GLOBALS['wp_version']; - - // Announce that the class is ready, and pass the object (for advanced use). - do_action_ref_array( 'tgmpa_init', array( $this ) ); - - - - // When the rest of WP has loaded, kick-start the rest of the class. - add_action( 'init', array( $this, 'init' ) ); - } - - /** - * Magic method to (not) set protected properties from outside of this class. - * - * {@internal hackedihack... There is a serious bug in v2.3.2 - 2.3.6 where the `menu` property - * is being assigned rather than tested in a conditional, effectively rendering it useless. - * This 'hack' prevents this from happening.}} - * - * @see https://github.com/TGMPA/TGM-Plugin-Activation/blob/2.3.6/tgm-plugin-activation/class-tgm-plugin-activation.php#L1593 - * - * @since 2.5.2 - * - * @param string $name Name of an inaccessible property. - * @param mixed $value Value to assign to the property. - * @return void Silently fail to set the property when this is tried from outside of this class context. - * (Inside this class context, the __set() method if not used as there is direct access.) - */ - public function __set( $name, $value ) { - return; - } - - /** - * Magic method to get the value of a protected property outside of this class context. - * - * @since 2.5.2 - * - * @param string $name Name of an inaccessible property. - * @return mixed The property value. - */ - public function __get( $name ) { - return $this->{$name}; - } - - /** - * Initialise the interactions between this class and WordPress. - * - * Hooks in three new methods for the class: admin_menu, notices and styles. - * - * @since 2.0.0 - * - * @see TGM_Plugin_Activation::admin_menu() - * @see TGM_Plugin_Activation::notices() - * @see TGM_Plugin_Activation::styles() - */ - public function init() { - /** - * By default TGMPA only loads on the WP back-end and not in an Ajax call. Using this filter - * you can overrule that behaviour. - * - * @since 2.5.0 - * - * @param bool $load Whether or not TGMPA should load. - * Defaults to the return of `is_admin() && ! defined( 'DOING_AJAX' )`. - */ - if ( true !== apply_filters( 'tgmpa_load', ( is_admin() && ! defined( 'DOING_AJAX' ) ) ) ) { - return; - } - - // Load class strings. - $this->strings = array( - 'page_title' => __( 'Install Required Plugins', 'craftnce' ), - 'menu_title' => __( 'Install Plugins', 'craftnce' ), - /* translators: %s: plugin name. */ - 'installing' => __( 'Installing Plugin: %s', 'craftnce' ), - /* translators: %s: plugin name. */ - 'updating' => __( 'Updating Plugin: %s', 'craftnce' ), - 'oops' => __( 'Something went wrong with the plugin API.', 'craftnce' ), - 'notice_can_install_required' => _n_noop( - /* translators: 1: plugin name(s). */ - 'This theme requires the following plugin: %1$s.', - 'This theme requires the following plugins: %1$s.', - 'craftnce' - ), - 'notice_can_install_recommended' => _n_noop( - /* translators: 1: plugin name(s). */ - 'This theme recommends the following plugin: %1$s.', - 'This theme recommends the following plugins: %1$s.', - 'craftnce' - ), - 'notice_ask_to_update' => _n_noop( - /* translators: 1: plugin name(s). */ - 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', - 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.', - 'craftnce' - ), - 'notice_ask_to_update_maybe' => _n_noop( - /* translators: 1: plugin name(s). */ - 'There is an update available for: %1$s.', - 'There are updates available for the following plugins: %1$s.', - 'craftnce' - ), - 'notice_can_activate_required' => _n_noop( - /* translators: 1: plugin name(s). */ - 'The following required plugin is currently inactive: %1$s.', - 'The following required plugins are currently inactive: %1$s.', - 'craftnce' - ), - 'notice_can_activate_recommended' => _n_noop( - /* translators: 1: plugin name(s). */ - 'The following recommended plugin is currently inactive: %1$s.', - 'The following recommended plugins are currently inactive: %1$s.', - 'craftnce' - ), - 'install_link' => _n_noop( - 'Begin installing plugin', - 'Begin installing plugins', - 'craftnce' - ), - 'update_link' => _n_noop( - 'Begin updating plugin', - 'Begin updating plugins', - 'craftnce' - ), - 'activate_link' => _n_noop( - 'Begin activating plugin', - 'Begin activating plugins', - 'craftnce' - ), - 'return' => __( 'Return to Required Plugins Installer', 'craftnce' ), - 'dashboard' => __( 'Return to the Dashboard', 'craftnce' ), - 'plugin_activated' => __( 'Plugin activated successfully.', 'craftnce' ), - 'activated_successfully' => __( 'The following plugin was activated successfully:', 'craftnce' ), - /* translators: 1: plugin name. */ - 'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'craftnce' ), - /* translators: 1: plugin name. */ - 'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'craftnce' ), - /* translators: 1: dashboard link. */ - 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'craftnce' ), - 'dismiss' => __( 'Dismiss this notice', 'craftnce' ), - 'notice_cannot_install_activate' => __( 'There are one or more required or recommended plugins to install, update or activate.', 'craftnce' ), - 'contact_admin' => __( 'Please contact the administrator of this site for help.', 'craftnce' ), - ); - - do_action( 'tgmpa_register' ); - - /* After this point, the plugins should be registered and the configuration set. */ - - // Proceed only if we have plugins to handle. - if ( empty( $this->plugins ) || ! is_array( $this->plugins ) ) { - return; - } - - // Set up the menu and notices if we still have outstanding actions. - if ( true !== $this->is_tgmpa_complete() ) { - // Sort the plugins. - array_multisort( $this->sort_order, SORT_ASC, $this->plugins ); - - add_action( 'admin_menu', array( $this, 'admin_menu' ) ); - add_action( 'admin_head', array( $this, 'dismiss' ) ); - - // Prevent the normal links from showing underneath a single install/update page. - add_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) ); - add_filter( 'update_plugin_complete_actions', array( $this, 'actions' ) ); - - if ( $this->has_notices ) { - add_action( 'admin_notices', array( $this, 'notices' ) ); - add_action( 'admin_init', array( $this, 'admin_init' ), 1 ); - add_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) ); - } - } - - // If needed, filter plugin action links. - add_action( 'load-plugins.php', array( $this, 'add_plugin_action_link_filters' ), 1 ); - - // Make sure things get reset on switch theme. - add_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) ); - - if ( $this->has_notices ) { - add_action( 'switch_theme', array( $this, 'update_dismiss' ) ); - } - - // Setup the force activation hook. - if ( true === $this->has_forced_activation ) { - add_action( 'admin_init', array( $this, 'force_activation' ) ); - } - - // Setup the force deactivation hook. - if ( true === $this->has_forced_deactivation ) { - add_action( 'switch_theme', array( $this, 'force_deactivation' ) ); - } - } - - - - - - - - /** - * Hook in plugin action link filters for the WP native plugins page. - * - * - Prevent activation of plugins which don't meet the minimum version requirements. - * - Prevent deactivation of force-activated plugins. - * - Add update notice if update available. - * - * @since 2.5.0 - */ - public function add_plugin_action_link_filters() { - foreach ( $this->plugins as $slug => $plugin ) { - if ( false === $this->can_plugin_activate( $slug ) ) { - add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_activate' ), 20 ); - } - - if ( true === $plugin['force_activation'] ) { - add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_deactivate' ), 20 ); - } - - if ( false !== $this->does_plugin_require_update( $slug ) ) { - add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_update' ), 20 ); - } - } - } - - /** - * Remove the 'Activate' link on the WP native plugins page if the plugin does not meet the - * minimum version requirements. - * - * @since 2.5.0 - * - * @param array $actions Action links. - * @return array - */ - public function filter_plugin_action_links_activate( $actions ) { - unset( $actions['activate'] ); - - return $actions; - } - - /** - * Remove the 'Deactivate' link on the WP native plugins page if the plugin has been set to force activate. - * - * @since 2.5.0 - * - * @param array $actions Action links. - * @return array - */ - public function filter_plugin_action_links_deactivate( $actions ) { - unset( $actions['deactivate'] ); - - return $actions; - } - - /** - * Add a 'Requires update' link on the WP native plugins page if the plugin does not meet the - * minimum version requirements. - * - * @since 2.5.0 - * - * @param array $actions Action links. - * @return array - */ - public function filter_plugin_action_links_update( $actions ) { - $actions['update'] = sprintf( - '%3$s', - esc_url( $this->get_tgmpa_status_url( 'update' ) ), - esc_attr__( 'This plugin needs to be updated to be compatible with your theme.', 'craftnce' ), - esc_html__( 'Update Required', 'craftnce' ) - ); - - return $actions; - } - - /** - * Handles calls to show plugin information via links in the notices. - * - * We get the links in the admin notices to point to the TGMPA page, rather - * than the typical plugin-install.php file, so we can prepare everything - * beforehand. - * - * WP does not make it easy to show the plugin information in the thickbox - - * here we have to require a file that includes a function that does the - * main work of displaying it, enqueue some styles, set up some globals and - * finally call that function before exiting. - * - * Down right easy once you know how... - * - * Returns early if not the TGMPA page. - * - * @since 2.1.0 - * - * @global string $tab Used as iframe div class names, helps with styling - * @global string $body_id Used as the iframe body ID, helps with styling - * - * @return null Returns early if not the TGMPA page. - */ - public function admin_init() { - if ( ! $this->is_tgmpa_page() ) { - return; - } - - if ( isset( $_REQUEST['tab'] ) && 'plugin-information' === $_REQUEST['tab'] ) { - // Needed for install_plugin_information(). - require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; - - wp_enqueue_style( 'plugin-install' ); - - global $tab, $body_id; - $body_id = 'plugin-information'; - // @codingStandardsIgnoreStart - $tab = 'plugin-information'; - // @codingStandardsIgnoreEnd - - install_plugin_information(); - - exit; - } - } - - /** - * Enqueue thickbox scripts/styles for plugin info. - * - * Thickbox is not automatically included on all admin pages, so we must - * manually enqueue it for those pages. - * - * Thickbox is only loaded if the user has not dismissed the admin - * notice or if there are any plugins left to install and activate. - * - * @since 2.1.0 - */ - public function thickbox() { - if ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) { - add_thickbox(); - } - } - - /** - * Adds submenu page if there are plugin actions to take. - * - * This method adds the submenu page letting users know that a required - * plugin needs to be installed. - * - * This page disappears once the plugin has been installed and activated. - * - * @since 1.0.0 - * - * @see TGM_Plugin_Activation::init() - * @see TGM_Plugin_Activation::install_plugins_page() - * - * @return null Return early if user lacks capability to install a plugin. - */ - public function admin_menu() { - // Make sure privileges are correct to see the page. - if ( ! current_user_can( 'install_plugins' ) ) { - return; - } - - $args = apply_filters( - 'tgmpa_admin_menu_args', - array( - 'parent_slug' => $this->parent_slug, // Parent Menu slug. - 'page_title' => $this->strings['page_title'], // Page title. - 'menu_title' => $this->strings['menu_title'], // Menu title. - 'capability' => $this->capability, // Capability. - 'menu_slug' => $this->menu, // Menu slug. - 'function' => array( $this, 'install_plugins_page' ), // Callback. - ) - ); - - $this->add_admin_menu( $args ); - } - - /** - * Add the menu item. - * - * {@internal IMPORTANT! If this function changes, review the regex in the custom TGMPA - * generator on the website.}} - * - * @since 2.5.0 - * - * @param array $args Menu item configuration. - */ - protected function add_admin_menu( array $args ) { - $this->page_hook = add_theme_page( $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] ); - } - - /** - * Echoes plugin installation form. - * - * This method is the callback for the admin_menu method function. - * This displays the admin page and form area where the user can select to install and activate the plugin. - * Aborts early if we're processing a plugin installation action. - * - * @since 1.0.0 - * - * @return null Aborts early if we're processing a plugin installation action. - */ - public function install_plugins_page() { - // Store new instance of plugin table in object. - $plugin_table = new TGMPA_List_Table; - - // Return early if processing a plugin installation action. - if ( ( ( 'tgmpa-bulk-install' === $plugin_table->current_action() || 'tgmpa-bulk-update' === $plugin_table->current_action() ) && $plugin_table->process_bulk_actions() ) || $this->do_plugin_install() ) { - return; - } - - // Force refresh of available plugin information so we'll know about manual updates/deletes. - wp_clean_plugins_cache( false ); - - ?> -
-

- prepare_items(); ?> - - message ) && is_string( $this->message ) ) { - echo wp_kses_post( $this->message ); - } - ?> - views(); ?> - -
- - - display(); ?> -
-
- sanitize_key( urldecode( $_GET['plugin'] ) ); - - if ( ! isset( $this->plugins[ $slug ] ) ) { - return false; - } - - // Was an install or upgrade action link clicked? - if ( ( isset( $_GET['tgmpa-install'] ) && 'install-plugin' === $_GET['tgmpa-install'] ) || ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) ) { - - $install_type = 'install'; - if ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) { - $install_type = 'update'; - } - - check_admin_referer( 'tgmpa-' . $install_type, 'tgmpa-nonce' ); - - // Pass necessary information via URL if WP_Filesystem is needed. - $url = wp_nonce_url( - add_query_arg( - array( - 'plugin' => urlencode( $slug ), - 'tgmpa-' . $install_type => $install_type . '-plugin', - ), - $this->get_tgmpa_url() - ), - 'tgmpa-' . $install_type, - 'tgmpa-nonce' - ); - - $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. - - if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, array() ) ) ) { - return true; - } - - if ( ! WP_Filesystem( $creds ) ) { - request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, array() ); // Setup WP_Filesystem. - return true; - } - - /* If we arrive here, we have the filesystem. */ - - // Prep variables for Plugin_Installer_Skin class. - $extra = array(); - $extra['slug'] = $slug; // Needed for potentially renaming of directory name. - $source = $this->get_download_url( $slug ); - $api = ( 'repo' === $this->plugins[ $slug ]['source_type'] ) ? $this->get_plugins_api( $slug ) : null; - $api = ( false !== $api ) ? $api : null; - - $url = add_query_arg( - array( - 'action' => $install_type . '-plugin', - 'plugin' => urlencode( $slug ), - ), - 'update.php' - ); - - if ( ! class_exists( 'Plugin_Upgrader', false ) ) { - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - } - - $title = ( 'update' === $install_type ) ? $this->strings['updating'] : $this->strings['installing']; - $skin_args = array( - 'type' => ( 'bundled' !== $this->plugins[ $slug ]['source_type'] ) ? 'web' : 'upload', - 'title' => sprintf( $title, $this->plugins[ $slug ]['name'] ), - 'url' => esc_url_raw( $url ), - 'nonce' => $install_type . '-plugin_' . $slug, - 'plugin' => '', - 'api' => $api, - 'extra' => $extra, - ); - unset( $title ); - - if ( 'update' === $install_type ) { - $skin_args['plugin'] = $this->plugins[ $slug ]['file_path']; - $skin = new Plugin_Upgrader_Skin( $skin_args ); - } else { - $skin = new Plugin_Installer_Skin( $skin_args ); - } - - // Create a new instance of Plugin_Upgrader. - $upgrader = new Plugin_Upgrader( $skin ); - - // Perform the action and install the plugin from the $source urldecode(). - add_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 ); - - if ( 'update' === $install_type ) { - // Inject our info into the update transient. - $to_inject = array( $slug => $this->plugins[ $slug ] ); - $to_inject[ $slug ]['source'] = $source; - $this->inject_update_info( $to_inject ); - - $upgrader->upgrade( $this->plugins[ $slug ]['file_path'] ); - } else { - $upgrader->install( $source ); - } - - remove_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1 ); - - // Make sure we have the correct file path now the plugin is installed/updated. - $this->populate_file_path( $slug ); - - // Only activate plugins if the config option is set to true and the plugin isn't - // already active (upgrade). - if ( $this->is_automatic && ! $this->is_plugin_active( $slug ) ) { - $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method. - if ( false === $this->activate_single_plugin( $plugin_activate, $slug, true ) ) { - return true; // Finish execution of the function early as we encountered an error. - } - } - - $this->show_tgmpa_version(); - - // Display message based on if all plugins are now active or not. - if ( $this->is_tgmpa_complete() ) { - echo '

', sprintf( esc_html( $this->strings['complete'] ), '' . esc_html__( 'Return to the Dashboard', 'craftnce' ) . '' ), '

'; - echo ''; - } else { - echo '

', esc_html( $this->strings['return'] ), '

'; - } - - return true; - } elseif ( isset( $this->plugins[ $slug ]['file_path'], $_GET['tgmpa-activate'] ) && 'activate-plugin' === $_GET['tgmpa-activate'] ) { - // Activate action link was clicked. - check_admin_referer( 'tgmpa-activate', 'tgmpa-nonce' ); - - if ( false === $this->activate_single_plugin( $this->plugins[ $slug ]['file_path'], $slug ) ) { - return true; // Finish execution of the function early as we encountered an error. - } - } - - return false; - } - - /** - * Inject information into the 'update_plugins' site transient as WP checks that before running an update. - * - * @since 2.5.0 - * - * @param array $plugins The plugin information for the plugins which are to be updated. - */ - public function inject_update_info( $plugins ) { - $repo_updates = get_site_transient( 'update_plugins' ); - - if ( ! is_object( $repo_updates ) ) { - $repo_updates = new stdClass; - } - - foreach ( $plugins as $slug => $plugin ) { - $file_path = $plugin['file_path']; - - if ( empty( $repo_updates->response[ $file_path ] ) ) { - $repo_updates->response[ $file_path ] = new stdClass; - } - - // We only really need to set package, but let's do all we can in case WP changes something. - $repo_updates->response[ $file_path ]->slug = $slug; - $repo_updates->response[ $file_path ]->plugin = $file_path; - $repo_updates->response[ $file_path ]->new_version = $plugin['version']; - $repo_updates->response[ $file_path ]->package = $plugin['source']; - if ( empty( $repo_updates->response[ $file_path ]->url ) && ! empty( $plugin['external_url'] ) ) { - $repo_updates->response[ $file_path ]->url = $plugin['external_url']; - } - } - - set_site_transient( 'update_plugins', $repo_updates ); - } - - /** - * Adjust the plugin directory name if necessary. - * - * The final destination directory of a plugin is based on the subdirectory name found in the - * (un)zipped source. In some cases - most notably GitHub repository plugin downloads -, this - * subdirectory name is not the same as the expected slug and the plugin will not be recognized - * as installed. This is fixed by adjusting the temporary unzipped source subdirectory name to - * the expected plugin slug. - * - * @since 2.5.0 - * - * @param string $source Path to upgrade/zip-file-name.tmp/subdirectory/. - * @param string $remote_source Path to upgrade/zip-file-name.tmp. - * @param \WP_Upgrader $upgrader Instance of the upgrader which installs the plugin. - * @return string $source - */ - public function maybe_adjust_source_dir( $source, $remote_source, $upgrader ) { - if ( ! $this->is_tgmpa_page() || ! is_object( $GLOBALS['wp_filesystem'] ) ) { - return $source; - } - - // Check for single file plugins. - $source_files = array_keys( $GLOBALS['wp_filesystem']->dirlist( $remote_source ) ); - if ( 1 === count( $source_files ) && false === $GLOBALS['wp_filesystem']->is_dir( $source ) ) { - return $source; - } - - // Multi-file plugin, let's see if the directory is correctly named. - $desired_slug = ''; - - // Figure out what the slug is supposed to be. - if ( false === $upgrader->bulk && ! empty( $upgrader->skin->options['extra']['slug'] ) ) { - $desired_slug = $upgrader->skin->options['extra']['slug']; - } else { - // Bulk installer contains less info, so fall back on the info registered here. - foreach ( $this->plugins as $slug => $plugin ) { - if ( ! empty( $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) && $plugin['name'] === $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) { - $desired_slug = $slug; - break; - } - } - unset( $slug, $plugin ); - } - - if ( ! empty( $desired_slug ) ) { - $subdir_name = untrailingslashit( str_replace( trailingslashit( $remote_source ), '', $source ) ); - - if ( ! empty( $subdir_name ) && $subdir_name !== $desired_slug ) { - $from_path = untrailingslashit( $source ); - $to_path = trailingslashit( $remote_source ) . $desired_slug; - - if ( true === $GLOBALS['wp_filesystem']->move( $from_path, $to_path ) ) { - return trailingslashit( $to_path ); - } else { - return new WP_Error( 'rename_failed', esc_html__( 'The remote plugin package does not contain a folder with the desired slug and renaming did not work.', 'craftnce' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'craftnce' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) ); - } - } elseif ( empty( $subdir_name ) ) { - return new WP_Error( 'packaged_wrong', esc_html__( 'The remote plugin package consists of more than one file, but the files are not packaged in a folder.', 'craftnce' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'craftnce' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) ); - } - } - - return $source; - } - - /** - * Activate a single plugin and send feedback about the result to the screen. - * - * @since 2.5.0 - * - * @param string $file_path Path within wp-plugins/ to main plugin file. - * @param string $slug Plugin slug. - * @param bool $automatic Whether this is an automatic activation after an install. Defaults to false. - * This determines the styling of the output messages. - * @return bool False if an error was encountered, true otherwise. - */ - protected function activate_single_plugin( $file_path, $slug, $automatic = false ) { - if ( $this->can_plugin_activate( $slug ) ) { - $activate = activate_plugin( $file_path ); - - if ( is_wp_error( $activate ) ) { - echo '

', wp_kses_post( $activate->get_error_message() ), '

', - '

', esc_html( $this->strings['return'] ), '

'; - - return false; // End it here if there is an error with activation. - } else { - if ( ! $automatic ) { - // Make sure message doesn't display again if bulk activation is performed - // immediately after a single activation. - if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK. - echo '

', esc_html( $this->strings['activated_successfully'] ), ' ', esc_html( $this->plugins[ $slug ]['name'] ), '.

'; - } - } else { - // Simpler message layout for use on the plugin install page. - echo '

', esc_html( $this->strings['plugin_activated'] ), '

'; - } - } - } elseif ( $this->is_plugin_active( $slug ) ) { - // No simpler message format provided as this message should never be encountered - // on the plugin install page. - echo '

', - sprintf( - esc_html( $this->strings['plugin_already_active'] ), - '' . esc_html( $this->plugins[ $slug ]['name'] ) . '' - ), - '

'; - } elseif ( $this->does_plugin_require_update( $slug ) ) { - if ( ! $automatic ) { - // Make sure message doesn't display again if bulk activation is performed - // immediately after a single activation. - if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK. - echo '

', - sprintf( - esc_html( $this->strings['plugin_needs_higher_version'] ), - '' . esc_html( $this->plugins[ $slug ]['name'] ) . '' - ), - '

'; - } - } else { - // Simpler message layout for use on the plugin install page. - echo '

', sprintf( esc_html( $this->strings['plugin_needs_higher_version'] ), esc_html( $this->plugins[ $slug ]['name'] ) ), '

'; - } - } - - return true; - } - - /** - * Echoes required plugin notice. - * - * Outputs a message telling users that a specific plugin is required for - * their theme. If appropriate, it includes a link to the form page where - * users can install and activate the plugin. - * - * Returns early if we're on the Install page. - * - * @since 1.0.0 - * - * @global object $current_screen - * - * @return null Returns early if we're on the Install page. - */ - public function notices() { - // Remove nag on the install page / Return early if the nag message has been dismissed or user < author. - if ( ( $this->is_tgmpa_page() || $this->is_core_update_page() ) || get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) || ! current_user_can( apply_filters( 'tgmpa_show_admin_notice_capability', 'publish_posts' ) ) ) { - return; - } - - // Store for the plugin slugs by message type. - $message = array(); - - // Initialize counters used to determine plurality of action link texts. - $install_link_count = 0; - $update_link_count = 0; - $activate_link_count = 0; - $total_required_action_count = 0; - - foreach ( $this->plugins as $slug => $plugin ) { - if ( $this->is_plugin_active( $slug ) && false === $this->does_plugin_have_update( $slug ) ) { - continue; - } - - if ( ! $this->is_plugin_installed( $slug ) ) { - if ( current_user_can( 'install_plugins' ) ) { - $install_link_count++; - - if ( true === $plugin['required'] ) { - $message['notice_can_install_required'][] = $slug; - } else { - $message['notice_can_install_recommended'][] = $slug; - } - } - if ( true === $plugin['required'] ) { - $total_required_action_count++; - } - } else { - if ( ! $this->is_plugin_active( $slug ) && $this->can_plugin_activate( $slug ) ) { - if ( current_user_can( 'activate_plugins' ) ) { - $activate_link_count++; - - if ( true === $plugin['required'] ) { - $message['notice_can_activate_required'][] = $slug; - } else { - $message['notice_can_activate_recommended'][] = $slug; - } - } - if ( true === $plugin['required'] ) { - $total_required_action_count++; - } - } - - if ( $this->does_plugin_require_update( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) { - - if ( current_user_can( 'update_plugins' ) ) { - $update_link_count++; - - if ( $this->does_plugin_require_update( $slug ) ) { - $message['notice_ask_to_update'][] = $slug; - } elseif ( false !== $this->does_plugin_have_update( $slug ) ) { - $message['notice_ask_to_update_maybe'][] = $slug; - } - } - if ( true === $plugin['required'] ) { - $total_required_action_count++; - } - } - } - } - unset( $slug, $plugin ); - - // If we have notices to display, we move forward. - if ( ! empty( $message ) || $total_required_action_count > 0 ) { - krsort( $message ); // Sort messages. - $rendered = ''; - - // As add_settings_error() wraps the final message in a

and as the final message can't be - // filtered, using

's in our html would render invalid html output. - $line_template = '%s' . "\n"; - - if ( ! current_user_can( 'activate_plugins' ) && ! current_user_can( 'install_plugins' ) && ! current_user_can( 'update_plugins' ) ) { - $rendered = esc_html( $this->strings['notice_cannot_install_activate'] ) . ' ' . esc_html( $this->strings['contact_admin'] ); - $rendered .= $this->create_user_action_links_for_notice( 0, 0, 0, $line_template ); - } else { - - // If dismissable is false and a message is set, output it now. - if ( ! $this->dismissable && ! empty( $this->dismiss_msg ) ) { - $rendered .= sprintf( $line_template, wp_kses_post( $this->dismiss_msg ) ); - } - - // Render the individual message lines for the notice. - foreach ( $message as $type => $plugin_group ) { - $linked_plugins = array(); - - // Get the external info link for a plugin if one is available. - foreach ( $plugin_group as $plugin_slug ) { - $linked_plugins[] = $this->get_info_link( $plugin_slug ); - } - unset( $plugin_slug ); - - $count = count( $plugin_group ); - $linked_plugins = array_map( array( 'TGMPA_Utils', 'wrap_in_em' ), $linked_plugins ); - $last_plugin = array_pop( $linked_plugins ); // Pop off last name to prep for readability. - $imploded = empty( $linked_plugins ) ? $last_plugin : ( implode( ', ', $linked_plugins ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'craftnce' ) . ' ' . $last_plugin ); - - $rendered .= sprintf( - $line_template, - sprintf( - translate_nooped_plural( $this->strings[ $type ], $count, 'craftnce' ), - $imploded, - $count - ) - ); - - } - unset( $type, $plugin_group, $linked_plugins, $count, $last_plugin, $imploded ); - - $rendered .= $this->create_user_action_links_for_notice( $install_link_count, $update_link_count, $activate_link_count, $line_template ); - } - - // Register the nag messages and prepare them to be processed. - add_settings_error( 'tgmpa', 'tgmpa', $rendered, $this->get_admin_notice_class() ); - } - - // Admin options pages already output settings_errors, so this is to avoid duplication. - if ( 'options-general' !== $GLOBALS['current_screen']->parent_base ) { - $this->display_settings_errors(); - } - } - - /** - * Generate the user action links for the admin notice. - * - * @since 2.6.0 - * - * @param int $install_count Number of plugins to install. - * @param int $update_count Number of plugins to update. - * @param int $activate_count Number of plugins to activate. - * @param int $line_template Template for the HTML tag to output a line. - * @return string Action links. - */ - protected function create_user_action_links_for_notice( $install_count, $update_count, $activate_count, $line_template ) { - // Setup action links. - $action_links = array( - 'install' => '', - 'update' => '', - 'activate' => '', - 'dismiss' => $this->dismissable ? '' . esc_html( $this->strings['dismiss'] ) . '' : '', - ); - - $link_template = '%1$s'; - - if ( current_user_can( 'install_plugins' ) ) { - if ( $install_count > 0 ) { - $action_links['install'] = sprintf( - $link_template, - translate_nooped_plural( $this->strings['install_link'], $install_count, 'craftnce' ), - esc_url( $this->get_tgmpa_status_url( 'install' ) ) - ); - } - if ( $update_count > 0 ) { - $action_links['update'] = sprintf( - $link_template, - translate_nooped_plural( $this->strings['update_link'], $update_count, 'craftnce' ), - esc_url( $this->get_tgmpa_status_url( 'update' ) ) - ); - } - } - - if ( current_user_can( 'activate_plugins' ) && $activate_count > 0 ) { - $action_links['activate'] = sprintf( - $link_template, - translate_nooped_plural( $this->strings['activate_link'], $activate_count, 'craftnce' ), - esc_url( $this->get_tgmpa_status_url( 'activate' ) ) - ); - } - - $action_links = apply_filters( 'tgmpa_notice_action_links', $action_links ); - - $action_links = array_filter( (array) $action_links ); // Remove any empty array items. - - if ( ! empty( $action_links ) ) { - $action_links = sprintf( $line_template, implode( ' | ', $action_links ) ); - return apply_filters( 'tgmpa_notice_rendered_action_links', $action_links ); - } else { - return ''; - } - } - - /** - * Get admin notice class. - * - * Work around all the changes to the various admin notice classes between WP 4.4 and 3.7 - * (lowest supported version by TGMPA). - * - * @since 2.6.0 - * - * @return string - */ - protected function get_admin_notice_class() { - if ( ! empty( $this->strings['nag_type'] ) ) { - return sanitize_html_class( strtolower( $this->strings['nag_type'] ) ); - } else { - if ( version_compare( $this->wp_version, '4.2', '>=' ) ) { - return 'notice-warning'; - } elseif ( version_compare( $this->wp_version, '4.1', '>=' ) ) { - return 'notice'; - } else { - return 'updated'; - } - } - } - - /** - * Display settings errors and remove those which have been displayed to avoid duplicate messages showing - * - * @since 2.5.0 - */ - protected function display_settings_errors() { - global $wp_settings_errors; - - settings_errors( 'tgmpa' ); - - foreach ( (array) $wp_settings_errors as $key => $details ) { - if ( 'tgmpa' === $details['setting'] ) { - unset( $wp_settings_errors[ $key ] ); - break; - } - } - } - - /** - * Register dismissal of admin notices. - * - * Acts on the dismiss link in the admin nag messages. - * If clicked, the admin notice disappears and will no longer be visible to this user. - * - * @since 2.1.0 - */ - public function dismiss() { - if ( isset( $_GET['tgmpa-dismiss'] ) && check_admin_referer( 'tgmpa-dismiss-' . get_current_user_id() ) ) { - update_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, 1 ); - } - } - - /** - * Add individual plugin to our collection of plugins. - * - * If the required keys are not set or the plugin has already - * been registered, the plugin is not added. - * - * @since 2.0.0 - * - * @param array|null $plugin Array of plugin arguments or null if invalid argument. - * @return null Return early if incorrect argument. - */ - public function register( $plugin ) { - if ( empty( $plugin['slug'] ) || empty( $plugin['name'] ) ) { - return; - } - - if ( empty( $plugin['slug'] ) || ! is_string( $plugin['slug'] ) || isset( $this->plugins[ $plugin['slug'] ] ) ) { - return; - } - - $defaults = array( - 'name' => '', // String - 'slug' => '', // String - 'source' => 'repo', // String - 'required' => false, // Boolean - 'version' => '', // String - 'force_activation' => false, // Boolean - 'force_deactivation' => false, // Boolean - 'external_url' => '', // String - 'is_callable' => '', // String|Array. - ); - - // Prepare the received data. - $plugin = wp_parse_args( $plugin, $defaults ); - - // Standardize the received slug. - $plugin['slug'] = $this->sanitize_key( $plugin['slug'] ); - - // Forgive users for using string versions of booleans or floats for version number. - $plugin['version'] = (string) $plugin['version']; - $plugin['source'] = empty( $plugin['source'] ) ? 'repo' : $plugin['source']; - $plugin['required'] = TGMPA_Utils::validate_bool( $plugin['required'] ); - $plugin['force_activation'] = TGMPA_Utils::validate_bool( $plugin['force_activation'] ); - $plugin['force_deactivation'] = TGMPA_Utils::validate_bool( $plugin['force_deactivation'] ); - - // Enrich the received data. - $plugin['file_path'] = $this->_get_plugin_basename_from_slug( $plugin['slug'] ); - $plugin['source_type'] = $this->get_plugin_source_type( $plugin['source'] ); - - // Set the class properties. - $this->plugins[ $plugin['slug'] ] = $plugin; - $this->sort_order[ $plugin['slug'] ] = $plugin['name']; - - // Should we add the force activation hook ? - if ( true === $plugin['force_activation'] ) { - $this->has_forced_activation = true; - } - - // Should we add the force deactivation hook ? - if ( true === $plugin['force_deactivation'] ) { - $this->has_forced_deactivation = true; - } - } - - /** - * Determine what type of source the plugin comes from. - * - * @since 2.5.0 - * - * @param string $source The source of the plugin as provided, either empty (= WP repo), a file path - * (= bundled) or an external URL. - * @return string 'repo', 'external', or 'bundled' - */ - protected function get_plugin_source_type( $source ) { - if ( 'repo' === $source || preg_match( self::WP_REPO_REGEX, $source ) ) { - return 'repo'; - } elseif ( preg_match( self::IS_URL_REGEX, $source ) ) { - return 'external'; - } else { - return 'bundled'; - } - } - - /** - * Sanitizes a string key. - * - * Near duplicate of WP Core `sanitize_key()`. The difference is that uppercase characters *are* - * allowed, so as not to break upgrade paths from non-standard bundled plugins using uppercase - * characters in the plugin directory path/slug. Silly them. - * - * @see https://developer.wordpress.org/reference/hooks/sanitize_key/ - * - * @since 2.5.0 - * - * @param string $key String key. - * @return string Sanitized key - */ - public function sanitize_key( $key ) { - $raw_key = $key; - $key = preg_replace( '`[^A-Za-z0-9_-]`', '', $key ); - - /** - * Filter a sanitized key string. - * - * @since 2.5.0 - * - * @param string $key Sanitized key. - * @param string $raw_key The key prior to sanitization. - */ - return apply_filters( 'tgmpa_sanitize_key', $key, $raw_key ); - } - - /** - * Amend default configuration settings. - * - * @since 2.0.0 - * - * @param array $config Array of config options to pass as class properties. - */ - public function config( $config ) { - $keys = array( - 'id', - 'default_path', - 'has_notices', - 'dismissable', - 'dismiss_msg', - 'menu', - 'parent_slug', - 'capability', - 'is_automatic', - 'message', - 'strings', - ); - - foreach ( $keys as $key ) { - if ( isset( $config[ $key ] ) ) { - if ( is_array( $config[ $key ] ) ) { - $this->$key = array_merge( $this->$key, $config[ $key ] ); - } else { - $this->$key = $config[ $key ]; - } - } - } - } - - /** - * Amend action link after plugin installation. - * - * @since 2.0.0 - * - * @param array $install_actions Existing array of actions. - * @return false|array Amended array of actions. - */ - public function actions( $install_actions ) { - // Remove action links on the TGMPA install page. - if ( $this->is_tgmpa_page() ) { - return false; - } - - return $install_actions; - } - - /** - * Flushes the plugins cache on theme switch to prevent stale entries - * from remaining in the plugin table. - * - * @since 2.4.0 - * - * @param bool $clear_update_cache Optional. Whether to clear the Plugin updates cache. - * Parameter added in v2.5.0. - */ - public function flush_plugins_cache( $clear_update_cache = true ) { - wp_clean_plugins_cache( $clear_update_cache ); - } - - /** - * Set file_path key for each installed plugin. - * - * @since 2.1.0 - * - * @param string $plugin_slug Optional. If set, only (re-)populates the file path for that specific plugin. - * Parameter added in v2.5.0. - */ - public function populate_file_path( $plugin_slug = '' ) { - if ( ! empty( $plugin_slug ) && is_string( $plugin_slug ) && isset( $this->plugins[ $plugin_slug ] ) ) { - $this->plugins[ $plugin_slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $plugin_slug ); - } else { - // Add file_path key for all plugins. - foreach ( $this->plugins as $slug => $values ) { - $this->plugins[ $slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $slug ); - } - } - } - - /** - * Helper function to extract the file path of the plugin file from the - * plugin slug, if the plugin is installed. - * - * @since 2.0.0 - * - * @param string $slug Plugin slug (typically folder name) as provided by the developer. - * @return string Either file path for plugin if installed, or just the plugin slug. - */ - protected function _get_plugin_basename_from_slug( $slug ) { - $keys = array_keys( $this->get_plugins() ); - - foreach ( $keys as $key ) { - if ( preg_match( '|^' . $slug . '/|', $key ) ) { - return $key; - } - } - - return $slug; - } - - /** - * Retrieve plugin data, given the plugin name. - * - * Loops through the registered plugins looking for $name. If it finds it, - * it returns the $data from that plugin. Otherwise, returns false. - * - * @since 2.1.0 - * - * @param string $name Name of the plugin, as it was registered. - * @param string $data Optional. Array key of plugin data to return. Default is slug. - * @return string|boolean Plugin slug if found, false otherwise. - */ - public function _get_plugin_data_from_name( $name, $data = 'slug' ) { - foreach ( $this->plugins as $values ) { - if ( $name === $values['name'] && isset( $values[ $data ] ) ) { - return $values[ $data ]; - } - } - - return false; - } - - /** - * Retrieve the download URL for a package. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return string Plugin download URL or path to local file or empty string if undetermined. - */ - public function get_download_url( $slug ) { - $dl_source = ''; - - switch ( $this->plugins[ $slug ]['source_type'] ) { - case 'repo': - return $this->get_wp_repo_download_url( $slug ); - case 'external': - return $this->plugins[ $slug ]['source']; - case 'bundled': - return $this->default_path . $this->plugins[ $slug ]['source']; - } - - return $dl_source; // Should never happen. - } - - /** - * Retrieve the download URL for a WP repo package. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return string Plugin download URL. - */ - protected function get_wp_repo_download_url( $slug ) { - $source = ''; - $api = $this->get_plugins_api( $slug ); - - if ( false !== $api && isset( $api->download_link ) ) { - $source = $api->download_link; - } - - return $source; - } - - /** - * Try to grab information from WordPress API. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return object Plugins_api response object on success, WP_Error on failure. - */ - protected function get_plugins_api( $slug ) { - static $api = array(); // Cache received responses. - - if ( ! isset( $api[ $slug ] ) ) { - if ( ! function_exists( 'plugins_api' ) ) { - require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; - } - - $response = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) ); - - $api[ $slug ] = false; - - if ( is_wp_error( $response ) ) { - wp_die( esc_html( $this->strings['oops'] ) ); - } else { - $api[ $slug ] = $response; - } - } - - return $api[ $slug ]; - } - - /** - * Retrieve a link to a plugin information page. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return string Fully formed html link to a plugin information page if available - * or the plugin name if not. - */ - public function get_info_link( $slug ) { - if ( ! empty( $this->plugins[ $slug ]['external_url'] ) && preg_match( self::IS_URL_REGEX, $this->plugins[ $slug ]['external_url'] ) ) { - $link = sprintf( - '%2$s', - esc_url( $this->plugins[ $slug ]['external_url'] ), - esc_html( $this->plugins[ $slug ]['name'] ) - ); - } elseif ( 'repo' === $this->plugins[ $slug ]['source_type'] ) { - $url = add_query_arg( - array( - 'tab' => 'plugin-information', - 'plugin' => urlencode( $slug ), - 'TB_iframe' => 'true', - 'width' => '640', - 'height' => '500', - ), - self_admin_url( 'plugin-install.php' ) - ); - - $link = sprintf( - '%2$s', - esc_url( $url ), - esc_html( $this->plugins[ $slug ]['name'] ) - ); - } else { - $link = esc_html( $this->plugins[ $slug ]['name'] ); // No hyperlink. - } - - return $link; - } - - /** - * Determine if we're on the TGMPA Install page. - * - * @since 2.1.0 - * - * @return boolean True when on the TGMPA page, false otherwise. - */ - protected function is_tgmpa_page() { - return isset( $_GET['page'] ) && $this->menu === $_GET['page']; - } - - /** - * Determine if we're on a WP Core installation/upgrade page. - * - * @since 2.6.0 - * - * @return boolean True when on a WP Core installation/upgrade page, false otherwise. - */ - protected function is_core_update_page() { - // Current screen is not always available, most notably on the customizer screen. - if ( ! function_exists( 'get_current_screen' ) ) { - return false; - } - - $screen = get_current_screen(); - - if ( 'update-core' === $screen->base ) { - // Core update screen. - return true; - } elseif ( 'plugins' === $screen->base && ! empty( $_POST['action'] ) ) { // WPCS: CSRF ok. - // Plugins bulk update screen. - return true; - } elseif ( 'update' === $screen->base && ! empty( $_POST['action'] ) ) { // WPCS: CSRF ok. - // Individual updates (ajax call). - return true; - } - - return false; - } - - /** - * Retrieve the URL to the TGMPA Install page. - * - * I.e. depending on the config settings passed something along the lines of: - * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins - * - * @since 2.5.0 - * - * @return string Properly encoded URL (not escaped). - */ - public function get_tgmpa_url() { - static $url; - - if ( ! isset( $url ) ) { - $parent = $this->parent_slug; - if ( false === strpos( $parent, '.php' ) ) { - $parent = 'admin.php'; - } - $url = add_query_arg( - array( - 'page' => urlencode( $this->menu ), - ), - self_admin_url( $parent ) - ); - } - - return $url; - } - - /** - * Retrieve the URL to the TGMPA Install page for a specific plugin status (view). - * - * I.e. depending on the config settings passed something along the lines of: - * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins&plugin_status=install - * - * @since 2.5.0 - * - * @param string $status Plugin status - either 'install', 'update' or 'activate'. - * @return string Properly encoded URL (not escaped). - */ - public function get_tgmpa_status_url( $status ) { - return add_query_arg( - array( - 'plugin_status' => urlencode( $status ), - ), - $this->get_tgmpa_url() - ); - } - - /** - * Determine whether there are open actions for plugins registered with TGMPA. - * - * @since 2.5.0 - * - * @return bool True if complete, i.e. no outstanding actions. False otherwise. - */ - public function is_tgmpa_complete() { - $complete = true; - foreach ( $this->plugins as $slug => $plugin ) { - if ( ! $this->is_plugin_active( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) { - $complete = false; - break; - } - } - - return $complete; - } - - /** - * Check if a plugin is installed. Does not take must-use plugins into account. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return bool True if installed, false otherwise. - */ - public function is_plugin_installed( $slug ) { - $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached). - - return ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ] ) ); - } - - /** - * Check if a plugin is active. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return bool True if active, false otherwise. - */ - public function is_plugin_active( $slug ) { - return ( ( ! empty( $this->plugins[ $slug ]['is_callable'] ) && is_callable( $this->plugins[ $slug ]['is_callable'] ) ) || is_plugin_active( $this->plugins[ $slug ]['file_path'] ) ); - } - - /** - * Check if a plugin can be updated, i.e. if we have information on the minimum WP version required - * available, check whether the current install meets them. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return bool True if OK to update, false otherwise. - */ - public function can_plugin_update( $slug ) { - // We currently can't get reliable info on non-WP-repo plugins - issue #380. - if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { - return true; - } - - $api = $this->get_plugins_api( $slug ); - - if ( false !== $api && isset( $api->requires ) ) { - return version_compare( $this->wp_version, $api->requires, '>=' ); - } - - // No usable info received from the plugins API, presume we can update. - return true; - } - - /** - * Check to see if the plugin is 'updatetable', i.e. installed, with an update available - * and no WP version requirements blocking it. - * - * @since 2.6.0 - * - * @param string $slug Plugin slug. - * @return bool True if OK to proceed with update, false otherwise. - */ - public function is_plugin_updatetable( $slug ) { - if ( ! $this->is_plugin_installed( $slug ) ) { - return false; - } else { - return ( false !== $this->does_plugin_have_update( $slug ) && $this->can_plugin_update( $slug ) ); - } - } - - /** - * Check if a plugin can be activated, i.e. is not currently active and meets the minimum - * plugin version requirements set in TGMPA (if any). - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return bool True if OK to activate, false otherwise. - */ - public function can_plugin_activate( $slug ) { - return ( ! $this->is_plugin_active( $slug ) && ! $this->does_plugin_require_update( $slug ) ); - } - - /** - * Retrieve the version number of an installed plugin. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return string Version number as string or an empty string if the plugin is not installed - * or version unknown (plugins which don't comply with the plugin header standard). - */ - public function get_installed_version( $slug ) { - $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached). - - if ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'] ) ) { - return $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version']; - } - - return ''; - } - - /** - * Check whether a plugin complies with the minimum version requirements. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return bool True when a plugin needs to be updated, otherwise false. - */ - public function does_plugin_require_update( $slug ) { - $installed_version = $this->get_installed_version( $slug ); - $minimum_version = $this->plugins[ $slug ]['version']; - - return version_compare( $minimum_version, $installed_version, '>' ); - } - - /** - * Check whether there is an update available for a plugin. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return false|string Version number string of the available update or false if no update available. - */ - public function does_plugin_have_update( $slug ) { - // Presume bundled and external plugins will point to a package which meets the minimum required version. - if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { - if ( $this->does_plugin_require_update( $slug ) ) { - return $this->plugins[ $slug ]['version']; - } - - return false; - } - - $repo_updates = get_site_transient( 'update_plugins' ); - - if ( isset( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version ) ) { - return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version; - } - - return false; - } - - /** - * Retrieve potential upgrade notice for a plugin. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return string The upgrade notice or an empty string if no message was available or provided. - */ - public function get_upgrade_notice( $slug ) { - // We currently can't get reliable info on non-WP-repo plugins - issue #380. - if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { - return ''; - } - - $repo_updates = get_site_transient( 'update_plugins' ); - - if ( ! empty( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice ) ) { - return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice; - } - - return ''; - } - - /** - * Wrapper around the core WP get_plugins function, making sure it's actually available. - * - * @since 2.5.0 - * - * @param string $plugin_folder Optional. Relative path to single plugin folder. - * @return array Array of installed plugins with plugin information. - */ - public function get_plugins( $plugin_folder = '' ) { - if ( ! function_exists( 'get_plugins' ) ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - } - - return get_plugins( $plugin_folder ); - } - - /** - * Delete dismissable nag option when theme is switched. - * - * This ensures that the user(s) is/are again reminded via nag of required - * and/or recommended plugins if they re-activate the theme. - * - * @since 2.1.1 - */ - public function update_dismiss() { - delete_metadata( 'user', null, 'tgmpa_dismissed_notice_' . $this->id, null, true ); - } - - /** - * Forces plugin activation if the parameter 'force_activation' is - * set to true. - * - * This allows theme authors to specify certain plugins that must be - * active at all times while using the current theme. - * - * Please take special care when using this parameter as it has the - * potential to be harmful if not used correctly. Setting this parameter - * to true will not allow the specified plugin to be deactivated unless - * the user switches themes. - * - * @since 2.2.0 - */ - public function force_activation() { - foreach ( $this->plugins as $slug => $plugin ) { - if ( true === $plugin['force_activation'] ) { - if ( ! $this->is_plugin_installed( $slug ) ) { - // Oops, plugin isn't there so iterate to next condition. - continue; - } elseif ( $this->can_plugin_activate( $slug ) ) { - // There we go, activate the plugin. - activate_plugin( $plugin['file_path'] ); - } - } - } - } - - /** - * Forces plugin deactivation if the parameter 'force_deactivation' - * is set to true and adds the plugin to the 'recently active' plugins list. - * - * This allows theme authors to specify certain plugins that must be - * deactivated upon switching from the current theme to another. - * - * Please take special care when using this parameter as it has the - * potential to be harmful if not used correctly. - * - * @since 2.2.0 - */ - public function force_deactivation() { - $deactivated = array(); - - foreach ( $this->plugins as $slug => $plugin ) { - /* - * Only proceed forward if the parameter is set to true and plugin is active - * as a 'normal' (not must-use) plugin. - */ - if ( true === $plugin['force_deactivation'] && is_plugin_active( $plugin['file_path'] ) ) { - deactivate_plugins( $plugin['file_path'] ); - $deactivated[ $plugin['file_path'] ] = time(); - } - } - - if ( ! empty( $deactivated ) ) { - update_option( 'recently_activated', $deactivated + (array) get_option( 'recently_activated' ) ); - } - } - - /** - * Echo the current TGMPA version number to the page. - * - * @since 2.5.0 - */ - public function show_tgmpa_version() { - echo '

', - esc_html( - sprintf( - /* translators: %s: version number */ - __( 'TGMPA v%s', 'craftnce' ), - self::TGMPA_VERSION - ) - ), - '

'; - } - - /** - * Returns the singleton instance of the class. - * - * @since 2.4.0 - * - * @return \TGM_Plugin_Activation The TGM_Plugin_Activation object. - */ - public static function get_instance() { - if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) { - self::$instance = new self(); - } - - return self::$instance; - } - } - - if ( ! function_exists( 'load_tgm_plugin_activation' ) ) { - /** - * Ensure only one instance of the class is ever invoked. - * - * @since 2.5.0 - */ - function load_tgm_plugin_activation() { - $GLOBALS['tgmpa'] = TGM_Plugin_Activation::get_instance(); - } - } - - if ( did_action( 'plugins_loaded' ) ) { - load_tgm_plugin_activation(); - } else { - add_action( 'plugins_loaded', 'load_tgm_plugin_activation' ); - } -} - -if ( ! function_exists( 'tgmpa' ) ) { - /** - * Helper function to register a collection of required plugins. - * - * @since 2.0.0 - * @api - * - * @param array $plugins An array of plugin arrays. - * @param array $config Optional. An array of configuration values. - */ - function tgmpa( $plugins, $config = array() ) { - $instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - - foreach ( $plugins as $plugin ) { - call_user_func( array( $instance, 'register' ), $plugin ); - } - - if ( ! empty( $config ) && is_array( $config ) ) { - // Send out notices for deprecated arguments passed. - if ( isset( $config['notices'] ) ) { - _deprecated_argument( __FUNCTION__, '2.2.0', 'The `notices` config parameter was renamed to `has_notices` in TGMPA 2.2.0. Please adjust your configuration.' ); - if ( ! isset( $config['has_notices'] ) ) { - $config['has_notices'] = $config['notices']; - } - } - - if ( isset( $config['parent_menu_slug'] ) ) { - _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_menu_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' ); - } - if ( isset( $config['parent_url_slug'] ) ) { - _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_url_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' ); - } - - call_user_func( array( $instance, 'config' ), $config ); - } - } -} - -/** - * WP_List_Table isn't always available. If it isn't available, - * we load it here. - * - * @since 2.2.0 - */ -if ( ! class_exists( 'WP_List_Table' ) ) { - require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; -} - -if ( ! class_exists( 'TGMPA_List_Table' ) ) { - - /** - * List table class for handling plugins. - * - * Extends the WP_List_Table class to provide a future-compatible - * way of listing out all required/recommended plugins. - * - * Gives users an interface similar to the Plugin Administration - * area with similar (albeit stripped down) capabilities. - * - * This class also allows for the bulk install of plugins. - * - * @since 2.2.0 - * - * @package TGM-Plugin-Activation - * @author Thomas Griffin - * @author Gary Jones - */ - class TGMPA_List_Table extends WP_List_Table { - /** - * TGMPA instance. - * - * @since 2.5.0 - * - * @var object - */ - protected $tgmpa; - - /** - * The currently chosen view. - * - * @since 2.5.0 - * - * @var string One of: 'all', 'install', 'update', 'activate' - */ - public $view_context = 'all'; - - /** - * The plugin counts for the various views. - * - * @since 2.5.0 - * - * @var array - */ - protected $view_totals = array( - 'all' => 0, - 'install' => 0, - 'update' => 0, - 'activate' => 0, - ); - - /** - * References parent constructor and sets defaults for class. - * - * @since 2.2.0 - */ - public function __construct() { - $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - - parent::__construct( - array( - 'singular' => 'plugin', - 'plural' => 'plugins', - 'ajax' => false, - ) - ); - - if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'install', 'update', 'activate' ), true ) ) { - $this->view_context = sanitize_key( $_REQUEST['plugin_status'] ); - } - - add_filter( 'tgmpa_table_data_items', array( $this, 'sort_table_items' ) ); - } - - /** - * Get a list of CSS classes for the tag. - * - * Overruled to prevent the 'plural' argument from being added. - * - * @since 2.5.0 - * - * @return array CSS classnames. - */ - public function get_table_classes() { - return array( 'widefat', 'fixed' ); - } - - /** - * Gathers and renames all of our plugin information to be used by WP_List_Table to create our table. - * - * @since 2.2.0 - * - * @return array $table_data Information for use in table. - */ - protected function _gather_plugin_data() { - // Load thickbox for plugin links. - $this->tgmpa->admin_init(); - $this->tgmpa->thickbox(); - - // Categorize the plugins which have open actions. - $plugins = $this->categorize_plugins_to_views(); - - // Set the counts for the view links. - $this->set_view_totals( $plugins ); - - // Prep variables for use and grab list of all installed plugins. - $table_data = array(); - $i = 0; - - // Redirect to the 'all' view if no plugins were found for the selected view context. - if ( empty( $plugins[ $this->view_context ] ) ) { - $this->view_context = 'all'; - } - - foreach ( $plugins[ $this->view_context ] as $slug => $plugin ) { - $table_data[ $i ]['sanitized_plugin'] = $plugin['name']; - $table_data[ $i ]['slug'] = $slug; - $table_data[ $i ]['plugin'] = '' . $this->tgmpa->get_info_link( $slug ) . ''; - $table_data[ $i ]['source'] = $this->get_plugin_source_type_text( $plugin['source_type'] ); - $table_data[ $i ]['type'] = $this->get_plugin_advise_type_text( $plugin['required'] ); - $table_data[ $i ]['status'] = $this->get_plugin_status_text( $slug ); - $table_data[ $i ]['installed_version'] = $this->tgmpa->get_installed_version( $slug ); - $table_data[ $i ]['minimum_version'] = $plugin['version']; - $table_data[ $i ]['available_version'] = $this->tgmpa->does_plugin_have_update( $slug ); - - // Prep the upgrade notice info. - $upgrade_notice = $this->tgmpa->get_upgrade_notice( $slug ); - if ( ! empty( $upgrade_notice ) ) { - $table_data[ $i ]['upgrade_notice'] = $upgrade_notice; - - add_action( "tgmpa_after_plugin_row_{$slug}", array( $this, 'wp_plugin_update_row' ), 10, 2 ); - } - - $table_data[ $i ] = apply_filters( 'tgmpa_table_data_item', $table_data[ $i ], $plugin ); - - $i++; - } - - return $table_data; - } - - /** - * Categorize the plugins which have open actions into views for the TGMPA page. - * - * @since 2.5.0 - */ - protected function categorize_plugins_to_views() { - $plugins = array( - 'all' => array(), // Meaning: all plugins which still have open actions. - 'install' => array(), - 'update' => array(), - 'activate' => array(), - ); - - foreach ( $this->tgmpa->plugins as $slug => $plugin ) { - if ( $this->tgmpa->is_plugin_active( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) { - // No need to display plugins if they are installed, up-to-date and active. - continue; - } else { - $plugins['all'][ $slug ] = $plugin; - - if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) { - $plugins['install'][ $slug ] = $plugin; - } else { - if ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) { - $plugins['update'][ $slug ] = $plugin; - } - - if ( $this->tgmpa->can_plugin_activate( $slug ) ) { - $plugins['activate'][ $slug ] = $plugin; - } - } - } - } - - return $plugins; - } - - /** - * Set the counts for the view links. - * - * @since 2.5.0 - * - * @param array $plugins Plugins order by view. - */ - protected function set_view_totals( $plugins ) { - foreach ( $plugins as $type => $list ) { - $this->view_totals[ $type ] = count( $list ); - } - } - - /** - * Get the plugin required/recommended text string. - * - * @since 2.5.0 - * - * @param string $required Plugin required setting. - * @return string - */ - protected function get_plugin_advise_type_text( $required ) { - if ( true === $required ) { - return __( 'Required', 'craftnce' ); - } - - return __( 'Recommended', 'craftnce' ); - } - - /** - * Get the plugin source type text string. - * - * @since 2.5.0 - * - * @param string $type Plugin type. - * @return string - */ - protected function get_plugin_source_type_text( $type ) { - $string = ''; - - switch ( $type ) { - case 'repo': - $string = __( 'WordPress Repository', 'craftnce' ); - break; - case 'external': - $string = __( 'External Source', 'craftnce' ); - break; - case 'bundled': - $string = __( 'Pre-Packaged', 'craftnce' ); - break; - } - - return $string; - } - - /** - * Determine the plugin status message. - * - * @since 2.5.0 - * - * @param string $slug Plugin slug. - * @return string - */ - protected function get_plugin_status_text( $slug ) { - if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) { - return __( 'Not Installed', 'craftnce' ); - } - - if ( ! $this->tgmpa->is_plugin_active( $slug ) ) { - $install_status = __( 'Installed But Not Activated', 'craftnce' ); - } else { - $install_status = __( 'Active', 'craftnce' ); - } - - $update_status = ''; - - if ( $this->tgmpa->does_plugin_require_update( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) { - $update_status = __( 'Required Update not Available', 'craftnce' ); - - } elseif ( $this->tgmpa->does_plugin_require_update( $slug ) ) { - $update_status = __( 'Requires Update', 'craftnce' ); - - } elseif ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) { - $update_status = __( 'Update recommended', 'craftnce' ); - } - - if ( '' === $update_status ) { - return $install_status; - } - - return sprintf( - /* translators: 1: install status, 2: update status */ - _x( '%1$s, %2$s', 'Install/Update Status', 'craftnce' ), - $install_status, - $update_status - ); - } - - /** - * Sort plugins by Required/Recommended type and by alphabetical plugin name within each type. - * - * @since 2.5.0 - * - * @param array $items Prepared table items. - * @return array Sorted table items. - */ - public function sort_table_items( $items ) { - $type = array(); - $name = array(); - - foreach ( $items as $i => $plugin ) { - $type[ $i ] = $plugin['type']; // Required / recommended. - $name[ $i ] = $plugin['sanitized_plugin']; - } - - array_multisort( $type, SORT_DESC, $name, SORT_ASC, $items ); - - return $items; - } - - /** - * Get an associative array ( id => link ) of the views available on this table. - * - * @since 2.5.0 - * - * @return array - */ - public function get_views() { - $status_links = array(); - - foreach ( $this->view_totals as $type => $count ) { - if ( $count < 1 ) { - continue; - } - - switch ( $type ) { - case 'all': - /* translators: 1: number of plugins. */ - $text = _nx( 'All (%s)', 'All (%s)', $count, 'plugins', 'craftnce' ); - break; - case 'install': - /* translators: 1: number of plugins. */ - $text = _n( 'To Install (%s)', 'To Install (%s)', $count, 'craftnce' ); - break; - case 'update': - /* translators: 1: number of plugins. */ - $text = _n( 'Update Available (%s)', 'Update Available (%s)', $count, 'craftnce' ); - break; - case 'activate': - /* translators: 1: number of plugins. */ - $text = _n( 'To Activate (%s)', 'To Activate (%s)', $count, 'craftnce' ); - break; - default: - $text = ''; - break; - } - - if ( ! empty( $text ) ) { - - $status_links[ $type ] = sprintf( - '%s', - esc_url( $this->tgmpa->get_tgmpa_status_url( $type ) ), - ( $type === $this->view_context ) ? ' class="current"' : '', - sprintf( $text, number_format_i18n( $count ) ) - ); - } - } - - return $status_links; - } - - /** - * Create default columns to display important plugin information - * like type, action and status. - * - * @since 2.2.0 - * - * @param array $item Array of item data. - * @param string $column_name The name of the column. - * @return string - */ - public function column_default( $item, $column_name ) { - return $item[ $column_name ]; - } - - /** - * Required for bulk installing. - * - * Adds a checkbox for each plugin. - * - * @since 2.2.0 - * - * @param array $item Array of item data. - * @return string The input checkbox with all necessary info. - */ - public function column_cb( $item ) { - return sprintf( - '', - esc_attr( $this->_args['singular'] ), - esc_attr( $item['slug'] ), - esc_attr( $item['sanitized_plugin'] ) - ); - } - - /** - * Create default title column along with the action links. - * - * @since 2.2.0 - * - * @param array $item Array of item data. - * @return string The plugin name and action links. - */ - public function column_plugin( $item ) { - return sprintf( - '%1$s %2$s', - $item['plugin'], - $this->row_actions( $this->get_row_actions( $item ), true ) - ); - } - - /** - * Create version information column. - * - * @since 2.5.0 - * - * @param array $item Array of item data. - * @return string HTML-formatted version information. - */ - public function column_version( $item ) { - $output = array(); - - if ( $this->tgmpa->is_plugin_installed( $item['slug'] ) ) { - $installed = ! empty( $item['installed_version'] ) ? $item['installed_version'] : _x( 'unknown', 'as in: "version nr unknown"', 'craftnce' ); - - $color = ''; - if ( ! empty( $item['minimum_version'] ) && $this->tgmpa->does_plugin_require_update( $item['slug'] ) ) { - $color = ' color: #ff0000; font-weight: bold;'; - } - - $output[] = sprintf( - '

%2$s' . __( 'Installed version:', 'craftnce' ) . '

', - $color, - $installed - ); - } - - if ( ! empty( $item['minimum_version'] ) ) { - $output[] = sprintf( - '

%1$s' . __( 'Minimum required version:', 'craftnce' ) . '

', - $item['minimum_version'] - ); - } - - if ( ! empty( $item['available_version'] ) ) { - $color = ''; - if ( ! empty( $item['minimum_version'] ) && version_compare( $item['available_version'], $item['minimum_version'], '>=' ) ) { - $color = ' color: #71C671; font-weight: bold;'; - } - - $output[] = sprintf( - '

%2$s' . __( 'Available version:', 'craftnce' ) . '

', - $color, - $item['available_version'] - ); - } - - if ( empty( $output ) ) { - return ' '; // Let's not break the table layout. - } else { - return implode( "\n", $output ); - } - } - - /** - * Sets default message within the plugins table if no plugins - * are left for interaction. - * - * Hides the menu item to prevent the user from clicking and - * getting a permissions error. - * - * @since 2.2.0 - */ - public function no_items() { - echo esc_html__( 'No plugins to install, update or activate.', 'craftnce' ) . ' ' . esc_html__( 'Return to the Dashboard', 'craftnce' ) . ''; - echo ''; - } - - /** - * Output all the column information within the table. - * - * @since 2.2.0 - * - * @return array $columns The column names. - */ - public function get_columns() { - $columns = array( - 'cb' => '', - 'plugin' => __( 'Plugin', 'craftnce' ), - 'source' => __( 'Source', 'craftnce' ), - 'type' => __( 'Type', 'craftnce' ), - ); - - if ( 'all' === $this->view_context || 'update' === $this->view_context ) { - $columns['version'] = __( 'Version', 'craftnce' ); - $columns['status'] = __( 'Status', 'craftnce' ); - } - - return apply_filters( 'tgmpa_table_columns', $columns ); - } - - /** - * Get name of default primary column - * - * @since 2.5.0 / WP 4.3+ compatibility - * @access protected - * - * @return string - */ - protected function get_default_primary_column_name() { - return 'plugin'; - } - - /** - * Get the name of the primary column. - * - * @since 2.5.0 / WP 4.3+ compatibility - * @access protected - * - * @return string The name of the primary column. - */ - protected function get_primary_column_name() { - if ( method_exists( 'WP_List_Table', 'get_primary_column_name' ) ) { - return parent::get_primary_column_name(); - } else { - return $this->get_default_primary_column_name(); - } - } - - /** - * Get the actions which are relevant for a specific plugin row. - * - * @since 2.5.0 - * - * @param array $item Array of item data. - * @return array Array with relevant action links. - */ - protected function get_row_actions( $item ) { - $actions = array(); - $action_links = array(); - - // Display the 'Install' action link if the plugin is not yet available. - if ( ! $this->tgmpa->is_plugin_installed( $item['slug'] ) ) { - /* translators: %2$s: plugin name in screen reader markup */ - $actions['install'] = __( 'Install %2$s', 'craftnce' ); - } else { - // Display the 'Update' action link if an update is available and WP complies with plugin minimum. - if ( false !== $this->tgmpa->does_plugin_have_update( $item['slug'] ) && $this->tgmpa->can_plugin_update( $item['slug'] ) ) { - /* translators: %2$s: plugin name in screen reader markup */ - $actions['update'] = __( 'Update %2$s', 'craftnce' ); - } - - // Display the 'Activate' action link, but only if the plugin meets the minimum version. - if ( $this->tgmpa->can_plugin_activate( $item['slug'] ) ) { - /* translators: %2$s: plugin name in screen reader markup */ - $actions['activate'] = __( 'Activate %2$s', 'craftnce' ); - } - } - - // Create the actual links. - foreach ( $actions as $action => $text ) { - $nonce_url = wp_nonce_url( - add_query_arg( - array( - 'plugin' => urlencode( $item['slug'] ), - 'tgmpa-' . $action => $action . '-plugin', - ), - $this->tgmpa->get_tgmpa_url() - ), - 'tgmpa-' . $action, - 'tgmpa-nonce' - ); - - $action_links[ $action ] = sprintf( - '' . esc_html( $text ) . '', // $text contains the second placeholder. - esc_url( $nonce_url ), - '' . esc_html( $item['sanitized_plugin'] ) . '' - ); - } - - $prefix = ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN ) ? 'network_admin_' : ''; - return apply_filters( "tgmpa_{$prefix}plugin_action_links", array_filter( $action_links ), $item['slug'], $item, $this->view_context ); - } - - /** - * Generates content for a single row of the table. - * - * @since 2.5.0 - * - * @param object $item The current item. - */ - public function single_row( $item ) { - parent::single_row( $item ); - - /** - * Fires after each specific row in the TGMPA Plugins list table. - * - * The dynamic portion of the hook name, `$item['slug']`, refers to the slug - * for the plugin. - * - * @since 2.5.0 - */ - do_action( "tgmpa_after_plugin_row_{$item['slug']}", $item['slug'], $item, $this->view_context ); - } - - /** - * Show the upgrade notice below a plugin row if there is one. - * - * @since 2.5.0 - * - * @see /wp-admin/includes/update.php - * - * @param string $slug Plugin slug. - * @param array $item The information available in this table row. - * @return null Return early if upgrade notice is empty. - */ - public function wp_plugin_update_row( $slug, $item ) { - if ( empty( $item['upgrade_notice'] ) ) { - return; - } - - echo ' - - - '; - } - - /** - * Extra controls to be displayed between bulk actions and pagination. - * - * @since 2.5.0 - * - * @param string $which 'top' or 'bottom' table navigation. - */ - public function extra_tablenav( $which ) { - if ( 'bottom' === $which ) { - $this->tgmpa->show_tgmpa_version(); - } - } - - /** - * Defines the bulk actions for handling registered plugins. - * - * @since 2.2.0 - * - * @return array $actions The bulk actions for the plugin install table. - */ - public function get_bulk_actions() { - - $actions = array(); - - if ( 'update' !== $this->view_context && 'activate' !== $this->view_context ) { - if ( current_user_can( 'install_plugins' ) ) { - $actions['tgmpa-bulk-install'] = __( 'Install', 'craftnce' ); - } - } - - if ( 'install' !== $this->view_context ) { - if ( current_user_can( 'update_plugins' ) ) { - $actions['tgmpa-bulk-update'] = __( 'Update', 'craftnce' ); - } - if ( current_user_can( 'activate_plugins' ) ) { - $actions['tgmpa-bulk-activate'] = __( 'Activate', 'craftnce' ); - } - } - - return $actions; - } - - /** - * Processes bulk installation and activation actions. - * - * The bulk installation process looks for the $_POST information and passes that - * through if a user has to use WP_Filesystem to enter their credentials. - * - * @since 2.2.0 - */ - public function process_bulk_actions() { - // Bulk installation process. - if ( 'tgmpa-bulk-install' === $this->current_action() || 'tgmpa-bulk-update' === $this->current_action() ) { - - check_admin_referer( 'bulk-' . $this->_args['plural'] ); - - $install_type = 'install'; - if ( 'tgmpa-bulk-update' === $this->current_action() ) { - $install_type = 'update'; - } - - $plugins_to_install = array(); - - // Did user actually select any plugins to install/update ? - if ( empty( $_POST['plugin'] ) ) { - if ( 'install' === $install_type ) { - $message = __( 'No plugins were selected to be installed. No action taken.', 'craftnce' ); - } else { - $message = __( 'No plugins were selected to be updated. No action taken.', 'craftnce' ); - } - - echo '

', esc_html( $message ), '

'; - - return false; - } - - if ( is_array( $_POST['plugin'] ) ) { - $plugins_to_install = (array) $_POST['plugin']; - } elseif ( is_string( $_POST['plugin'] ) ) { - // Received via Filesystem page - un-flatten array (WP bug #19643). - $plugins_to_install = explode( ',', $_POST['plugin'] ); - } - - // Sanitize the received input. - $plugins_to_install = array_map( 'urldecode', $plugins_to_install ); - $plugins_to_install = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins_to_install ); - - // Validate the received input. - foreach ( $plugins_to_install as $key => $slug ) { - // Check if the plugin was registered with TGMPA and remove if not. - if ( ! isset( $this->tgmpa->plugins[ $slug ] ) ) { - unset( $plugins_to_install[ $key ] ); - continue; - } - - // For install: make sure this is a plugin we *can* install and not one already installed. - if ( 'install' === $install_type && true === $this->tgmpa->is_plugin_installed( $slug ) ) { - unset( $plugins_to_install[ $key ] ); - } - - // For updates: make sure this is a plugin we *can* update (update available and WP version ok). - if ( 'update' === $install_type && false === $this->tgmpa->is_plugin_updatetable( $slug ) ) { - unset( $plugins_to_install[ $key ] ); - } - } - - // No need to proceed further if we have no plugins to handle. - if ( empty( $plugins_to_install ) ) { - if ( 'install' === $install_type ) { - $message = __( 'No plugins are available to be installed at this time.', 'craftnce' ); - } else { - $message = __( 'No plugins are available to be updated at this time.', 'craftnce' ); - } - - echo '

', esc_html( $message ), '

'; - - return false; - } - - // Pass all necessary information if WP_Filesystem is needed. - $url = wp_nonce_url( - $this->tgmpa->get_tgmpa_url(), - 'bulk-' . $this->_args['plural'] - ); - - // Give validated data back to $_POST which is the only place the filesystem looks for extra fields. - $_POST['plugin'] = implode( ',', $plugins_to_install ); // Work around for WP bug #19643. - - $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. - $fields = array_keys( $_POST ); // Extra fields to pass to WP_Filesystem. - - if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, $fields ) ) ) { - return true; // Stop the normal page form from displaying, credential request form will be shown. - } - - // Now we have some credentials, setup WP_Filesystem. - if ( ! WP_Filesystem( $creds ) ) { - // Our credentials were no good, ask the user for them again. - request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, $fields ); - - return true; - } - - /* If we arrive here, we have the filesystem */ - - // Store all information in arrays since we are processing a bulk installation. - $names = array(); - $sources = array(); // Needed for installs. - $file_paths = array(); // Needed for upgrades. - $to_inject = array(); // Information to inject into the update_plugins transient. - - // Prepare the data for validated plugins for the install/upgrade. - foreach ( $plugins_to_install as $slug ) { - $name = $this->tgmpa->plugins[ $slug ]['name']; - $source = $this->tgmpa->get_download_url( $slug ); - - if ( ! empty( $name ) && ! empty( $source ) ) { - $names[] = $name; - - switch ( $install_type ) { - - case 'install': - $sources[] = $source; - break; - - case 'update': - $file_paths[] = $this->tgmpa->plugins[ $slug ]['file_path']; - $to_inject[ $slug ] = $this->tgmpa->plugins[ $slug ]; - $to_inject[ $slug ]['source'] = $source; - break; - } - } - } - unset( $slug, $name, $source ); - - // Create a new instance of TGMPA_Bulk_Installer. - $installer = new TGMPA_Bulk_Installer( - new TGMPA_Bulk_Installer_Skin( - array( - 'url' => esc_url_raw( $this->tgmpa->get_tgmpa_url() ), - 'nonce' => 'bulk-' . $this->_args['plural'], - 'names' => $names, - 'install_type' => $install_type, - ) - ) - ); - - // Wrap the install process with the appropriate HTML. - echo '
', - '

', esc_html( get_admin_page_title() ), '

-
'; - - // Process the bulk installation submissions. - add_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 ); - - if ( 'tgmpa-bulk-update' === $this->current_action() ) { - // Inject our info into the update transient. - $this->tgmpa->inject_update_info( $to_inject ); - - $installer->bulk_upgrade( $file_paths ); - } else { - $installer->bulk_install( $sources ); - } - - remove_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1 ); - - echo '
'; - - return true; - } - - // Bulk activation process. - if ( 'tgmpa-bulk-activate' === $this->current_action() ) { - check_admin_referer( 'bulk-' . $this->_args['plural'] ); - - // Did user actually select any plugins to activate ? - if ( empty( $_POST['plugin'] ) ) { - echo '

', esc_html__( 'No plugins were selected to be activated. No action taken.', 'craftnce' ), '

'; - - return false; - } - - // Grab plugin data from $_POST. - $plugins = array(); - if ( isset( $_POST['plugin'] ) ) { - $plugins = array_map( 'urldecode', (array) $_POST['plugin'] ); - $plugins = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins ); - } - - $plugins_to_activate = array(); - $plugin_names = array(); - - // Grab the file paths for the selected & inactive plugins from the registration array. - foreach ( $plugins as $slug ) { - if ( $this->tgmpa->can_plugin_activate( $slug ) ) { - $plugins_to_activate[] = $this->tgmpa->plugins[ $slug ]['file_path']; - $plugin_names[] = $this->tgmpa->plugins[ $slug ]['name']; - } - } - unset( $slug ); - - // Return early if there are no plugins to activate. - if ( empty( $plugins_to_activate ) ) { - echo '

', esc_html__( 'No plugins are available to be activated at this time.', 'craftnce' ), '

'; - - return false; - } - - // Now we are good to go - let's start activating plugins. - $activate = activate_plugins( $plugins_to_activate ); - - if ( is_wp_error( $activate ) ) { - echo '

', wp_kses_post( $activate->get_error_message() ), '

'; - } else { - $count = count( $plugin_names ); // Count so we can use _n function. - $plugin_names = array_map( array( 'TGMPA_Utils', 'wrap_in_strong' ), $plugin_names ); - $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability. - $imploded = empty( $plugin_names ) ? $last_plugin : ( implode( ', ', $plugin_names ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'craftnce' ) . ' ' . $last_plugin ); - - printf( // WPCS: xss ok. - '

%1$s %2$s.

', - esc_html( _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'craftnce' ) ), - $imploded - ); - - // Update recently activated plugins option. - $recent = (array) get_option( 'recently_activated' ); - foreach ( $plugins_to_activate as $plugin => $time ) { - if ( isset( $recent[ $plugin ] ) ) { - unset( $recent[ $plugin ] ); - } - } - update_option( 'recently_activated', $recent ); - } - - unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another. - - return true; - } - - return false; - } - - /** - * Prepares all of our information to be outputted into a usable table. - * - * @since 2.2.0 - */ - public function prepare_items() { - $columns = $this->get_columns(); // Get all necessary column information. - $hidden = array(); // No columns to hide, but we must set as an array. - $sortable = array(); // No reason to make sortable columns. - $primary = $this->get_primary_column_name(); // Column which has the row actions. - $this->_column_headers = array( $columns, $hidden, $sortable, $primary ); // Get all necessary column headers. - - // Process our bulk activations here. - if ( 'tgmpa-bulk-activate' === $this->current_action() ) { - $this->process_bulk_actions(); - } - - // Store all of our plugin data into $items array so WP_List_Table can use it. - $this->items = apply_filters( 'tgmpa_table_data_items', $this->_gather_plugin_data() ); - } - - /* *********** DEPRECATED METHODS *********** */ - - /** - * Retrieve plugin data, given the plugin name. - * - * @since 2.2.0 - * @deprecated 2.5.0 use {@see TGM_Plugin_Activation::_get_plugin_data_from_name()} instead. - * @see TGM_Plugin_Activation::_get_plugin_data_from_name() - * - * @param string $name Name of the plugin, as it was registered. - * @param string $data Optional. Array key of plugin data to return. Default is slug. - * @return string|boolean Plugin slug if found, false otherwise. - */ - protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { - _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'TGM_Plugin_Activation::_get_plugin_data_from_name()' ); - - return $this->tgmpa->_get_plugin_data_from_name( $name, $data ); - } - } -} - - -if ( ! class_exists( 'TGM_Bulk_Installer' ) ) { - - /** - * Hack: Prevent TGMPA v2.4.1- bulk installer class from being loaded if 2.4.1- is loaded after 2.5+. - * - * @since 2.5.2 - * - * {@internal The TGMPA_Bulk_Installer class was originally called TGM_Bulk_Installer. - * For more information, see that class.}} - */ - class TGM_Bulk_Installer { - } -} -if ( ! class_exists( 'TGM_Bulk_Installer_Skin' ) ) { - - /** - * Hack: Prevent TGMPA v2.4.1- bulk installer skin class from being loaded if 2.4.1- is loaded after 2.5+. - * - * @since 2.5.2 - * - * {@internal The TGMPA_Bulk_Installer_Skin class was originally called TGM_Bulk_Installer_Skin. - * For more information, see that class.}} - */ - class TGM_Bulk_Installer_Skin { - } -} - -/** - * The WP_Upgrader file isn't always available. If it isn't available, - * we load it here. - * - * We check to make sure no action or activation keys are set so that WordPress - * does not try to re-include the class when processing upgrades or installs outside - * of the class. - * - * @since 2.2.0 - */ -add_action( 'admin_init', 'tgmpa_load_bulk_installer' ); -if ( ! function_exists( 'tgmpa_load_bulk_installer' ) ) { - /** - * Load bulk installer - */ - function tgmpa_load_bulk_installer() { - // Silently fail if 2.5+ is loaded *after* an older version. - if ( ! isset( $GLOBALS['tgmpa'] ) ) { - return; - } - - // Get TGMPA class instance. - $tgmpa_instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - - if ( isset( $_GET['page'] ) && $tgmpa_instance->menu === $_GET['page'] ) { - if ( ! class_exists( 'Plugin_Upgrader', false ) ) { - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; - } - - if ( ! class_exists( 'TGMPA_Bulk_Installer' ) ) { - - /** - * Installer class to handle bulk plugin installations. - * - * Extends WP_Upgrader and customizes to suit the installation of multiple - * plugins. - * - * @since 2.2.0 - * - * {@internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader.}} - * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer. - * This was done to prevent backward compatibility issues with v2.3.6.}} - * - * @package TGM-Plugin-Activation - * @author Thomas Griffin - * @author Gary Jones - */ - class TGMPA_Bulk_Installer extends Plugin_Upgrader { - /** - * Holds result of bulk plugin installation. - * - * @since 2.2.0 - * - * @var string - */ - public $result; - - /** - * Flag to check if bulk installation is occurring or not. - * - * @since 2.2.0 - * - * @var boolean - */ - public $bulk = false; - - /** - * TGMPA instance - * - * @since 2.5.0 - * - * @var object - */ - protected $tgmpa; - - /** - * Whether or not the destination directory needs to be cleared ( = on update). - * - * @since 2.5.0 - * - * @var bool - */ - protected $clear_destination = false; - - /** - * References parent constructor and sets defaults for class. - * - * @since 2.2.0 - * - * @param \Bulk_Upgrader_Skin|null $skin Installer skin. - */ - public function __construct( $skin = null ) { - // Get TGMPA class instance. - $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - - parent::__construct( $skin ); - - if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) { - $this->clear_destination = true; - } - - if ( $this->tgmpa->is_automatic ) { - $this->activate_strings(); - } - - add_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) ); - } - - /** - * Sets the correct activation strings for the installer skin to use. - * - * @since 2.2.0 - */ - public function activate_strings() { - $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'craftnce' ); - $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'craftnce' ); - } - - /** - * Performs the actual installation of each plugin. - * - * @since 2.2.0 - * - * @see WP_Upgrader::run() - * - * @param array $options The installation config options. - * @return null|array Return early if error, array of installation data on success. - */ - public function run( $options ) { - $result = parent::run( $options ); - - // Reset the strings in case we changed one during automatic activation. - if ( $this->tgmpa->is_automatic ) { - if ( 'update' === $this->skin->options['install_type'] ) { - $this->upgrade_strings(); - } else { - $this->install_strings(); - } - } - - return $result; - } - - /** - * Processes the bulk installation of plugins. - * - * @since 2.2.0 - * - * {@internal This is basically a near identical copy of the WP Core - * Plugin_Upgrader::bulk_upgrade() method, with minor adjustments to deal with - * new installs instead of upgrades. - * For ease of future synchronizations, the adjustments are clearly commented, but no other - * comments are added. Code style has been made to comply.}} - * - * @see Plugin_Upgrader::bulk_upgrade() - * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838 - * (@internal Last synced: Dec 31st 2015 against https://core.trac.wordpress.org/browser/trunk?rev=36134}} - * - * @param array $plugins The plugin sources needed for installation. - * @param array $args Arbitrary passed extra arguments. - * @return array|false Install confirmation messages on success, false on failure. - */ - public function bulk_install( $plugins, $args = array() ) { - // [TGMPA + ] Hook auto-activation in. - add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - - $defaults = array( - 'clear_update_cache' => true, - ); - $parsed_args = wp_parse_args( $args, $defaults ); - - $this->init(); - $this->bulk = true; - - $this->install_strings(); // [TGMPA + ] adjusted. - - /* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */ - - /* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */ - - $this->skin->header(); - - // Connect to the Filesystem first. - $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); - if ( ! $res ) { - $this->skin->footer(); - return false; - } - - $this->skin->bulk_header(); - - /* - * Only start maintenance mode if: - * - running Multisite and there are one or more plugins specified, OR - * - a plugin with an update available is currently active. - * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. - */ - $maintenance = ( is_multisite() && ! empty( $plugins ) ); - - /* - [TGMPA - ] - foreach ( $plugins as $plugin ) - $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) ); - */ - if ( $maintenance ) { - $this->maintenance_mode( true ); - } - - $results = array(); - - $this->update_count = count( $plugins ); - $this->update_current = 0; - foreach ( $plugins as $plugin ) { - $this->update_current++; - - /* - [TGMPA - ] - $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true); - - if ( !isset( $current->response[ $plugin ] ) ) { - $this->skin->set_result('up_to_date'); - $this->skin->before(); - $this->skin->feedback('up_to_date'); - $this->skin->after(); - $results[$plugin] = true; - continue; - } - - // Get the URL to the zip file. - $r = $current->response[ $plugin ]; - - $this->skin->plugin_active = is_plugin_active($plugin); - */ - - $result = $this->run( - array( - 'package' => $plugin, // [TGMPA + ] adjusted. - 'destination' => WP_PLUGIN_DIR, - 'clear_destination' => false, // [TGMPA + ] adjusted. - 'clear_working' => true, - 'is_multi' => true, - 'hook_extra' => array( - 'plugin' => $plugin, - ), - ) - ); - - $results[ $plugin ] = $this->result; - - // Prevent credentials auth screen from displaying multiple times. - if ( false === $result ) { - break; - } - } //end foreach $plugins - - $this->maintenance_mode( false ); - - /** - * Fires when the bulk upgrader process is complete. - * - * @since WP 3.6.0 / TGMPA 2.5.0 - * - * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might - * be a Theme_Upgrader or Core_Upgrade instance. - * @param array $data { - * Array of bulk item update data. - * - * @type string $action Type of action. Default 'update'. - * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. - * @type bool $bulk Whether the update process is a bulk update. Default true. - * @type array $packages Array of plugin, theme, or core packages to update. - * } - */ - do_action( 'upgrader_process_complete', $this, array( - 'action' => 'install', // [TGMPA + ] adjusted. - 'type' => 'plugin', - 'bulk' => true, - 'plugins' => $plugins, - ) ); - - $this->skin->bulk_footer(); - - $this->skin->footer(); - - // Cleanup our hooks, in case something else does a upgrade on this connection. - /* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */ - - // [TGMPA + ] Remove our auto-activation hook. - remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - - // Force refresh of plugin update information. - wp_clean_plugins_cache( $parsed_args['clear_update_cache'] ); - - return $results; - } - - /** - * Handle a bulk upgrade request. - * - * @since 2.5.0 - * - * @see Plugin_Upgrader::bulk_upgrade() - * - * @param array $plugins The local WP file_path's of the plugins which should be upgraded. - * @param array $args Arbitrary passed extra arguments. - * @return string|bool Install confirmation messages on success, false on failure. - */ - public function bulk_upgrade( $plugins, $args = array() ) { - - add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - - $result = parent::bulk_upgrade( $plugins, $args ); - - remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - - return $result; - } - - /** - * Abuse a filter to auto-activate plugins after installation. - * - * Hooked into the 'upgrader_post_install' filter hook. - * - * @since 2.5.0 - * - * @param bool $bool The value we need to give back (true). - * @return bool - */ - public function auto_activate( $bool ) { - // Only process the activation of installed plugins if the automatic flag is set to true. - if ( $this->tgmpa->is_automatic ) { - // Flush plugins cache so the headers of the newly installed plugins will be read correctly. - wp_clean_plugins_cache(); - - // Get the installed plugin file. - $plugin_info = $this->plugin_info(); - - // Don't try to activate on upgrade of active plugin as WP will do this already. - if ( ! is_plugin_active( $plugin_info ) ) { - $activate = activate_plugin( $plugin_info ); - - // Adjust the success string based on the activation result. - $this->strings['process_success'] = $this->strings['process_success'] . "
\n"; - - if ( is_wp_error( $activate ) ) { - $this->skin->error( $activate ); - $this->strings['process_success'] .= $this->strings['activation_failed']; - } else { - $this->strings['process_success'] .= $this->strings['activation_success']; - } - } - } - - return $bool; - } - } - } - - if ( ! class_exists( 'TGMPA_Bulk_Installer_Skin' ) ) { - - /** - * Installer skin to set strings for the bulk plugin installations.. - * - * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple - * plugins. - * - * @since 2.2.0 - * - * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to - * TGMPA_Bulk_Installer_Skin. - * This was done to prevent backward compatibility issues with v2.3.6.}} - * - * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php - * - * @package TGM-Plugin-Activation - * @author Thomas Griffin - * @author Gary Jones - */ - class TGMPA_Bulk_Installer_Skin extends Bulk_Upgrader_Skin { - /** - * Holds plugin info for each individual plugin installation. - * - * @since 2.2.0 - * - * @var array - */ - public $plugin_info = array(); - - /** - * Holds names of plugins that are undergoing bulk installations. - * - * @since 2.2.0 - * - * @var array - */ - public $plugin_names = array(); - - /** - * Integer to use for iteration through each plugin installation. - * - * @since 2.2.0 - * - * @var integer - */ - public $i = 0; - - /** - * TGMPA instance - * - * @since 2.5.0 - * - * @var object - */ - protected $tgmpa; - - /** - * Constructor. Parses default args with new ones and extracts them for use. - * - * @since 2.2.0 - * - * @param array $args Arguments to pass for use within the class. - */ - public function __construct( $args = array() ) { - // Get TGMPA class instance. - $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - - // Parse default and new args. - $defaults = array( - 'url' => '', - 'nonce' => '', - 'names' => array(), - 'install_type' => 'install', - ); - $args = wp_parse_args( $args, $defaults ); - - // Set plugin names to $this->plugin_names property. - $this->plugin_names = $args['names']; - - // Extract the new args. - parent::__construct( $args ); - } - - /** - * Sets install skin strings for each individual plugin. - * - * Checks to see if the automatic activation flag is set and uses the - * the proper strings accordingly. - * - * @since 2.2.0 - */ - public function add_strings() { - if ( 'update' === $this->options['install_type'] ) { - parent::add_strings(); - /* translators: 1: plugin name, 2: action number 3: total number of actions. */ - $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'craftnce' ); - } else { - /* translators: 1: plugin name, 2: error message. */ - $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'craftnce' ); - /* translators: 1: plugin name. */ - $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'craftnce' ); - - if ( $this->tgmpa->is_automatic ) { - // Automatic activation strings. - $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'craftnce' ); - /* translators: 1: plugin name. */ - $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'craftnce' ) . ' ' . esc_html__( 'Show Details', 'craftnce' ) . '.'; - $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'craftnce' ); - /* translators: 1: plugin name, 2: action number 3: total number of actions. */ - $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'craftnce' ); - } else { - // Default installation strings. - $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'craftnce' ); - /* translators: 1: plugin name. */ - $this->upgrader->strings['skin_update_successful'] = esc_html__( '%1$s installed successfully.', 'craftnce' ) . ' ' . esc_html__( 'Show Details', 'craftnce' ) . '.'; - $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'craftnce' ); - /* translators: 1: plugin name, 2: action number 3: total number of actions. */ - $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'craftnce' ); - } - } - } - - /** - * Outputs the header strings and necessary JS before each plugin installation. - * - * @since 2.2.0 - * - * @param string $title Unused in this implementation. - */ - public function before( $title = '' ) { - if ( empty( $title ) ) { - $title = esc_html( $this->plugin_names[ $this->i ] ); - } - parent::before( $title ); - } - - /** - * Outputs the footer strings and necessary JS after each plugin installation. - * - * Checks for any errors and outputs them if they exist, else output - * success strings. - * - * @since 2.2.0 - * - * @param string $title Unused in this implementation. - */ - public function after( $title = '' ) { - if ( empty( $title ) ) { - $title = esc_html( $this->plugin_names[ $this->i ] ); - } - parent::after( $title ); - - $this->i++; - } - - /** - * Outputs links after bulk plugin installation is complete. - * - * @since 2.2.0 - */ - public function bulk_footer() { - // Serve up the string to say installations (and possibly activations) are complete. - parent::bulk_footer(); - - // Flush plugins cache so we can make sure that the installed plugins list is always up to date. - wp_clean_plugins_cache(); - - $this->tgmpa->show_tgmpa_version(); - - // Display message based on if all plugins are now active or not. - $update_actions = array(); - - if ( $this->tgmpa->is_tgmpa_complete() ) { - // All plugins are active, so we display the complete string and hide the menu to protect users. - echo ''; - $update_actions['dashboard'] = sprintf( - esc_html( $this->tgmpa->strings['complete'] ), - '' . esc_html__( 'Return to the Dashboard', 'craftnce' ) . '' - ); - } else { - $update_actions['tgmpa_page'] = '' . esc_html( $this->tgmpa->strings['return'] ) . ''; - } - - /** - * Filter the list of action links available following bulk plugin installs/updates. - * - * @since 2.5.0 - * - * @param array $update_actions Array of plugin action links. - * @param array $plugin_info Array of information for the last-handled plugin. - */ - $update_actions = apply_filters( 'tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info ); - - if ( ! empty( $update_actions ) ) { - $this->feedback( implode( ' | ', (array) $update_actions ) ); - } - } - - /* *********** DEPRECATED METHODS *********** */ - - /** - * Flush header output buffer. - * - * @since 2.2.0 - * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead - * @see Bulk_Upgrader_Skin::flush_output() - */ - public function before_flush_output() { - _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); - $this->flush_output(); - } - - /** - * Flush footer output buffer and iterate $this->i to make sure the - * installation strings reference the correct plugin. - * - * @since 2.2.0 - * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead - * @see Bulk_Upgrader_Skin::flush_output() - */ - public function after_flush_output() { - _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); - $this->flush_output(); - $this->i++; - } - } - } - } - } -} - -if ( ! class_exists( 'TGMPA_Utils' ) ) { - - /** - * Generic utilities for TGMPA. - * - * All methods are static, poor-dev name-spacing class wrapper. - * - * Class was called TGM_Utils in 2.5.0 but renamed TGMPA_Utils in 2.5.1 as this was conflicting with Soliloquy. - * - * @since 2.5.0 - * - * @package TGM-Plugin-Activation - * @author Juliette Reinders Folmer - */ - class TGMPA_Utils { - /** - * Whether the PHP filter extension is enabled. - * - * @see http://php.net/book.filter - * - * @since 2.5.0 - * - * @static - * - * @var bool $has_filters True is the extension is enabled. - */ - public static $has_filters; - - /** - * Wrap an arbitrary string in tags. Meant to be used in combination with array_map(). - * - * @since 2.5.0 - * - * @static - * - * @param string $string Text to be wrapped. - * @return string - */ - public static function wrap_in_em( $string ) { - return '' . wp_kses_post( $string ) . ''; - } - - /** - * Wrap an arbitrary string in tags. Meant to be used in combination with array_map(). - * - * @since 2.5.0 - * - * @static - * - * @param string $string Text to be wrapped. - * @return string - */ - public static function wrap_in_strong( $string ) { - return '' . wp_kses_post( $string ) . ''; - } - - /** - * Helper function: Validate a value as boolean - * - * @since 2.5.0 - * - * @static - * - * @param mixed $value Arbitrary value. - * @return bool - */ - public static function validate_bool( $value ) { - if ( ! isset( self::$has_filters ) ) { - self::$has_filters = extension_loaded( 'filter' ); - } - - if ( self::$has_filters ) { - return filter_var( $value, FILTER_VALIDATE_BOOLEAN ); - } else { - return self::emulate_filter_bool( $value ); - } - } - - /** - * Helper function: Cast a value to bool - * - * @since 2.5.0 - * - * @static - * - * @param mixed $value Value to cast. - * @return bool - */ - protected static function emulate_filter_bool( $value ) { - // @codingStandardsIgnoreStart - static $true = array( - '1', - 'true', 'True', 'TRUE', - 'y', 'Y', - 'yes', 'Yes', 'YES', - 'on', 'On', 'ON', - ); - static $false = array( - '0', - 'false', 'False', 'FALSE', - 'n', 'N', - 'no', 'No', 'NO', - 'off', 'Off', 'OFF', - ); - // @codingStandardsIgnoreEnd - - if ( is_bool( $value ) ) { - return $value; - } elseif ( is_int( $value ) && ( 0 === $value || 1 === $value ) ) { - return (bool) $value; - } elseif ( ( is_float( $value ) && ! is_nan( $value ) ) && ( (float) 0 === $value || (float) 1 === $value ) ) { - return (bool) $value; - } elseif ( is_string( $value ) ) { - $value = trim( $value ); - if ( in_array( $value, $true, true ) ) { - return true; - } elseif ( in_array( $value, $false, true ) ) { - return false; - } else { - return false; - } - } - - return false; - } - } // End of class TGMPA_Utils -} // End of class_exists wrapper
-
', - esc_html__( 'Upgrade message from the plugin author:', 'craftnce' ), - ' ', wp_kses_data( $item['upgrade_notice'] ), ' -
-