/*
 * @Author: xiaodongyu
 * @Date 2021-04-02 18:54:30
 * @Last Modified by: xiaodongyu
 * @Last Modified time: 2021-12-01 14:11:18
 */

@use "sass:list";
@use "sass:map";
@use "sass:string";
// stylelint-disable indentation, at-rule-empty-line-before
// ref: https://getbootstrap.com/docs/5.0/utilities/api/  bootstrap/scss/bootstrap-utilities
// bootstrap/scss/function
// Internal Bootstrap function to turn maps into its negative variant.
// It prefixes the keys with `n` and makes the value negative.
@function negativify-map($map) {
  $result: ();
  @each $key, $value in $map {
    @if $key != 0 {
      $result: map.merge($result, ("n" + $key: (-$value)));
    }
  }
  @return $result;
}

// bootstrap/scss/variables
$black: #000;
$enable-important-utilities: true !default;

// scss-docs-start border-radius-variables
$border-radius: 0.25rem !default;
$border-radius-sm: 0.2rem !default;
$border-radius-lg: 0.3rem !default;
$border-radius-pill: 50rem !default;

// scss-docs-end border-radius-variables
// scss-docs-start box-shadow-variables
$box-shadow: 0 0.5rem 1rem rgb($black, 0.15) !default;
$box-shadow-sm: 0 0.125rem 0.25rem rgb($black, 0.075) !default;
$box-shadow-lg: 0 1rem 3rem rgb($black, 0.175) !default;
$box-shadow-inset: inset 0 1px 2px rgb($black, 0.075) !default;

// scss-docs-end box-shadow-variables

// Position
// Define the edge positioning anchors of the position utilities.

// scss-docs-start position-map
$position-values: (
  0: 0,
  50: 50%,
  100: 100%
) !default;

// scss-docs-end position-map
// Spacing
// Control the default styling of most Bootstrap elements by modifying these
// variables. Mostly focused on spacing.
// You can add more entries to the $spacers map, should you need more variation.

// scss-docs-start spacer-variables-maps
$spacer: 1rem !default;
$spacers: (
  0: 0,
  1: $spacer / 4,
  2: $spacer / 2,
  3: $spacer,
  4: $spacer * 1.5,
  5: $spacer * 3,
) !default;
$enable-negative-margins: true;
$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;

// scss-docs-end spacer-variables-maps
$font-weight-lighter: lighter !default;
$font-weight-light: 300 !default;
$font-weight-normal: 400 !default;
$font-weight-bold: 700 !default;
$font-weight-bolder: bolder !default;
$line-height-base: 1.5 !default;
$line-height-sm: 1.25 !default;
$line-height-lg: 2 !default;

// bootstrap/scss/mixin
// Text truncate
// Requires inline-block or block for proper styling

@mixin text-truncate() {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

// Utility generator
// Used to generate utilities & print utilities
@mixin generate-utility($utility, $infix: "", $is-rfs-media-query: false) {
  $values: map.get($utility, values);

  // If the values are a list or string, convert it into a map
  @if type-of($values) == "string" or type-of(nth($values, 1)) != "list" {
    $values: list.zip($values, $values);
  }

  @each $key, $value in $values {
    $properties: map.get($utility, property);

    // Multiple properties are possible, for example with vertical or horizontal margins or paddings
    @if type-of($properties) == "string" {
      $properties: list.append((), $properties);
    }

    // Use custom class if present
    $property-class: if(map.has-key($utility, class), map.get($utility, class), list.nth($properties, 1));
    $property-class: if($property-class == null, "", $property-class);

    // State params to generate pseudo-classes
    $state: if(map.has-key($utility, state), map.get($utility, state), ());
    $infix: if($property-class == "" and string.slice($infix, 1, 1) == "-", string.slice($infix, 2), $infix);

    // Don't prefix if value key is null (eg. with shadow class)
    $property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, "");

    @if map-get($utility, rfs) {
      // Inside the media query
      @if $is-rfs-media-query {
        $val: rfs-value($value);

        // Do not render anything if fluid and non fluid values are the same
        $value: if($val == rfs-fluid-value($value), null, $val);
      } @else {
        $value: rfs-fluid-value($value);
      }
    }

    $is-rtl: map.get($utility, rtl);

    @if $value {
      @if $is-rtl == false {
        /* rtl:begin:remove */
      }
      .#{$property-class + $infix + $property-class-modifier} {
        @each $property in $properties {
          #{$property}: $value if($enable-important-utilities, !important, null);
        }
      }

      @each $pseudo in $state {
        .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
          @each $property in $properties {
            #{$property}: $value if($enable-important-utilities, !important, null);
          }
        }
      }
      @if $is-rtl == false {
        /* rtl:end:remove */
      }
    }
  }
}

// bootstrap/scss/utilities
$utilities: () !default;
$utilities: map.merge(
  (
    // scss-docs-start utils-vertical-align
    "align": (
      property: vertical-align,
      class: align,
      values: baseline top middle bottom text-bottom text-top
    ),
    // scss-docs-end utils-vertical-align
    // scss-docs-start utils-float
    "float": (
      // responsive: true,
      property: float,
      values: (
        start: left,
        end: right,
        none: none,
      )
    ),
    // scss-docs-end utils-float
    // scss-docs-start utils-overflow
    "overflow": (
      property: overflow,
      values: auto hidden visible scroll,
    ),
    // scss-docs-end utils-overflow
    // scss-docs-start utils-display
    "display": (
      // responsive: true,
      print: true,
      property: display,
      class: d,
      values: inline inline-block block grid table table-row table-cell flex inline-flex none
    ),
    // scss-docs-end utils-display
    // scss-docs-start utils-shadow
    "shadow": (
      property: box-shadow,
      class: shadow,
      values: (
        null: $box-shadow,
        sm: $box-shadow-sm,
        lg: $box-shadow-lg,
        none: none,
      )
    ),
    // scss-docs-end utils-shadow
    // scss-docs-start utils-position
    "position": (
      property: position,
      values: static relative absolute fixed sticky
    ),
    "top": (
      property: top,
      values: $position-values
    ),
    "bottom": (
      property: bottom,
      values: $position-values
    ),
    "start": (
      property: left,
      class: start,
      values: $position-values
    ),
    "end": (
      property: right,
      class: end,
      values: $position-values
    ),
    "translate-middle": (
      property: transform,
      class: translate-middle,
      values: (
        null: translate(-50%, -50%),
        x: translateX(-50%),
        y: translateY(-50%),
      )
    ),
    // scss-docs-end utils-position
    // scss-docs-start utils-borders
    /*
    "border": (
      property: border,
      values: (
        null: $border-width solid $border-color,
        0: 0,
      )
    ),
    "border-top": (
      property: border-top,
      values: (
        null: $border-width solid $border-color,
        0: 0,
      )
    ),
    "border-end": (
      property: border-right,
      class: border-end,
      values: (
        null: $border-width solid $border-color,
        0: 0,
      )
    ),
    "border-bottom": (
      property: border-bottom,
      values: (
        null: $border-width solid $border-color,
        0: 0,
      )
    ),
    "border-start": (
      property: border-left,
      class: border-start,
      values: (
        null: $border-width solid $border-color,
        0: 0,
      )
    ),
    "border-color": (
      property: border-color,
      class: border,
      values: map-merge($theme-colors, ("white": $white))
    ),
    "border-width": (
      property: border-width,
      class: border,
      values: $border-widths
    ),
    */
    // scss-docs-end utils-borders
    // Sizing utilities
    // scss-docs-start utils-sizing
    "width": (
      property: width,
      class: w,
      values: (
        25: 25%,
        50: 50%,
        75: 75%,
        100: 100%,
        auto: auto
      )
    ),
    "max-width": (
      property: max-width,
      class: mw,
      values: (100: 100%)
    ),
    "viewport-width": (
      property: width,
      class: vw,
      values: (100: 100vw)
    ),
    "min-viewport-width": (
      property: min-width,
      class: min-vw,
      values: (100: 100vw)
    ),
    "height": (
      property: height,
      class: h,
      values: (
        25: 25%,
        50: 50%,
        75: 75%,
        100: 100%,
        auto: auto
      )
    ),
    "max-height": (
      property: max-height,
      class: mh,
      values: (100: 100%)
    ),
    "viewport-height": (
      property: height,
      class: vh,
      values: (100: 100vh)
    ),
    "min-viewport-height": (
      property: min-height,
      class: min-vh,
      values: (100: 100vh)
    ),
    // scss-docs-end utils-sizing
    // Flex utilities
    // scss-docs-start utils-flex
    "flex": (
      // responsive: true,
      property: flex,
      values: (fill: 1 1 auto)
    ),
    "flex-direction": (
      // responsive: true,
      property: flex-direction,
      class: flex,
      values: row column row-reverse column-reverse
    ),
    "flex-grow": (
      responsive: true,
      property: flex-grow,
      class: flex,
      values: (
        grow-0: 0,
        grow-1: 1,
      )
    ),
    "flex-shrink": (
      // responsive: true,
      property: flex-shrink,
      class: flex,
      values: (
        shrink-0: 0,
        shrink-1: 1,
      )
    ),
    "flex-wrap": (
      // responsive: true,
      property: flex-wrap,
      class: flex,
      values: wrap nowrap wrap-reverse
    ),
    "gap": (
      // responsive: true,
      property: gap,
      class: gap,
      values: $spacers
    ),
    "justify-content": (
      // responsive: true,
      property: justify-content,
      values: (
        start: flex-start,
        end: flex-end,
        center: center,
        between: space-between,
        around: space-around,
        evenly: space-evenly,
      )
    ),
    "align-items": (
      // responsive: true,
      property: align-items,
      values: (
        start: flex-start,
        end: flex-end,
        center: center,
        baseline: baseline,
        stretch: stretch,
      )
    ),
    "align-content": (
      // responsive: true,
      property: align-content,
      values: (
        start: flex-start,
        end: flex-end,
        center: center,
        between: space-between,
        around: space-around,
        stretch: stretch,
      )
    ),
    "align-self": (
      // responsive: true,
      property: align-self,
      values: (
        auto: auto,
        start: flex-start,
        end: flex-end,
        center: center,
        baseline: baseline,
        stretch: stretch,
      )
    ),
    "order": (
      // responsive: true,
      property: order,
      values: (
        first: -1,
        0: 0,
        1: 1,
        2: 2,
        3: 3,
        4: 4,
        5: 5,
        last: 6,
      ),
    ),
    // scss-docs-end utils-flex
    // Margin utilities
    // scss-docs-start utils-spacing
    "margin": (
      // responsive: true,
      property: margin,
      class: m,
      values: map.merge($spacers, (auto: auto))
    ),
    "margin-x": (
      // responsive: true,
      property: margin-right margin-left,
      class: mx,
      values: map.merge($spacers, (auto: auto))
    ),
    "margin-y": (
      // responsive: true,
      property: margin-top margin-bottom,
      class: my,
      values: map.merge($spacers, (auto: auto))
    ),
    "margin-top": (
      // responsive: true,
      property: margin-top,
      class: mt,
      values: map.merge($spacers, (auto: auto))
    ),
    "margin-end": (
      // responsive: true,
      property: margin-right,
      class: me,
      values: map.merge($spacers, (auto: auto))
    ),
    "margin-bottom": (
      // responsive: true,
      property: margin-bottom,
      class: mb,
      values: map.merge($spacers, (auto: auto))
    ),
    "margin-start": (
      // responsive: true,
      property: margin-left,
      class: ms,
      values: map.merge($spacers, (auto: auto))
    ),
    // Negative margin utilities
    "negative-margin": (
      // responsive: true,
      property: margin,
      class: m,
      values: $negative-spacers
    ),
    "negative-margin-x": (
      // responsive: true,
      property: margin-right margin-left,
      class: mx,
      values: $negative-spacers
    ),
    "negative-margin-y": (
      // responsive: true,
      property: margin-top margin-bottom,
      class: my,
      values: $negative-spacers
    ),
    "negative-margin-top": (
      // responsive: true,
      property: margin-top,
      class: mt,
      values: $negative-spacers
    ),
    "negative-margin-end": (
      // responsive: true,
      property: margin-right,
      class: me,
      values: $negative-spacers
    ),
    "negative-margin-bottom": (
      // responsive: true,
      property: margin-bottom,
      class: mb,
      values: $negative-spacers
    ),
    "negative-margin-start": (
      // responsive: true,
      property: margin-left,
      class: ms,
      values: $negative-spacers
    ),
    // Padding utilities
    "padding": (
      // responsive: true,
      property: padding,
      class: p,
      values: $spacers
    ),
    "padding-x": (
      // responsive: true,
      property: padding-right padding-left,
      class: px,
      values: $spacers
    ),
    "padding-y": (
      // responsive: true,
      property: padding-top padding-bottom,
      class: py,
      values: $spacers
    ),
    "padding-top": (
      // responsive: true,
      property: padding-top,
      class: pt,
      values: $spacers
    ),
    "padding-end": (
      // responsive: true,
      property: padding-right,
      class: pe,
      values: $spacers
    ),
    "padding-bottom": (
      // responsive: true,
      property: padding-bottom,
      class: pb,
      values: $spacers
    ),
    "padding-start": (
      // responsive: true,
      property: padding-left,
      class: ps,
      values: $spacers
    ),
    // scss-docs-end utils-spacing
    // Text
    // scss-docs-start utils-text
    /*
    "font-family": (
      property: font-family,
      class: font,
      values: (monospace: var(--#{$variable-prefix}font-monospace))
    ),
    "font-size": (
      rfs: true,
      property: font-size,
      class: fs,
      values: $font-sizes
    ),
    "font-style": (
      property: font-style,
      class: fst,
      values: italic normal
    ),
    */
    "font-weight": (
      property: font-weight,
      class: fw,
      values: (
        light: $font-weight-light,
        lighter: $font-weight-lighter,
        normal: $font-weight-normal,
        bold: $font-weight-bold,
        bolder: $font-weight-bolder
      )
    ),
    "line-height": (
      property: line-height,
      class: lh,
      values: (
        1: 1,
        sm: $line-height-sm,
        base: $line-height-base,
        lg: $line-height-lg,
      )
    ),
    "text-align": (
      // responsive: true,
      property: text-align,
      class: text,
      values: (
        start: left,
        end: right,
        center: center,
      )
    ),
    "text-decoration": (
      property: text-decoration,
      values: none underline line-through
    ),
    "text-transform": (
      property: text-transform,
      class: text,
      values: lowercase uppercase capitalize
    ),
    "white-space": (
      property: white-space,
      class: text,
      values: (
        wrap: normal,
        nowrap: nowrap,
      )
    ),
    "word-wrap": (
      property: word-wrap word-break,
      class: text,
      values: (break: break-word),
      rtl: false
    ),
    // scss-docs-end utils-text
    // scss-docs-start utils-color
    /*
    "color": (
      property: color,
      class: text,
      values: map-merge(
        $theme-colors,
        (
          "white": $white,
          "body": $body-color,
          "muted": $text-muted,
          "black-50": rgba($black, .5),
          "white-50": rgba($white, .5),
          "reset": inherit,
        )
      )
    ),
    // scss-docs-end utils-color
    // scss-docs-start utils-bg-color
    "background-color": (
      property: background-color,
      class: bg,
      values: map-merge(
        $theme-colors,
        (
          "body": $body-bg,
          "white": $white,
          "transparent": transparent
        )
      )
    ),
    // scss-docs-end utils-bg-color
    "gradient": (
      property: background-image,
      class: bg,
      values: (gradient: var(--#{$variable-prefix}gradient))
    ),
    */
    // scss-docs-start utils-interaction
    "user-select": (
      property: user-select,
      values: all auto none
    ),
    "pointer-events": (
      property: pointer-events,
      class: pe,
      values: none auto,
    ),
    // scss-docs-end utils-interaction
    // scss-docs-start utils-border-radius
    "rounded": (
      property: border-radius,
      class: rounded,
      values: (
        null: $border-radius,
        0: 0,
        1: $border-radius-sm,
        2: $border-radius,
        3: $border-radius-lg,
        circle: 50%,
        pill: $border-radius-pill
      )
    ),
    "rounded-top": (
      property: border-top-left-radius border-top-right-radius,
      class: rounded-top,
      values: (null: $border-radius)
    ),
    "rounded-end": (
      property: border-top-right-radius border-bottom-right-radius,
      class: rounded-end,
      values: (null: $border-radius)
    ),
    "rounded-bottom": (
      property: border-bottom-right-radius border-bottom-left-radius,
      class: rounded-bottom,
      values: (null: $border-radius)
    ),
    "rounded-start": (
      property: border-bottom-left-radius border-top-left-radius,
      class: rounded-start,
      values: (null: $border-radius)
    ),
    // scss-docs-end utils-border-radius
    // scss-docs-start utils-visibility
    "visibility": (
      property: visibility,
      class: null,
      values: (
        visible: visible,
        invisible: hidden,
      )
    )
    // scss-docs-end utils-visibility
  ),
  $utilities
);

// bootstrap/scss/helpers
.text-truncate {
  @include text-truncate;
}

// bootstrap/scss/utilities/api

// Loop over each utility property
@each $key, $utility in $utilities {
  // The utility can be disabled with `false`, thus check if the utility is a map first
  // Only proceed if responsive media queries are enabled or if it's the base media query
  @if type-of($utility) == "map" {
    @include generate-utility($utility);
  }
}
