Skip to content

Instantly share code, notes, and snippets.

@katyo
Last active November 25, 2015 15:49
Show Gist options
  • Save katyo/bd5a8811d63d77efeead to your computer and use it in GitHub Desktop.
Save katyo/bd5a8811d63d77efeead to your computer and use it in GitHub Desktop.
UglifyJS clossure variables overlapping
node_modules/
dist/

This project demonstrates strange behavior of UglifyJS mangler.

Gist

The source of function replace from ./node_modules/remarkable/lib/common/html_re.js:

function replace(regex, options) {
  regex = regex.source;
  options = options || '';

  return function self(name, val) {
    if (!name) {
      return new RegExp(regex, options);
    }
    val = val.source || val;
    regex = regex.replace(name, val);
    return self;
  };
}

The result of uglification:

function e(e,t){e=e.source;t=t||"";return function n(r,n){if(!r){return new RegExp(e,t)}n=n.source||n;e=e.replace(r,n);return n}}

Readable version:

function e(e,t){
  e=e.source;
  t=t||"";
  return function n(r,n){
    if(!r){
      return new RegExp(e,t)
    }
    n=n.source||n;
    e=e.replace(r,n);
    return n
  }
}

Overlapping between function name self and variable name val (both named with n in result).

Reproducing using webpack

  • Clone repo
  • Exec export PATH=$PATH:./node_modules/.bin (optional)
  • Exec cake build to produce uglified version of client
  • Explore to the dist/client_0.0.1.min.js or open index.html in browser (it throws exception).
  • Exec cake -d build to produce non-uglified version of client
  • Explore the dist/client_0.0.1.min.js or open index.html in browser (it works perfect).

Reproducing using uglifyjs command line

  • Exec cake -d build to produce non-uglified version of client
  • Rename dist/client_0.0.1.min.js to dist/client_0.0.1.src.js
  • Exec ./node_modules/webpack/node_modules/uglify-js/bin/uglifyjs -m top_level=true,sort=true -o dist/client_0.0.1.min.js dist/client_0.0.1.src.js
  • Explore the dist/client_0.0.1.min.js or open index.html in browser (it throws exception).
{createFactory, createClass, PropTypes: {bool}, DOM: {div, span}} = require "react"
{Modal} = bootstrap = require "react-bootstrap"
@[field] = createFactory value for field, value of module for module in [
bootstrap
]
@["Modal#{field}"] = createFactory Modal[field] for field in ["Dialog", "Header", "Title", "Body", "Footer"]
@Container = createFactory createClass
propTypes:
content: bool
container: bool
fluid: bool
render: ->
div
className: "#{if @props.container then " container" else ""}#{if @props.fluid then " container-fluid" else ""}"
style:
paddingTop: 80 if @props.content
@props.children
@Wrapper = span
@ModalMixin = (name)->
getInitialState: ->
"show#{name}": no
"hide#{name}": no
"show#{name}": (done)->
done = null if "function" isnt typeof done
@setState "show#{name}": yes, done
"hide#{name}": (done)->
done = null if "function" isnt typeof done
@setState "hide#{name}": yes, done
"drop#{name}": ->
@setState
"show#{name}": no
"hide#{name}": no
"modal#{name}": ->
if @state["show#{name}"]
@["render#{name}"]
show: not @state["hide#{name}"]
onHide: @["hide#{name}"]
onExited: @["drop#{name}"]
{
name: packageName
version: packageVersion
} = require "./package.json"
{join, resolve} = require "path"
webpack = {DefinePlugin, optimize:{UglifyJsPlugin, DedupePlugin}} = require "webpack"
ExtractTextPlugin = require "extract-text-webpack-plugin"
CompressionPlugin = require "compression-webpack-plugin"
{chdir, cwd, env} = process
webpack_config = ({debug, cordova, crosswalk})->
context: __dirname
entry:
client: "./client.coffee"
output:
path: join __dirname, "dist"
filename: "[name]_#{packageVersion}.min.js"
chunkFilename: "[id].js"
externals: [
(context, request, callback)->
if request is "fs" and /node_modules\/yamljs/.test context
callback null, yes
return
do callback
]
module:
loaders: (loader for loader in [
test: /\.coffee$/
loader: "coffee"
,
test: /\.less$/
#loader: "style!css!less?strictMath"
loader: ExtractTextPlugin.extract "style", "css!less?strictMath"
,
test: /\.(?:png|svg|eot|ttf|otf|woff2?)$/
loader: if debug then "file" else "url"
query: limit: 32*1024
,
test: /\.json$/,
loader: "json"
,
test: /\.js$/,
loader: "transform?brfs!transform?envify"
] when loader?)
resolve:
extensions: [
""
".js"
".json"
".coffee"
".css"
]
devtool: switch
when debug then no #"cheap-module-eval-source-map"
else "source-map"
plugins: (plugin for plugin in [
new DefinePlugin
NODE_ENV: switch
when debug then '"development"'
else '"production"'
TARGET: '"browser"'
,
new DedupePlugin
,
unless debug
new UglifyJsPlugin
screw_ie8: no
comments: no
preamble: no
bare_returns: yes
mangle:
sort: yes
toplevel: yes
eval: no
compress:
sequences: yes
properties: yes
dead_code: yes
drop_debugger: yes
unsafe: yes
conditionals: yes
comparisons: yes
evaluate: yes
booleans: yes
loops: yes
unused: yes
hoist_funs: yes
hoist_vars: no
if_return: yes
join_vars: yes
cascade: yes
negate_iife: yes
pure_getters: yes
pure_funcs: null
drop_console: yes
keep_fargs: no
keep_fnames: no
,
new ExtractTextPlugin "[name]_#{packageVersion}.min.css"
,
unless debug
new CompressionPlugin
asset: "{file}.gz",
algorithm: "gzip",
regExp: /\.(?:js|svg|eot|ttf|otf|woff2?)$/,
threshold: 5*1024,
minRatio: 0.8
] when plugin?)
webpack_build = (opts, cb)->
webpack (webpack_config opts)
.run (error, stats)->
if error
throw error
else
{errors, warnings} = do stats.toJson
if errors.length > 0
console.error "Errors:"
for error in errors
console.error error
if warnings.length > 0
for warning in warnings
console.warn warning
#console.log stats
cb? null
env.PATH += ":#{__dirname}/node_modules/.bin"
option "-d", "--debug", "Debug mode"
task "build", "Build project", ({debug})->
env.BUILD_TYPE = switch
when debug then "debug"
else "release"
webpack_build {debug}
require "es5-shim"
require "es5-shim/es5-sham"
require "animation-frame"
.shim frameRate: 60
require "./client.less"
{render} = require "react-dom"
{Main: Base} = require "./main"
{Root} = require "./root"
{
document
navigator
localStorage
JSON: {
parse: fromJson
stringify: toJson
}
requestAnimationFrame
cancelAnimationFrame
} = window
###
{onerror} = window
window.onerror = (args...)->
{msg, file, line, col, error} = args
console.error "#{msg} #{file}:#{line}:#{col}\n${error?.stack}"
onerror.apply @, args... if onerror?
###
class Main extends Base
constructor: (@_rootNode)->
@_pendFrame = null
super
do @$render
$load: (props)->
for key of props when (raw = localStorage.getItem key)?
try val = fromJson raw
props[key] = val if val?
props
$save: (props)->
for key, val of props
if val?
try raw = toJson val
localStorage.setItem key, raw
else
localStorage.removeItem key
$redraw: =>
@_pendFrame = null
render (Root @), @_rootNode
$render: ->
unless @_pendFrame?
@_pendFrame = requestAnimationFrame @$redraw
initialize = ->
new Main document.getElementById "app-root"
document.addEventListener (switch TARGET
when "cordova" then "deviceready"
else "DOMContentLoaded"), initialize, no
@import "~bootstrap/less/bootstrap";
@import "variables";
@import "theme";
<!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="format-detection" content="telephone=no"><meta name="msapplication-tap-highlight" content="no"><meta name="viewport" content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><title>UglifyJS</title></head><body><div id="app-root"></div><script src="dist/client_0.0.1.min.js"></script></body></html>
class @Main
constructor: ->
{
@language
} = @$load
language: (navigator?.userLanguage or navigator?.language or "en").replace /[\-\_].+$/, ""
@languages =
en:
title: "English"
plural: (n)->
n |= 0
# nplurals=2; plural=(n != 1);
if n isnt 1 then 1 else 0
ru:
title: "Русский"
plural: (n)->
n |= 0
# nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);
switch
when n % 10 is 1 and n % 100 isnt 11 then 0
when n % 10 >= 2 and n % 10 <= 4 and (n % 100 < 10 or n % 100 >= 20) then 1
else 2
@language = "en" if @language not of @languages
@plural = @languages[@language].plural
destructor: ->
setLanguage: (@language)=>
@$save {@language}
@plural = @languages[@language].plural
do @$render
{createClass, DOM:{div}} = require "./react"
Remarkable = require "remarkable"
@Markup = createClass
getDefaultProps: ->
preset: "full"
options:
html: no
linkify: no
breaks: on
typographer: on
src: ""
plugins: []
walkers: []
shouldComponentUpdate: (props)->
# force rendering only if source text changed
@props.src isnt props.src
componentWillMount: ->
# create renderer instance once when mounting
@md = new Remarkable @props.preset, @props.markdown
@md.use plugin for plugin in @props.plugins
render: ->
tree = @md.parse @props.src, env = {}
walker.walk tree for walker in @props.walkers
div
className: @props.className
dangerouslySetInnerHTML:
__html: @md.renderer.render tree, @md.options, env
getTeaser = (content)->
if (pos = content.search /[\n]{2,}/)?
content[0..pos]
else
content
@getContent = (content, teaser = no)->
[teaser_, content_includes_teaser, content_] = content.split /(?:^[\n]*|[\n]{2,})([<])?[\/]{3,}[\n]{2,}/, 3
if teaser # need teaser
if content_? # have splitter
teaser_
else # haven't splitter
getTeaser content
else # need content
if content_? # have splitter
if content_includes_teaser
"""
#{teaser_}
#{content_}
"""
else
content_
else
content
{
"name": "uglify-clossure-vars-overlapping",
"version": "0.0.1",
"description": "UglifyJS closure vars overlapping.",
"main": "client.js",
"dependencies": {
"animation-frame": "^0.2.5",
"async": "^0.9.2",
"bootstrap": "^3.3.6",
"brfs": "^1.0.2",
"clarinet": "^0.9.1",
"clean-css": "^2.2.23",
"codemirror": "^5.7.0",
"coffee-script": "^1.9.2",
"es5-shim": "^4.3.1",
"gerber-parser": "^0.1.3",
"httpinvoke": "^1.3.2",
"json3": "^3.3.2",
"jszip": "^2.5.0",
"katex": "^0.5.1",
"moment": "^2.10.6",
"pdfkit": "^0.7.1",
"react": "^0.14.3",
"react-addons-update": "^0.14.3",
"react-bootstrap": "^0.28.1",
"react-codemirror": "^0.2.1",
"react-dom": "^0.14.3",
"readable-stream": "^2.0.4",
"remarkable": "^1.6.1",
"route-parser": "0.0.4",
"store": "^1.3.17",
"yamljs": "^0.2.4"
},
"devDependencies": {
"codo": "^2.0.9",
"coffee-loader": "^0.7.2",
"coffee-script": "^1.10.0",
"compression-webpack-plugin": "^0.2.0",
"css-loader": "^0.18.0",
"envify": "^3.4.0",
"extract-text-webpack-plugin": "^0.9.1",
"file-loader": "^0.8.5",
"json-loader": "^0.5.4",
"less": "^2.5.3",
"less-loader": "^2.2.1",
"style-loader": "^0.13.0",
"transform-loader": "^0.2.3",
"url-loader": "^0.5.7",
"webpack": "^1.12.9"
},
"scripts": {
"preuninstall": "rm -f client*.min.js client*.min.js.map",
"postinstall": "[ x$NODE_ENV = xproduction ] && { npm run-script release; true; } || npm run-script debug",
"release": "cake build",
"debug": "cake -d build",
"documentation": "codo -u common/*.coffee api/*.coffee",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "coffee server.coffee &",
"stop": "pkill --signal SIGINT $npm_package_name || true"
},
"repository": {
"type": "git",
"url": ""
},
"keywords": [
"ReactJS",
"NodeJS",
"Web",
"UglifyJS"
],
"author": "K. <[email protected]>",
"license": "MIT"
}
React = require "react"
{createClass, createFactory, createElement} = React
@[field] = value for field, value of React
@createClass = (args...)->
createFactory createClass args...
{createClass} = require "./react"
{Markup} = require "./markup"
@Root = createClass
getInitialState: ->
src: @props.content or """
# Example title
Example content
"""
render: ->
Markup
src: @state.src
// Paper 3.3.5
// Bootswatch
// -----------------------------------------------------
//@web-font-path: "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700";
/*
.web-font(@path) {
@import url("@{path}");
}
.web-font(@web-font-path);
*/
// Navbar =====================================================================
.navbar {
border: none;
.box-shadow(0 1px 2px rgba(0,0,0,.3));
&-brand {
font-size: 24px;
}
&-inverse {
.navbar-form {
input[type=text],
input[type=password] {
color: #fff;
.box-shadow(inset 0 -1px 0 @navbar-inverse-link-color);
.placeholder(@navbar-inverse-link-color);
&:focus {
.box-shadow(inset 0 -2px 0 #fff);
}
}
}
}
}
// Buttons ====================================================================
#btn(@class,@bg) {
.btn-@{class} {
background-size: 200%;
background-position: 50%;
&:focus {
background-color: @bg;
}
&:hover,
&:active:hover {
background-color: darken(@bg, 6%);
}
&:active {
background-color: darken(@bg, 12%);
#gradient > .radial(darken(@bg, 12%) 10%, @bg 11%);
background-size: 1000%;
.box-shadow(2px 2px 4px rgba(0,0,0,.4));
}
}
}
#btn(default,@btn-default-bg);
#btn(primary,@btn-primary-bg);
#btn(success,@btn-success-bg);
#btn(info,@btn-info-bg);
#btn(warning,@btn-warning-bg);
#btn(danger,@btn-danger-bg);
#btn(link,#fff);
.btn {
text-transform: uppercase;
border: none;
.box-shadow(1px 1px 4px rgba(0,0,0,.4));
.transition(all 0.4s);
&-link {
border-radius: @btn-border-radius-base;
.box-shadow(none);
color: @btn-default-color;
&:hover,
&:focus {
.box-shadow(none);
color: @btn-default-color;
text-decoration: none;
}
}
&-default {
&.disabled {
background-color: rgba(0, 0, 0, 0.1);
color: rgba(0, 0, 0, 0.4);
opacity: 1;
}
}
}
.btn-group {
.btn + .btn,
.btn + .btn-group,
.btn-group + .btn,
.btn-group + .btn-group {
margin-left: 0;
}
&-vertical {
> .btn + .btn,
> .btn + .btn-group,
> .btn-group + .btn,
> .btn-group + .btn-group {
margin-top: 0;
}
}
}
// Typography =================================================================
body {
-webkit-font-smoothing: antialiased;
letter-spacing: .1px;
}
p {
margin: 0 0 1em;
}
input,
button {
-webkit-font-smoothing: antialiased;
letter-spacing: .1px;
}
a {
.transition(all 0.2s);
}
// Tables =====================================================================
.table-hover {
> tbody > tr,
> tbody > tr > th,
> tbody > tr > td {
.transition(all 0.2s);
}
}
// Forms ======================================================================
label {
font-weight: normal;
}
textarea,
textarea.form-control,
input.form-control,
input[type=text],
input[type=password],
input[type=email],
input[type=number],
[type=text].form-control,
[type=password].form-control,
[type=email].form-control,
[type=tel].form-control,
[contenteditable].form-control {
padding: 0;
border: none;
border-radius: 0;
-webkit-appearance: none;
.box-shadow(inset 0 -1px 0 #ddd);
font-size: 16px;
&:focus {
.box-shadow(inset 0 -2px 0 @brand-primary);
}
&[disabled],
&[readonly] {
.box-shadow(none);
border-bottom: 1px dotted #ddd;
}
&.input {
&-sm {
font-size: @font-size-small;
}
&-lg {
font-size: @font-size-large;
}
}
}
select,
select.form-control {
border: 0;
border-radius: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding-left: 0;
padding-right: 0\9; // remove padding for < ie9 since default arrow can't be removed
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=);
background-size: 13px;
background-repeat: no-repeat;
background-position: right center;
.box-shadow(inset 0 -1px 0 #ddd);
font-size: 16px;
line-height: 1.5;
&::-ms-expand {
display: none;
}
&.input {
&-sm {
font-size: @font-size-small;
}
&-lg {
font-size: @font-size-large;
}
}
&:focus {
.box-shadow(inset 0 -2px 0 @brand-primary);
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEUhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF8S9ewAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=);
}
&[multiple] {
background: none;
}
}
.radio,
.radio-inline,
.checkbox,
.checkbox-inline {
label {
padding-left: 25px;
}
input[type="radio"],
input[type="checkbox"] {
margin-left: -25px;
}
}
input[type="radio"],
.radio input[type="radio"],
.radio-inline input[type="radio"] {
position: relative;
margin-top: 6px;
margin-right: 4px;
vertical-align: top;
border: none;
background-color: transparent;
-webkit-appearance: none;
appearance: none;
cursor: pointer;
&:focus {
outline: none;
}
&:before,
&:after {
content: "";
display: block;
width: 18px;
height: 18px;
border-radius: 50%;
.transition(240ms);
}
&:before {
position: absolute;
left: 0;
top: -3px;
background-color: @brand-primary;
.scale(0);
}
&:after {
position: relative;
top: -3px;
border: 2px solid @gray;
}
&:checked:before {
.scale(0.5);
}
&:disabled:checked:before {
background-color: @gray-light;
}
&:checked:after {
border-color: @brand-primary;
}
&:disabled:after,
&:disabled:checked:after {
border-color: @gray-light;
}
}
input[type="checkbox"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
position: relative;
border: none;
margin-bottom: -4px;
-webkit-appearance: none;
appearance: none;
cursor: pointer;
&:focus {
outline: none;
}
&:focus:after {
border-color: @brand-primary;
}
&:after {
content: "";
display: block;
width: 18px;
height: 18px;
margin-top: -2px;
margin-right: 5px;
border: 2px solid @gray;
border-radius: 2px;
.transition(240ms);
}
&:checked:before {
content: "";
position: absolute;
top: 0;
left: 6px;
display: table;
width: 6px;
height: 12px;
border: 2px solid #fff;
border-top-width: 0;
border-left-width: 0;
.rotate(45deg);
}
&:checked:after {
background-color: @brand-primary;
border-color: @brand-primary;
}
&:disabled:after {
border-color: @gray-light;
}
&:disabled:checked:after {
background-color: @gray-light;
border-color: transparent;
}
}
.has-warning {
input:not([type=checkbox]),
.form-control,
input.form-control[readonly],
input[type=text][readonly],
[type=text].form-control[readonly],
input:not([type=checkbox]):focus,
.form-control:focus {
border-bottom: none;
.box-shadow(inset 0 -2px 0 @brand-warning);
}
}
.has-error {
input:not([type=checkbox]),
.form-control,
input.form-control[readonly],
input[type=text][readonly],
[type=text].form-control[readonly],
input:not([type=checkbox]):focus,
.form-control:focus {
border-bottom: none;
.box-shadow(inset 0 -2px 0 @brand-danger);
}
}
.has-success {
input:not([type=checkbox]),
.form-control,
input.form-control[readonly],
input[type=text][readonly],
[type=text].form-control[readonly],
input:not([type=checkbox]):focus,
.form-control:focus {
border-bottom: none;
.box-shadow(inset 0 -2px 0 @brand-success);
}
}
// Remove the Bootstrap feedback styles for input addons
.input-group-addon {
.has-warning &, .has-error &, .has-success & {
color: @input-color;
border-color: @input-group-addon-border-color;
background-color: @input-group-addon-bg;
}
}
// Navs =======================================================================
.nav-tabs {
> li > a,
> li > a:focus {
margin-right: 0;
background-color: transparent;
border: none;
color: @navbar-default-link-color;
.box-shadow(inset 0 -1px 0 #ddd);
.transition(all 0.2s);
&:hover {
background-color: transparent;
.box-shadow(inset 0 -2px 0 @brand-primary);
color: @brand-primary;
}
}
& > li.active > a,
& > li.active > a:focus {
border: none;
.box-shadow(inset 0 -2px 0 @brand-primary);
color: @brand-primary;
&:hover {
border: none;
color: @brand-primary;
}
}
& > li.disabled > a {
.box-shadow(inset 0 -1px 0 #ddd);
}
&.nav-justified {
& > li > a,
& > li > a:hover,
& > li > a:focus,
& > .active > a,
& > .active > a:hover,
& > .active > a:focus {
border: none;
}
}
.dropdown-menu {
margin-top: 0;
}
}
.dropdown-menu {
margin-top: 0;
border: none;
.box-shadow(0 1px 4px rgba(0,0,0,.3));
}
// Indicators =================================================================
.alert {
border: none;
color: #fff;
&-success {
background-color: @brand-success;
}
&-info {
background-color: @brand-info;
}
&-warning {
background-color: @brand-warning;
}
&-danger {
background-color: @brand-danger;
}
a:not(.close),
.alert-link {
color: #fff;
font-weight: bold;
}
.close {
color: #fff;
}
}
.badge {
padding: 3px 6px 5px;
}
.progress {
position: relative;
z-index: 1;
height: 6px;
border-radius: 0;
.box-shadow(none);
&-bar {
.box-shadow(none);
&:last-child {
border-radius: 0 3px 3px 0;
}
&:last-child {
&:before {
display: block;
content: "";
position: absolute;
width: 100%;
height: 100%;
left: 0;
right: 0;
z-index: -1;
background-color: lighten(@progress-bar-bg, 35%);
}
}
&-success:last-child.progress-bar:before {
background-color: lighten(@brand-success, 35%);
}
&-info:last-child.progress-bar:before {
background-color: lighten(@brand-info, 45%);
}
&-warning:last-child.progress-bar:before {
background-color: lighten(@brand-warning, 35%);
}
&-danger:last-child.progress-bar:before {
background-color: lighten(@brand-danger, 25%);
}
}
}
// Progress bars ==============================================================
// Containers =================================================================
.close {
font-size: 34px;
font-weight: 300;
line-height: 24px;
opacity: 0.6;
.transition(all 0.2s);
&:hover {
opacity: 1;
}
}
.list-group {
&-item {
padding: 15px;
}
&-item-text {
color: @gray-light;
}
}
.well {
border-radius: 0;
.box-shadow(none);
}
.panel {
border: none;
border-radius: 2px;
.box-shadow(0 1px 4px rgba(0,0,0,.3));
&-heading {
border-bottom: none;
}
&-footer {
border-top: none;
}
}
.popover {
border: none;
.box-shadow(0 1px 4px rgba(0,0,0,.3));
}
.carousel {
&-caption {
h1, h2, h3, h4, h5, h6 {
color: inherit;
}
}
}
/*! Generated by Live LESS Theme Customizer */
@gray-dark: rgb(33, 33, 33);
@gray: rgb(102, 102, 102);
@gray-light: rgb(187, 187, 187);
@brand-primary: rgb(21, 140, 186);
@brand-success: rgb(76, 175, 80);
@brand-info: rgb(156, 39, 176);
@brand-warning: rgb(255, 152, 0);
@brand-danger: rgb(229, 28, 35);
@font-family-sans-serif: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
@font-size-base: 13px;
@font-size-h1: 56px;
@font-size-h2: 45px;
@font-size-h3: 34px;
@font-size-h4: 24px;
@font-size-h5: 20px;
@font-size-h6: 14px;
@line-height-base: 1.846;
@headings-font-weight: 400;
@headings-color: rgb(68, 68, 68);
@padding-base-horizontal: 16px;
@border-radius-base: 2px;
@border-radius-large: 3px;
@border-radius-small: 1px;
@btn-default-color: rgb(68, 68, 68);
@btn-default-bg: rgb(217, 216, 216);
@btn-default-border: transparent;
@btn-primary-bg: rgb(21, 140, 186);
@btn-primary-border: transparent;
@btn-success-border: transparent;
@btn-info-border: transparent;
@btn-warning-border: transparent;
@btn-danger-border: transparent;
@input-bg: transparent;
@input-bg-disabled: transparent;
@input-border: transparent;
@input-color-placeholder: @gray-light;
@input-group-addon-bg: transparent;
@dropdown-link-hover-bg: @gray-lighter;
@navbar-height: 64px;
@navbar-default-color: @gray-light;
@navbar-default-bg: rgb(255, 255, 255);
@navbar-default-border: transparent;
@navbar-default-link-color: @gray;
@navbar-default-link-hover-color: @gray-dark;
@navbar-default-link-active-color: @gray-dark;
@navbar-default-toggle-hover-bg: transparent;
@navbar-default-toggle-icon-bar-bg: rgba(0, 0, 0, 0.5);
@navbar-default-toggle-border-color: transparent;
@navbar-inverse-bg: @brand-primary;
@navbar-inverse-border: transparent;
@navbar-inverse-toggle-hover-bg: transparent;
@navbar-inverse-toggle-icon-bar-bg: rgba(0, 0, 0, 0.5);
@navbar-inverse-toggle-border-color: transparent;
@nav-tabs-border-color: transparent;
@nav-tabs-active-link-hover-bg: transparent;
@nav-tabs-active-link-hover-border-color: transparent;
@nav-tabs-justified-link-border-color: @nav-tabs-border-color;
@jumbotron-bg: rgb(249, 249, 249);
@state-success-text: @brand-success;
@state-info-text: @brand-info;
@state-info-bg: rgb(225, 190, 231);
@state-warning-text: @brand-warning;
@state-warning-bg: rgb(255, 224, 178);
@state-danger-text: @brand-danger;
@state-danger-bg: rgb(249, 189, 187);
@tooltip-bg: rgb(114, 114, 114);
@popover-border-color: transparent;
@popover-fallback-border-color: transparent;
@modal-content-border-color: transparent;
@modal-header-border-color: transparent;
@panel-success-text: rgb(255, 255, 255);
@panel-info-text: rgb(255, 255, 255);
@panel-warning-text: rgb(255, 255, 255);
@panel-danger-text: rgb(255, 255, 255);
@well-bg: rgb(249, 249, 249);
@well-border: transparent;
@badge-font-weight: normal;
@close-font-weight: normal;
@close-text-shadow: none;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment