fr(selector, name, i = '')
  unquote(replace(unquote('<i>'), unquote(i), replace(unquote('<name>'), unquote(name), unquote(selector))))

fe(selector, name, noProc, i = '')
  if noProc
    return fr(selector, name, i)
  return unquote(join(',', fr(selector, '', i) fr(selector, name, i)))

fg($name, $size)
  $noProcZero = $size == 0
  $noProcNotZero = $size > 0
  @media (min-width $size)
    {fe('.flex<name>-', $name, $noProcNotZero)}
      &block
        display block
      &inline
        display inline-block

    $all-{$name}-inline-flex
      display inline-flex
    $row-{$name}-reverse
      flex-direction row-reverse
    $column-{$name}-reverse
      flex-direction column-reverse

    for $space, $value in $spaces
      .q-pa{$name}-{$space}
        padding: $value.y $value.x
      .q-pl{$name}-{$space}
        padding-left: $value.x
      .q-pr{$name}-{$space}
        padding-right: $value.x
      .q-pt{$name}-{$space}
        padding-top: $value.y
      .q-pb{$name}-{$space}
        padding-bottom: $value.y
      .q-px{$name}-{$space}
        @extends .q-pl{$name}-{$space}, .q-pr{$name}-{$space}
      .q-py{$name}-{$space}
        @extends .q-pt{$name}-{$space}, .q-pb{$name}-{$space}
      .q-ma{$name}-{$space}
        margin: $value.y $value.x
      .q-ml{$name}-{$space}
        margin-left: $value.x
      .q-mr{$name}-{$space}
        margin-right: $value.x
      .q-mt{$name}-{$space}
        margin-top: $value.y
      .q-mb{$name}-{$space}
        margin-bottom: $value.y
      .q-mx{$name}-{$space}
        @extends .q-ml{$name}-{$space}, .q-mr{$name}-{$space}
      .q-my{$name}-{$space}
        @extends .q-mt{$name}-{$space}, .q-mb{$name}-{$space}

    .q-ml{$name}-auto
      margin-left auto
    .q-mr{$name}-auto
      margin-right auto
    .q-mx{$name}-auto
      @extends .q-ml{$name}-auto, .q-mr{$name}-auto

    .row, .column, .flex
      if $noProcNotZero
        {fr('&.inline<name>', $name)}
          @extends $all-{$name}-inline-flex
      {fr('&<name>', $name)}
        display flex
        flex-wrap wrap
        {fe('&.inline<name>', $name, $noProcZero)}
          @extends $all-{$name}-inline-flex

    .row
      if $noProcNotZero
        {fr('&.reverse<name>', $name)}
          @extends $row-{$name}-reverse
      {fr('&<name>', $name)}
        flex-direction row
        {fe('&.reverse<name>', $name, $noProcZero)}
          @extends $row-{$name}-reverse

    .column
      if $noProcNotZero
        {fr('&.reverse<name>', $name)}
          @extends $column-{$name}-reverse
      {fr('&<name>', $name)}
        flex-direction column
        {fe('&.reverse<name>', $name, $noProcZero)}
          @extends $column-{$name}-reverse

    {fr('.wrap<name>', $name)}
      flex-wrap wrap
    {fr('.no-wrap<name>', $name)}
      flex-wrap nowrap
    {fr('.reverse-wrap<name>', $name)}
      flex-wrap wrap-reverse

    {fr('.order<name>-', $name)}
      &first
        order -10000
      &last
        order 10000
      &none
        order 0

    {fr('.justify<name>-', $name)}
      &start
        justify-content flex-start
      &end
        justify-content flex-end
      &center
        justify-content center
      &between
        justify-content space-between
      &around
        justify-content space-around

    {fr('.items<name>-', $name)}
      &start
        align-items flex-start
      &end
        align-items flex-end
      &center
        align-items center
      &baseline
        align-items baseline
      &stretch
        align-items stretch

    {fr('.content<name>-', $name)}
      &start
        align-content flex-start
      &end
        align-content flex-end
      &center
        align-content center
      &between
        align-content space-between
      &around
        align-content space-around

    {fr('.self<name>-', $name)}
      &start
        align-self flex-start
      &end
        align-self flex-end
      &center
        align-self center
      &baseline
        align-self baseline
      &stretch
        align-self stretch

    {fr('.flex<name>-center', $name)}
      @extends .items{$name}-center
      @extends .justify{$name}-center

    for $gname, $gsize in $flex-gutter
      {fr('.q-gutter<name>', $name)}
        &-x-{$gname}
          margin-left (- $gsize)
          > *
            margin-left $gsize
        &-y-{$gname}
          margin-top (- $gsize)
          > *
            margin-top $gsize
        &-{$gname}
          @extends .q-gutter{$name}-x-{$gname}, .q-gutter{$name}-y-{$gname}
      {fr('.q-col-gutter<name>', $name)}
        &-x-{$gname}
          margin-left (- $gsize)
          > *
            padding-left ($gsize)
        &-y-{$gname}
          margin-top (- $gsize)
          > *
            padding-top ($gsize)
        &-{$gname}
          @extends .q-col-gutter{$name}-x-{$gname}, .q-col-gutter{$name}-y-{$gname}

    for $name2, $size2 in $sizes
      if $size >= $size2
        $name2c = s('-%s', unquote($name2))
        $noProcNotZero2 = $size2 > 0

        for $i in (0..$flex-cols)
          $ic = s('%s', $i)

          {fr('.row<name>', $name)}
            {fe('> .col<name>-<i>', $name2c, $noProcNotZero2, $ic)}
              height auto
              width (round($i / $flex-cols * 100, 4))%
            {fe('> .offset<name>-<i>', $name2c, $noProcNotZero2, $ic)}
              margin-left (round($i / $flex-cols * 100, 4))%

          {fr('.column<name>', $name)}
            {fe('> .col<name>-<i>', $name2c, $noProcNotZero2, $ic)}
              height (round($i / $flex-cols * 100, 4))%
              width auto

for $name, $size in $sizes
  fg(s('-%s', unquote($name)), $size)
