//
// Compatibility
// -----------------------------------------------------------------------------
//
// ### Usage:
// 解决常见兼容性问题，如浏览器私有前缀等。

@import "variables.less";

.inline-block() {
    display: inline-block;
}
.ie-inline-block() {
    *display: inline;
    *zoom: 1;
}
.inline-block() when (@support-old-ie) {
    .ie-inline-block;
}

//
// Known issue:
// 不支持IE 6/7

.box-sizing(@boxmodel) {
    -webkit-box-sizing: @boxmodel;
       -moz-box-sizing: @boxmodel;
            box-sizing: @boxmodel;
}

//
// Reference:
// * http://css-tricks.com/snippets/css/style-placeholder-text/
// * https://bugzilla.mozilla.org/show_bug.cgi?id=737786
//
// Known issue:
// 不支持IE 9及以下

.placeholder(@color: @default-input-placeholder-color) {
    &:-moz-placeholder {
        color: @color;
    }
    &::-moz-placeholder {
        color: @color;
    }
    &::-webkit-input-placeholder {
        color: @color;
    }
    &:-ms-input-placeholder {
        color: @color;
    }
}


//
// Known issue:
// 不支持Opera 14及以前版本，Opera 15起支持-webkit-user-select。

.user-select(@type) {
    -webkit-user-select: @type;
       -moz-user-select: @type;
        -ms-user-select: @type;
            user-select: @type;
}

.opacity(@opacity: 100) {
    opacity: @opacity / 100;
    filter: ~"alpha(opacity=@{opacity})";
}

// Border Radius
// all
.border-radius(@radius: @default-border-radius) {
    -webkit-border-radius: @radius;
       -moz-border-radius: @radius;
            border-radius: @radius;
}
.border-radius(@radius-x, @radius-y) {
    .border-radius(@radius-x ~`"/"` @radius-y);
}

// top left
.border-top-left-radius(@radius) {
    -webkit-border-top-left-radius: @radius;
        -moz-border-radius-topleft: @radius;
            border-top-left-radius: @radius;
}
.border-top-left-radius(@radius-x, @radius-y) {
    .border-top-left-radius(@radius-x ~"/" @radius-y);
}

// top right
.border-top-right-radius(@radius) {
    -webkit-border-top-right-radius: @radius;
        -moz-border-radius-topright: @radius;
            border-top-right-radius: @radius;
}
.border-top-right-radius(@radius-x, @radius-y) {
    .border-top-right-radius(@radius-x ~"/" @radius-y)
}

// bottom right
.border-bottom-right-radius(@radius) {
    -webkit-border-bottom-right-radius: @radius;
        -moz-border-radius-bottomright: @radius;
            border-bottom-right-radius: @radius;
}
.border-bottom-right-radius(@radius-x, @radius-y) {
    .border-bottom-right-radius(@radius-x ~"/" @radius-y)
}

// bottom left
.border-bottom-left-radius(@radius) {
    -webkit-border-bottom-left-radius: @radius;
        -moz-border-radius-bottomleft: @radius;
            border-bottom-left-radius: @radius;
}
.border-bottom-left-radius(@radius-x, @radius-y) {
    .border-bottom-left-radius(@radius-x ~"/" @radius-y);
}

// top
.border-top-radius(@radius) {
    .border-top-left-radius(@radius);
    .border-top-right-radius(@radius);
}
.border-top-radius(@radius-x, @radius-y) {
    .border-top-radius(@radius-x ~"/" @radius-y);
}

// right
.border-right-radius(@radius) {
    .border-top-right-radius(@radius);
    .border-bottom-right-radius(@radius);
}
.border-right-radius(@radius-x, @radius-y) {
    .border-right-radius(@radius-x ~"/" @radius-y);
}

// bottom
.border-bottom-radius(@radius) {
    .border-bottom-right-radius(@radius);
    .border-bottom-left-radius(@radius);
}
.border-bottom-radius(@radius-x, @radius-y) {
    .border-bottom-radius(@radius-x ~"/" @radius-y);
}

// left
.border-left-radius(@radius) {
    .border-top-left-radius(@radius);
    .border-bottom-left-radius(@radius);
}
.border-left-radius(@radius-x, @radius-y) {
    .border-left-radius(@radius-x ~"/" @radius-y);
}

// Drop shadows
.box-shadow(@shadow: @default-box-shadow, ...) {
    @shadows: ~`(function() { var args = "@{arguments}".replace(/[[\]]/g, ""); if(!args.match(/[^,]\s+[^,]/)) { args = args.replace(/,(?=[^()]*\))/g, "%est%").replace(/,/g, "").replace(/%est%/g, ","); } return args;})()`;
    -webkit-box-shadow: @shadows;
       -moz-box-shadow: @shadows;
            box-shadow: @shadows;
}

// Transitions
// Reference:
// * https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

.transition(@transition, ...) {
    @transitions: ~`(function() { var args = "@{arguments}".replace(/[[\]]/g, ""); if(!args.match(/[^,]\s+[^,]/)) { args = args.replace(/,(?=[^()]*\))/g, "%est%").replace(/,/g, "").replace(/%est%/g, ","); } return args;})()`;
    @webkit-transitions: ~`"@{transitions}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-webkit-$1")`;
    @moz-transitions: ~`"@{transitions}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-moz-$1")`;
    @ms-transitions: ~`"@{transitions}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-ms-$1")`;
    @o-transitions: ~`"@{transitions}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-o-$1")`;
    -webkit-transition: @webkit-transitions;
       -moz-transition: @moz-transitions;
        -ms-transition: @ms-transitions;
         -o-transition: @o-transitions;
            transition: @transitions;
}
.transition-property(@property: all, ...) {
    @properties: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    @webkit-properties: ~`"@{properties}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-webkit-$1")`;
    @moz-properties: ~`"@{properties}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-moz-$1")`;
    @ms-properties: ~`"@{properties}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-ms-$1")`;
    @o-properties: ~`"@{properties}".replace(/(transform|perspective|border(?:-\w+)*?-radius|box-shadow)/g, "-o-$1")`;
    -webkit-transition-property: @webkit-properties;
       -moz-transition-property: @moz-properties;
        -ms-transition-property: @ms-properties;
         -o-transition-property: @o-properties;
            transition-property: @properties;
}
.transition-duration(@duration: 0s, ...) {
    @durations: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-transition-duration: @durations;
       -moz-transition-duration: @durations;
        -ms-transition-duration: @durations;
         -o-transition-duration: @durations;
            transition-duration: @durations;
}
.transition-timing-function(@timing-function: ease, ...) {
    @timing-functions: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-transition-timing-function: @timing-functions;
       -moz-transition-timing-function: @timing-functions;
        -ms-transition-timing-function: @timing-functions;
         -o-transition-timing-function: @timing-functions;
            transition-timing-function: @timing-functions;
}
.transition-delay(@delay: 0s, ...) {
    @delays: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-transition-delay: @delays;
       -moz-transition-delay: @delays;
        -ms-transition-delay: @delays;
         -o-transition-delay: @delays;
            transition-delay: @delays;
}


//
// Animations
//
// Reference:
// * https://developer.mozilla.org/en-US/docs/Web/CSS/animation


.animation(@animation, ...) {
    @animations: ~`(function() { var args = "@{arguments}".replace(/[[\]]/g, ""); if(!args.match(/[^,]\s+[^,]/)) { args = args.replace(/,(?=[^()]*\))/g, "%est%").replace(/,/g, "").replace(/%est%/g, ","); } return args;})()`;
    -webkit-animation: @animations;
       -moz-animation: @animations;
        -ms-animation: @animations;
         -o-animation: @animations;
            animation: @animations;
}
.animation-name(@name: none, ...) {
    @names: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-name: @names;
       -moz-animation-name: @names;
        -ms-animation-name: @names;
         -o-animation-name: @names;
            animation-name: @names;
}
.animation-duration(@duration: 0s, ...) {
    @durations: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-duration: @durations;
       -moz-animation-duration: @durations;
        -ms-animation-duration: @durations;
         -o-animation-duration: @durations;
            animation-duration: @durations;
}
.animation-timing-function(@timing-function: ease, ...) {
    @timing-functions: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-timing-function: @timing-functions;
       -moz-animation-timing-function: @timing-functions;
        -ms-animation-timing-function: @timing-functions;
         -o-animation-timing-function: @timing-functions;
            animation-timing-function: @timing-functions;
}
.animation-iteration-count(@count: 1, ...) {
    @counts: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-iteration-count: @counts;
       -moz-animation-iteration-count: @counts;
        -ms-animation-iteration-count: @counts;
         -o-animation-iteration-count: @counts;
            animation-iteration-count: @counts;
}
.animation-direction(@direction: normal, ...) {
    @directions: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-direction: @directions;
       -moz-animation-direction: @directions;
        -ms-animation-direction: @directions;
         -o-animation-direction: @directions;
            animation-direction: @directions;
}
.animation-play-state(@state: normal, ...) {
    @states: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-play-state: @states;
       -moz-animation-play-state: @states;
        -ms-animation-play-state: @states;
         -o-animation-play-state: @states;
            animation-play-state: @states;
}
.animation-delay(@delay: 0s, ...) {
    @delays: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-delay: @delays;
       -moz-animation-delay: @delays;
        -ms-animation-delay: @delays;
         -o-animation-delay: @delays;
            animation-delay: @delays;
}
.animation-fill-mode(@mode: none, ...) {
    @modes: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-animation-fill-mode: @modes;
       -moz-animation-fill-mode: @modes;
        -ms-animation-fill-mode: @modes;
         -o-animation-fill-mode: @modes;
            animation-fill-mode: @modes;
}


//
// Transformations
//
// Reference:
// * https://developer.mozilla.org/en-US/docs/Web/CSS/transform
// * http://dev.w3.org/csswg/css-transforms/#transform

.transform(...) {
    -webkit-transform: @arguments;
       -moz-transform: @arguments;
        -ms-transform: @arguments;
         -o-transform: @arguments;
            transform: @arguments;
}

// Known issue:
// IE不支持，Opera 15起以`-webkit`前缀方式支持

.transform-style(@style) {
    -webkit-transform-style: @style;
       -moz-transform-style: @style;
            transform-style: @style;
}

//
// Known issue:
// Opera 15起以`-webkit`前缀方式支持三值语法，之前以`-o`前缀方式支持

.transform-origin(@origin) {
    -webkit-transform-origin: @origin;
       -moz-transform-origin: @origin;
        -ms-transform-origin: @origin;
         -o-transform-origin: @origin;
            transform-origin: @origin;
}

//
// Known issue:
// IE9、Opera 14及以下不支持，Opera 15起以`-webkit`前缀方式支持

.backface-visibility(@visibility) {
    -webkit-backface-visibility: @visibility;
       -moz-backface-visibility: @visibility;
            backface-visibility: @visibility;
}

//
// Known issue:
// IE9、Opera 14及以下不支持，Opera 15起以`-webkit`前缀方式支持

.perspective(@d) {
    -webkit-perspective: @d;
       -moz-perspective: @d;
            perspective: @d;
}

//
// 单个变换函数的快捷方法

.transform-single(@transform-function, @rest...) {
    @args: ~`"@{rest}".replace(/[\[\]]/g, "")`;
    -webkit-transform: ~`"@{transform-function}(@{args})"`;
       -moz-transform: ~`"@{transform-function}(@{args})"`;
        -ms-transform: ~`"@{transform-function}(@{args})"`;
         -o-transform: ~`"@{transform-function}(@{args})"`;
            transform: ~`"@{transform-function}(@{args})"`;
}

//2D transform  functions

.matrix(@a, @b, @c, @d, @tx, @ty) {
    .transform-single(matrix, @arguments);
}

.translate(@tx) {
    .transform-single(translate, @arguments);
}
.translate(@tx, @ty) {
    .transform-single(translate, @arguments);
}

.translateX(@tx) {
    .transform-single(translateX, @arguments);
}

.translateY(@ty) {
    .transform-single(translateY, @arguments);
}

.scale(@sx) {
    .transform-single(scale, @arguments);
}
.scale(@sx, @sy) {
    .transform-single(scale, @arguments);
}

.scaleX(@sx) {
    .transform-single(scaleX, @arguments);
}

.scaleY(@sy) {
    .transform-single(scaleY, @arguments);
}

.rotate(@angle) {
    .transform-single(rotate, @arguments);
}

// TODO: see https://github.com/twitter/bootstrap/blob/master/less/mixins.less#L300
.skew(@ax) {
    .transform-single(skew, @arguments);
}
.skew(@ax, @ay) {
    .transform-single(skew, @arguments);
}

.skewX(@ax) {
    .transform-single(skewX, @arguments);
}

.skewY(@ay) {
    .transform-single(skewY, @arguments);
}

//3D transform  functions

.maxtrix3d(@a1, @b1, @c1, @d1, @a2, @b2, @c2, @d2,
           @a3, @b3, @c3, @d3, @a4, @b4, @c4, @d4) {
    .transform-single(matrix3d, @arguments);
}

.translate3d(@tx, @ty, @tz) {
    .transform-single(translate3d, @arguments);
}

.translateZ(@tz) {
    .transform-single(translateZ, @arguments);
}

.scale3d(@sx, @sy, @sz) {
    .transform-single(scale3d, @arguments);
}

.scaleZ(@sz) {
    .transform-single(scaleZ, @arguments);
}

.rotate3d(@x, @y, @z, @angle) {
    .transform-single(rotate3d, @arguments);
}

.rotateX(@angle) {
    .transform-single(rotateX, @arguments);
}

.rotateY(@angle) {
    .transform-single(rotateY, @arguments);
}

.rotateZ(@angle) {
    .transform-single(rotateZ, @arguments);
}

// TODO: transform: perspective() needs a better name
// (which will not conflict with the original perspective property mixin)
// .perspective(@d) {
//     .transform-single(perspective, @d);
// }

//
// CSS3 Background

// FF 3.6 and under need "padding" instead of "padding-box"
.background-clip(@clip, ...) {
    @clips: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-background-clip: @clips;
       -moz-background-clip: ~`"@{clips}".replace(/-box/g, "")`;
            background-clip: @clips;
}

// Background sizing
.background-size(@size, ...) {
    @sizes: ~`"@{arguments}".replace(/[\[\]]/g, "")`;
    -webkit-background-size: @sizes;
       -moz-background-size: @sizes;
         -o-background-size: @sizes;
            background-size: @sizes;
}

//
// Gradients

// General linear-gradient
.linear-gradient(@direction, @color-stop...) {
    @dir: ~`"@{direction}".replace(/[\[\],]/g, "")`;
    @is-old-side-or-corner: ~`/^(?:top|right|bottom|left)(?:\s+(?:top|right|bottom|left))?$/.test("@{dir}") ? "true" : "false"`;
    @is-standard-side-or-corner: ~`/^to\s+(?:top|right|bottom|left)(?:\s+(?:top|right|bottom|left))?$/.test("@{dir}") ? "true" : "false"`;
    @color-stops: ~`"@{color-stop}".replace(/[\[\]]/g, "")`;
    .output() when (@is-old-side-or-corner) {
        @standard-direction: ~`"to @{dir}".replace("top", "b#ottom").replace("right", "l#eft").replace("bottom", "t#op").replace("left", "r#ight").replace(/#/g, "")`;
        background-image: -webkit-linear-gradient(@dir, @color-stops); // Chrome 10+
        background-image: -moz-linear-gradient(@dir, @color-stops); // Firefox 3.6+
        background-image: -moz-linear-gradient(@standard-direction, @color-stops); // Firefox 10+
        background-image: -o-linear-gradient(@standard-direction, @color-stops); // Opera 11.10+
        background-image: linear-gradient(@standard-direction, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output() when (@is-standard-side-or-corner) {
        @old-direction: ~`"@{dir}".replace(/^to\s+/, "").replace("top", "b#ottom").replace("right", "l#eft").replace("bottom", "t#op").replace("left", "r#ight").replace(/#/g, "")`;
        background-image: -webkit-linear-gradient(@old-direction, @color-stops); // Chrome 10+
        background-image: -moz-linear-gradient(@old-direction, @color-stops); // Firefox 3.6+
        background-image: -moz-linear-gradient(@dir, @color-stops); // Firefox 10+
        background-image: -o-linear-gradient(@dir, @color-stops); // Opera 11.10+
        background-image: linear-gradient(@dir, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output() when not (@is-old-side-or-corner) and not (@is-standard-side-or-corner) {
        background-image: -webkit-linear-gradient(mod(abs(convert(@direction, deg) - 450), 360), @color-stops); // Chrome 10+
        background-image: -moz-linear-gradient(mod(abs(convert(@direction, deg) - 450), 360), @color-stops); // Firefox 3.6+
        background-image: -o-linear-gradient(mod(abs(convert(@direction, deg) - 450), 360), @color-stops); // Opera 11.10+
        background-image: linear-gradient(@direction, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output();
    background-repeat: repeat;
}

// Horizontal gradient with better browser compatibility
.horizontal-gradient(@start-color, @end-color) {
    background-image: -webkit-gradient(linear, left top, right top, from(@start-color), to(@end-color)); // Safari 4+, Chrome 2+
    background-image: -webkit-linear-gradient(left, @start-color, @end-color); // Safari 5.1+, Chrome 10+
    background-image: -moz-linear-gradient(left, @start-color, @end-color); // FF 3.6+
    background-image: -o-linear-gradient(left, @start-color, @end-color); // Opera 11.10+
    background-image: linear-gradient(to right, @start-color, @end-color); // Standard, IE10
    background-repeat: repeat-x;
    filter: e(%("progid:DXImageTransform.Microsoft.Gradient(startColorstr='%d', endColorstr='%d', GradientType=1)", argb(@start-color), argb(@end-color))); // IE9 and down
}

// Vertical gradient with better browser compatibility
.vertical-gradient(@start-color, @end-color) {
    background-image: -webkit-gradient(linear, left top, left bottom, from(@start-color), to(@end-color)); // Safari 4+, Chrome 2+
    background-image: -webkit-linear-gradient(top, @start-color, @end-color); // Safari 5.1+, Chrome 10+
    background-image: -moz-linear-gradient(top, @start-color, @end-color); // FF 3.6+
    background-image: -o-linear-gradient(top, @start-color, @end-color); // Opera 11.10+
    background-image: linear-gradient(to bottom, @start-color, @end-color); // Standard, IE10
    background-repeat: repeat-x;
    filter: e(%("progid:DXImageTransform.Microsoft.Gradient(startColorstr='%d', endColorstr='%d', GradientType=0)", argb(@start-color), argb(@end-color))); // IE9 and down
}

// General repeating linear-gradient
.repeating-linear-gradient(@direction, @color-stop...) {
    @dir: ~`"@{direction}".replace(/[\[\],]/g, "")`;
    @is-old-side-or-corner: ~`/^(?:top|right|bottom|left)(?:\s+(?:top|right|bottom|left))?$/.test("@{dir}") ? "true" : "false"`;
    @is-standard-side-or-corner: ~`/^to\s+(?:top|right|bottom|left)(?:\s+(?:top|right|bottom|left))?$/.test("@{dir}") ? "true" : "false"`;
    @color-stops: ~`"@{color-stop}".replace(/[\[\]]/g, "")`;
    .output() when (@is-old-side-or-corner) {
        @standard-direction: ~`"to @{dir}".replace("top", "b#ottom").replace("right", "l#eft").replace("bottom", "t#op").replace("left", "r#ight").replace(/#/g, "")`;
        background-image: -webkit-repeating-linear-gradient(@dir, @color-stops); // Chrome 10+
        background-image: -moz-repeating-linear-gradient(@dir, @color-stops); // Firefox 3.6+
        background-image: -moz-repeating-linear-gradient(@standard-direction, @color-stops); // Firefox 10+
        background-image: -o-repeating-linear-gradient(@standard-direction, @color-stops); // Opera 11.10+
        background-image: repeating-linear-gradient(@standard-direction, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output() when (@is-standard-side-or-corner) {
        @old-direction: ~`"@{dir}".replace(/^to\s+/, "").replace("top", "b#ottom").replace("right", "l#eft").replace("bottom", "t#op").replace("left", "r#ight").replace(/#/g, "")`;
        background-image: -webkit-repeating-linear-gradient(@old-direction, @color-stops); // Chrome 10+
        background-image: -moz-repeating-linear-gradient(@old-direction, @color-stops); // Firefox 3.6+
        background-image: -moz-repeating-linear-gradient(@dir, @color-stops); // Firefox 10+
        background-image: -o-repeating-linear-gradient(@dir, @color-stops); // Opera 11.10+
        background-image: repeating-linear-gradient(@dir, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output() when not (@is-old-side-or-corner) and not (@is-standard-side-or-corner) {
        background-image: -webkit-repeating-linear-gradient(mod(abs(convert(@direction, deg) - 450), 360), @color-stops); // Chrome 10+
        background-image: -moz-repeating-linear-gradient(mod(abs(convert(@direction, deg) - 450), 360), @color-stops); // Firefox 3.6+
        background-image: -o-repeating-linear-gradient(mod(abs(convert(@direction, deg) - 450), 360), @color-stops); // Opera 11.10+
        background-image: repeating-linear-gradient(@direction, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output();
}

// General radial gradient (without size in specific dimensions)
.radial-gradient(@shape, @color-stop...) {
    @shape-string: ~"@{shape}";
    @position: ~`(function() { var pos = /(?:^|\s)at\s+(\S+)(?:\s+(\S+)\s*$)?/g.exec("@{shape-string}"); return pos? (pos[2]? pos[1] + ' ' + pos[2] : pos[1]) : 'false'; })()`;
    @contour-and-size: ~`(function() { var cs = /^(circle|ellipse|(?:(?:circle|ellipse)\s+)?(?:closest|farthest)-(?:corner|side))(?=$|\s+at)/.exec("@{shape-string}"); return cs? cs[1] : 'false'; })()`;
    @color-stops: ~`"@{color-stop}".replace(/[\[\]]/g, "")`;

    .output() when not (@position = false) and (@contour-and-size = false) {
        background-image: -webkit-radial-gradient(@position, @color-stops); // Chrome 10+
        background-image: -moz-radial-gradient(@position, @color-stops); // Firefox 3.6+
        background-image: -o-radial-gradient(@position, @color-stops); // Opera 11.60+
        background-image: radial-gradient(@shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output() when not (@contour-and-size = false) and (@position = false) {
        background-image: -webkit-radial-gradient(@contour-and-size, @color-stops); // Chrome 10+
        background-image: -moz-radial-gradient(@contour-and-size, @color-stops); // Firefox 3.6+
        background-image: -o-radial-gradient(@contour-and-size, @color-stops); // Opera 11.60+
        background-image: radial-gradient(@shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output() when not (@position = false) and not (@contour-and-size = false) {
        background-image: -webkit-radial-gradient(@position, @contour-and-size, @color-stops); // Chrome 10+
        background-image: -moz-radial-gradient(@position, @contour-and-size, @color-stops);
        background-image: -o-radial-gradient(@position, @contour-and-size, @color-stops); // Opera 11.60+
        background-image: radial-gradient(@shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    } // Standard, IE10+
    .output() when (@position = false) and (@contour-and-size = false) {
        background-image: -webkit-radial-gradient(@shape, @color-stops); // Chrome 10+
        background-image: -moz-radial-gradient(@shape, @color-stops); // Firefox 3.6+
        background-image: -o-radial-gradient(@shape, @color-stops); // Opera 11.60+
        background-image: radial-gradient(circle, @shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.10+, IE 10+
    }
    .output();
}

// General repeating radial gradient (without size in specific dimensions)
.repeating-radial-gradient(@shape, @color-stop...) {
    @shape-string: ~"@{shape}";
    @position: ~`(function() { var pos = /(?:^|\s)at\s+(\S+)(?:\s+(\S+)\s*$)?/g.exec("@{shape-string}"); return pos? (pos[2]? pos[1] + ' ' + pos[2] : pos[1]) : 'false'; })()`;
    @contour-and-size: ~`(function() { var cs = /^(circle|ellipse|(?:(?:circle|ellipse)\s+)?(?:closest|farthest)-(?:corner|side))(?=$|\s+at)/.exec("@{shape-string}"); return cs? cs[1] : 'false'; })()`;
    @color-stops: ~`"@{color-stop}".replace(/[\[\]]/g, "")`;

    .output() when not (@position = false) and (@contour-and-size = false) {
        background-image: -webkit-repeating-radial-gradient(@position, @color-stops); // Chrome 10+
        background-image: -moz-repeating-radial-gradient(@position, @color-stops); // Firefox 3.6+
        background-image: -o-repeating-radial-gradient(@position, @color-stops); // Opera 12+
        background-image: repeating-radial-gradient(@shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.50+, IE 10+
    }
    .output() when not (@contour-and-size = false) and (@position = false) {
        background-image: -webkit-repeating-radial-gradient(@contour-and-size, @color-stops); // Chrome 10+
        background-image: -moz-repeating-radial-gradient(@contour-and-size, @color-stops); // Firefox 3.6+
        background-image: -o-repeating-radial-gradient(@contour-and-size, @color-stops); // Opera 12+
        background-image: repeating-radial-gradient(@shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.50+, IE 10+
    }
    .output() when not (@position = false) and not (@contour-and-size = false) {
        background-image: -webkit-repeating-radial-gradient(@position, @contour-and-size, @color-stops); // Chrome 10+
        background-image: -moz-repeating-radial-gradient(@position, @contour-and-size, @color-stops); // Firefox 3.6+
        background-image: -o-repeating-radial-gradient(@position, @contour-and-size, @color-stops); // Opera 12+
        background-image: repeating-radial-gradient(@shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.50+, IE 10+
    }
    .output() when (@position = false) and (@contour-and-size = false) {
        background-image: -webkit-repeating-radial-gradient(@shape, @color-stops); // Chrome 10+
        background-image: -moz-repeating-radial-gradient(@shape, @color-stops); // Firefox 3.6+
        background-image: -o-repeating-radial-gradient(@shape, @color-stops); // Opera 12+
        background-image: repeating-radial-gradient(circle, @shape, @color-stops); // Chrome 26+, Firefox 16+, Opera 12.50+, IE 10+
    }
    .output();
}


//
// Extended display property values

.display(flex) {
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
}
.display(inline-flex) {
    display: -webkit-inline-flex;
    display: -ms-inline-flexbox;
    display: inline-flex;
}
.display(box) {
    display: -webkit-box;
    display: -moz-box;
}
.display(inline-box) {
    display: -webkit-inline-box;
    display: -moz-inline-box;
}
.display(@display) when not (@display = flex)
                    and not (@display = inline-flex)
                    and not (@display = box)
                    and not (@display = inline-box) {
    display: @display;
}


//
// Flexible Box Layout
//
// IE 10 support: http://msdn.microsoft.com/en-us/library/ie/hh673531%28v=vs.85%29.aspx
// IE 11 update: http://msdn.microsoft.com/en-us/library/ie/dn265027%28v=vs.85%29.aspx

.flex-direction(@direction) {
    -webkit-flex-direction: @direction;
       -moz-flex-direction: @direction;
        -ms-flex-direction: @direction;
            flex-direction: @direction; 
}

.flex-wrap(@wrap) {
    @ms-wrap: ~`"@{wrap}".replace(/nowrap/ig, "none")`;
    -webkit-flex-wrap: @wrap;
       -moz-flex-wrap: @wrap;
        -ms-flex-wrap: @ms-wrap;
            flex-wrap: @wrap; 
}

.flex-flow(@flow) {
    @direction: ~`(function() { var dir = /\b(row-reverse|row|column-reverse|column)\b/.exec("@{flow}"); return dir? dir[1] : "row"; })()`;
    @wrap: ~`(function() { var wrap = /\b(nowrap|wrap-reverse|wrap)\b/.exec("@{flow}"); return (wrap? wrap[1] : "nowrap").replace(/nowrap/ig, "none"); })()`;
    -ms-flex-direction: @direction;
    -ms-flex-wrap: @wrap;
    -webkit-flex-flow: @flow;
       -moz-flex-flow: @flow;
            flex-flow: @flow;
}

.order(@order) {
    -webkit-flex-order: @order;
       -moz-flex-order: @order;
        -ms-flex-order: @order;
    -webkit-order: @order;
       -moz-order: @order;
        -ms-order: @order;
            order: @order;
}

.flex(@flex) {
    -webkit-flex: @flex;
       -moz-flex: @flex;
        -ms-flex: @flex;
            flex: @flex;
}

.flex-grow(@flex) {
    -webkit-flex-grow: @flex;
       -moz-flex-grow: @flex;
            flex-grow: @flex;
}

.flex-shrink(@flex) {
    -webkit-flex-shrink: @flex;
       -moz-flex-shrink: @flex;
            flex-shrink: @flex;
}

.flex-basis(@size) {
    -webkit-flex-basis: @size;
       -moz-flex-basis: @size;
            flex-basis: @size;
}

.justify-content(@align) {
    @flex-pack: ~`"@{align}".replace(/flex-/ig, "").replace(/space-between/ig, "justify").replace(/space-around/ig, "distribute")`;
    -webkit-flex-pack: @flex-pack;
       -moz-flex-pack: @flex-pack;
        -ms-flex-pack: @flex-pack;
    -webkit-justify-content: @align;
       -moz-justify-content: @align;
        -ms-justify-content: @align;
            justify-content: @align;
}

.align-items(@align) {
    @flex-align: ~`"@{align}".replace(/flex-/ig, "")`;
    -webkit-flex-align: @flex-align;
       -moz-flex-align: @flex-align;
        -ms-flex-align: @flex-align;
    -webkit-align-items: @align;
       -moz-align-items: @align;
        -ms-align-items: @align;
            align-items: @align;
}

.align-self(@align) {
    @flex-align: ~`"@{align}".replace(/flex-/ig, "")`;
    -webkit-flex-item-align: @flex-align;
       -moz-flex-item-align: @flex-align;
        -ms-flex-item-align: @flex-align;
    -webkit-align-self: @align;
       -moz-align-self: @align;
        -ms-align-self: @align;
            align-self: @align;
}

.align-content(@align) {
    @flex-line-pack: ~`"@{align}".replace(/flex-/ig, "").replace(/space-between/ig, "justify").replace(/space-around/ig, "distribute")`;
    -webkit-flex-line-pack: @flex-line-pack;
       -moz-flex-line-pack: @flex-line-pack;
        -ms-flex-line-pack: @flex-line-pack;
    -webkit-align-content: @align;
       -moz-align-content: @align;
        -ms-align-content: @align;
            align-content: @align;
}

//
// Old Flexible Box Layout
.box-orient(@orient) {
    -webkit-box-orient: @orient;
       -moz-box-orient: @orient;
}

.box-direction(@direction) {
    -webkit-box-direction: @direction;
       -moz-box-direction: @direction;
}

.box-ordinal-group(@group) {
    -webkit-box-ordinal-group: @group;
       -moz-box-ordinal-group: @group;
}

.box-flex-group(@group) {
    -webkit-box-flex-group: @group;
       -moz-box-flex-group: @group;
}

.box-flex(@flex) {
    -webkit-box-flex: @flex;
       -moz-box-flex: @flex;
}

.box-align(@align) {
    -webkit-box-align: @align;
       -moz-box-align: @align;
}

.box-pack(@align) {
    -webkit-box-pack: @align;
       -moz-box-pack: @align;
}

// box-lines are omitted because no browser did implement it