Fix with current category

Fix with current category

<template>
  <div id="Category">
    Core Category
  </div>
</template>

<script>
import builder from 'bodybuilder'

import { breadCrumbRoutes } from 'src/lib/filters'
import Meta from 'src/lib/meta'
import EventBus from 'src/event-bus/event-bus'
import Sidebar from '../components/core/blocks/Category/Sidebar.vue'
import ProductListing from '../components/core/ProductListing.vue'
import Breadcrumbs from '../components/core/Breadcrumbs.vue'
import { optionLabel } from 'src/store/modules/attribute'

function baseFilterQuery (filters, parentCategory) {
  let searchProductQuery = builder().query('range', 'price', { 'gt': 0 }).andFilter('range', 'visibility', { 'gte': 3, 'lte': 4 }/** Magento visibility in search & categories */).orFilter('term', 'category.category_id', parentCategory.id)  // FIXME!

  // add filters to query
  for (let attrToFilter of filters) {
    if (attrToFilter !== 'price') {
      searchProductQuery = searchProductQuery.aggregation('terms', attrToFilter)
    } else {
      searchProductQuery = searchProductQuery.aggregation('terms', attrToFilter)
      searchProductQuery.aggregation('range', 'price', {
        ranges: [
          { from: 0, to: 50 },
          { from: 50, to: 100 },
          { from: 100, to: 150 },
          { from: 150 }
        ]
      })
    }
  }

  if (parentCategory.children_data) {
    let recurCatFinderBuilder = (category, searchProductQuery) => {
      if (!category) {
        return searchProductQuery
      }

      if (!category.children_data) {
        return searchProductQuery
      }

      for (let sc of category.children_data) {
        if (sc && sc.id) {
          searchProductQuery = searchProductQuery.orFilter('term', 'category.category_id', sc.id)
        }
        return recurCatFinderBuilder(sc, searchProductQuery)
      }

      return searchProductQuery
    }
    recurCatFinderBuilder(parentCategory, searchProductQuery)
  }

  return searchProductQuery
}

function filterData ({ populateAggregations = false, filters = [], searchProductQuery, store, route, offset = 0, pageSize = 50 }) {
  return store.dispatch('product/list', {
    query: searchProductQuery.build(),
    start: offset,
    size: pageSize
  }).then(function (res) {
    if (populateAggregations === true) { // populate filter aggregates
      for (let attrToFilter of filters) { // fill out the filter options
        store.state.category.filters[attrToFilter] = []

        if (attrToFilter !== 'price') {
          for (let option of res.aggregations['agg_terms_' + attrToFilter].buckets) {
            store.state.category.filters[attrToFilter].push({
              id: option.key,
              label: optionLabel(store.state.attribute, { attributeKey: attrToFilter, optionId: option.key })
            })
          }
        } else { // special case is range filter for prices
          let index = 0
          let count = res.aggregations['agg_range_' + attrToFilter].buckets.length
          for (let option of res.aggregations['agg_range_' + attrToFilter].buckets) {
            store.state.category.filters[attrToFilter].push({
              id: option.key,
              from: option.from,
              to: option.to,
              label: (index === 0 || (index === count - 1)) ? (option.to ? '< $' + option.to : '> $' + option.from) : '$' + option.from + (option.to ? ' - ' + option.to : '')// TODO: add better way for formatting, extract currency sign
            })
            index++
          }
        }
      }
    }
    return res
  }).catch((err) => {
    console.error(err)
    EventBus.$emit('notification', {
      type: 'warning',
      message: 'No products synchronized for this category. Please come back while online!',
      action1: { label: 'OK', action: 'close' }
    })
  })
}

export default {
  name: 'category',
  mixins: [Meta],
  meta () {
    return {
      title: this.$store.state.category.current.name
    }
  },
  methods: {
    fetchData ({ store, route }) {
      let self = this
      let searchProductQuery = baseFilterQuery(Object.keys(self.filters), store.state.category.current)

      if (self.category) { // fill breadcrumb data - TODO: extract it to a helper to be used on product page
        EventBus.$emit('current-category-changed', store.state.category.current_path)
        store.dispatch('attribute/list', { // load filter attributes for this specific category
          filterValues: Object.keys(self.filters)// TODO: assign specific filters/ attribute codes dynamicaly to specific categories
        })
      }
      filterData({ searchProductQuery: searchProductQuery, populateAggregations: true, store: store, route: route, ofset: self.pagination.offset, pageSize: self.pagination.pageSize, filters: Object.keys(self.filters) })
    },

    validateRoute ({store, route}) {
      let self = this
      if (store == null) {
        store = self.$store
      }
      if (route == null) {
        route = self.$route
      }
      let slug = route.params.slug

      store.dispatch('category/single', { key: 'slug', value: slug }).then((category) => {
        store.state.category.breadcrumbs.routes = breadCrumbRoutes(store.state.category.current_path)
        self.setMeta()

        if (!self.category) {
          self.$router.push('/')
        } else {
          self.fetchData({store: store, route: route})
        }
      })

    }
  },
  watch: {
    '$route': 'validateRoute'
  },

  asyncData ({ store, route }) { // this is for SSR purposes to prefetch data
    return new Promise((resolve, reject) => {
      const defaultFilters = ['color', 'size', 'price']
      store.dispatch('category/list', {}).then((categories) => {
        store.dispatch('attribute/list', { // load filter attributes for this specific category
          filterValues: defaultFilters// TODO: assign specific filters/ attribute codes dynamicaly to specific categories
        }).then((attrs) => {
          store.dispatch('category/single', { key: 'slug', value: route.params.slug }).then((parentCategory) => {
            console.log('Loading products list in SSR')
            store.dispatch('meta/set', { title: store.state.category.current.name })
            filterData({ searchProductQuery: baseFilterQuery(defaultFilters, parentCategory), populateAggregations: true, store: store, route: route, ofset: 0, pageSize: 50, filters: defaultFilters }).then((res) => {
              store.state.category.breadcrumbs.routes = breadCrumbRoutes(store.state.category.current_path)
              return resolve()
            })
          })
        })
      })
    })
  },
  beforeMount () {
    let self = this // TODO: refactor it to bind()
    EventBus.$on('filter-changed-category', (filterOption) => { // slection of product variant on product page
      console.log(filterOption)
      if (self.filterSet[filterOption.attribute_code]) {
        delete self.filterSet[filterOption.attribute_code]
      } else {
        self.filterSet[filterOption.attribute_code] = filterOption
      }

      let filterQr = baseFilterQuery(Object.keys(self.filters), this.$store.state.category.current)
      for (let code of Object.keys(self.filterSet)) {
        const filter = self.filterSet[code]

        if (filter.attribute_code !== 'price') {
          filterQr = filterQr.andFilter('match', filter.attribute_code, filter.id)
        } else { // multi should be possible filter here?
          const rangeqr = {}
          if (filter.from) {
            rangeqr['gte'] = filter.from
          }
          if (filter.to) {
            rangeqr['lte'] = filter.to
          }

          filterQr = filterQr.andFilter('range', filter.attribute_code, rangeqr)
        }
      }
      filterData({ populateAggregations: false, searchProductQuery: filterQr, store: self.$store, route: self.$route, offset: self.pagination.offset, pageSize: self.pagination.pageSize, filters: Object.keys(self.filters) }) // because already aggregated
    })
  },

  computed: {
    products () {
      return this.$store.state.product.list.items
    },
    isCategoryEmpty () {
      return (!(this.$store.state.product.list.items) || this.$store.state.product.list.items.length === 0)
    },
    category () {
      return this.$store.state.category.current
    },
    aggregations () {
      return this.$store.state.product.list.aggregations
    },
    filters () {
      return this.$store.state.category.filters
    },
    breadcrumbs () {
      return this.$store.state.category.breadcrumbs
    }

  },

  data () {
    return {
      pagination: {
        pageSize: 18,
        offset: 0
      },
      filterSet: {} // filter set selected by user
    }
  },
  components: {
    ProductListing,
    Breadcrumbs,
    Sidebar
  }
}
</script>

<template>
  <div id="Category">
    Core Category
  </div>
</template>

<script>
import builder from 'bodybuilder'

import { breadCrumbRoutes } from 'src/lib/filters'
import Meta from 'src/lib/meta'
import EventBus from 'src/event-bus/event-bus'
import Sidebar from '../components/core/blocks/Category/Sidebar.vue'
import ProductListing from '../components/core/ProductListing.vue'
import Breadcrumbs from '../components/core/Breadcrumbs.vue'
import { optionLabel } from 'src/store/modules/attribute'

function baseFilterQuery (filters, parentCategory) {
  let searchProductQuery = builder().query('range', 'price', { 'gt': 0 }).andFilter('range', 'visibility', { 'gte': 3, 'lte': 4 }/** Magento visibility in search & categories */).orFilter('term', 'category.category_id', parentCategory.id)  // FIXME!

  // add filters to query
  for (let attrToFilter of filters) {
    if (attrToFilter !== 'price') {
      searchProductQuery = searchProductQuery.aggregation('terms', attrToFilter)
    } else {
      searchProductQuery = searchProductQuery.aggregation('terms', attrToFilter)
      searchProductQuery.aggregation('range', 'price', {
        ranges: [
          { from: 0, to: 50 },
          { from: 50, to: 100 },
          { from: 100, to: 150 },
          { from: 150 }
        ]
      })
    }
  }

  if (parentCategory.children_data) {
    let recurCatFinderBuilder = (category, searchProductQuery) => {
      if (!category) {
        return searchProductQuery
      }

      if (!category.children_data) {
        return searchProductQuery
      }

      for (let sc of category.children_data) {
        if (sc && sc.id) {
          searchProductQuery = searchProductQuery.orFilter('term', 'category.category_id', sc.id)
        }
        return recurCatFinderBuilder(sc, searchProductQuery)
      }

      return searchProductQuery
    }
    recurCatFinderBuilder(parentCategory, searchProductQuery)
  }

  return searchProductQuery
}

function filterData ({ populateAggregations = false, filters = [], searchProductQuery, store, route, offset = 0, pageSize = 50 }) {
  return store.dispatch('product/list', {
    query: searchProductQuery.build(),
    start: offset,
    size: pageSize
  }).then(function (res) {
    if (populateAggregations === true) { // populate filter aggregates
      for (let attrToFilter of filters) { // fill out the filter options
        store.state.category.filters[attrToFilter] = []

        if (attrToFilter !== 'price') {
          for (let option of res.aggregations['agg_terms_' + attrToFilter].buckets) {
            store.state.category.filters[attrToFilter].push({
              id: option.key,
              label: optionLabel(store.state.attribute, { attributeKey: attrToFilter, optionId: option.key })
            })
          }
        } else { // special case is range filter for prices
          let index = 0
          let count = res.aggregations['agg_range_' + attrToFilter].buckets.length
          for (let option of res.aggregations['agg_range_' + attrToFilter].buckets) {
            store.state.category.filters[attrToFilter].push({
              id: option.key,
              from: option.from,
              to: option.to,
              label: (index === 0 || (index === count - 1)) ? (option.to ? '< $' + option.to : '> $' + option.from) : '$' + option.from + (option.to ? ' - ' + option.to : '')// TODO: add better way for formatting, extract currency sign
            })
            index++
          }
        }
      }
    }
    return res
  }).catch((err) => {
    console.error(err)
    EventBus.$emit('notification', {
      type: 'warning',
      message: 'No products synchronized for this category. Please come back while online!',
      action1: { label: 'OK', action: 'close' }
    })
  })
}

export default {
  name: 'category',
  mixins: [Meta],
  meta () {
    return {
      title: this.$store.state.category.current.name
    }
  },
  methods: {
    fetchData ({ store, route }) {
      let self = this
      let searchProductQuery = baseFilterQuery(Object.keys(self.filters), store.state.category.current)

      if (self.category) { // fill breadcrumb data - TODO: extract it to a helper to be used on product page
        EventBus.$emit('current-category-changed', store.state.category.current_path)
        store.dispatch('attribute/list', { // load filter attributes for this specific category
          filterValues: Object.keys(self.filters)// TODO: assign specific filters/ attribute codes dynamicaly to specific categories
        })
      }
      filterData({ searchProductQuery: searchProductQuery, populateAggregations: true, store: store, route: route, ofset: self.pagination.offset, pageSize: self.pagination.pageSize, filters: Object.keys(self.filters) })
    },

    validateRoute ({store, route}) {
      let self = this
      if (store == null) {
        store = self.$store
      }
      if (route == null) {
        route = self.$route
      }
      let slug = route.params.slug

      store.dispatch('category/list', {}).then((categories) => {
        store.dispatch('category/single', { key: 'slug', value: slug }).then((category) => {
          store.state.category.breadcrumbs.routes = breadCrumbRoutes(store.state.category.current_path)
          self.setMeta()

          if (!self.category) {
            self.$router.push('/')
          }
        })
      })
      self.fetchData({store: store, route: route})
    }
  },
  watch: {
    '$route': 'validateRoute'
  },

  asyncData ({ store, route }) { // this is for SSR purposes to prefetch data
    return new Promise((resolve, reject) => {
      const defaultFilters = ['color', 'size', 'price']
      store.dispatch('category/list', {}).then((categories) => {
        store.dispatch('attribute/list', { // load filter attributes for this specific category
          filterValues: defaultFilters// TODO: assign specific filters/ attribute codes dynamicaly to specific categories
        }).then((attrs) => {
          store.dispatch('category/single', { key: 'slug', value: route.params.slug }).then((parentCategory) => {
            console.log('Loading products list in SSR')
            store.dispatch('meta/set', { title: store.state.category.current.name })
            filterData({ searchProductQuery: baseFilterQuery(defaultFilters, parentCategory), populateAggregations: true, store: store, route: route, ofset: 0, pageSize: 50, filters: defaultFilters }).then((res) => {
              store.state.category.breadcrumbs.routes = breadCrumbRoutes(store.state.category.current_path)
              return resolve()
            })
          })
        })
      })
    })
  },
  beforeMount () {
    let self = this // TODO: refactor it to bind()
    EventBus.$on('filter-changed-category', (filterOption) => { // slection of product variant on product page
      console.log(filterOption)
      if (self.filterSet[filterOption.attribute_code]) {
        delete self.filterSet[filterOption.attribute_code]
      } else {
        self.filterSet[filterOption.attribute_code] = filterOption
      }

      let filterQr = baseFilterQuery(Object.keys(self.filters), this.$store.state.category.current)
      for (let code of Object.keys(self.filterSet)) {
        const filter = self.filterSet[code]

        if (filter.attribute_code !== 'price') {
          filterQr = filterQr.andFilter('match', filter.attribute_code, filter.id)
        } else { // multi should be possible filter here?
          const rangeqr = {}
          if (filter.from) {
            rangeqr['gte'] = filter.from
          }
          if (filter.to) {
            rangeqr['lte'] = filter.to
          }

          filterQr = filterQr.andFilter('range', filter.attribute_code, rangeqr)
        }
      }
      filterData({ populateAggregations: false, searchProductQuery: filterQr, store: self.$store, route: self.$route, offset: self.pagination.offset, pageSize: self.pagination.pageSize, filters: Object.keys(self.filters) }) // because already aggregated
    })
  },

  computed: {
    products () {
      return this.$store.state.product.list.items
    },
    isCategoryEmpty () {
      return (!(this.$store.state.product.list.items) || this.$store.state.product.list.items.length === 0)
    },
    category () {
      return this.$store.state.category.current
    },
    aggregations () {
      return this.$store.state.product.list.aggregations
    },
    filters () {
      return this.$store.state.category.filters
    },
    breadcrumbs () {
      return this.$store.state.category.breadcrumbs
    }

  },

  data () {
    return {
      pagination: {
        pageSize: 18,
        offset: 0
      },
      filterSet: {} // filter set selected by user
    }
  },
  components: {
    ProductListing,
    Breadcrumbs,
    Sidebar
  }
}
</script>


The ol' switcheroo

The ol' switcheroo

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NathanielDavid/Sumie.git/'


Temporarily resolves #12

Temporarily resolves #12


fix the timeLines sort function, change sorted by date

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/joriscai/myblog-vue.git/'


提交了signup

提交了signup

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/yickli/PublicClassroomSystem.git/'


iPhone screen size 🙃

iPhone screen size 🙃

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/paulstraw/paulstraw.com.git/'


Add step support for markdown

Add step support for markdown

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/JosefFriedrich-nodejs/baldr.git/'


Increase side border z-index

Increase side border z-index

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/wappulehti-apy/diilikone-front-2017.git/'


Tweaked the project search to not always return everything

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/codeweavers/Consign.git/'


Removed the test toast

Removed the test toast


feat(Hero): add hero component to render the header

<template>

gh stalker

                <search></search>

</template>

error: pathspec 'src/components/Hero.vue' did not match any file(s) known to git


Emit change & input events from mdTextarea

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/praneetloke/vue-material.git/'


Polyfills sticky position within a watcher

<template>

    <gl-loading-icon
      v-if="isLoading"
      :size="2"
      class="js-job-loading qa-loading-animation prepend-top-20"
    />

    <template v-else-if="shouldRenderContent">

            <ci-header
              :status="job.status"
              :item-id="job.id"
              :time="headerTime"
              :user="job.user"
              :actions="headerActions"
              :has-sidebar-button="true"
              :should-render-triggered-label="shouldRenderTriggeredLabel"
              :item-name="__('Job')"
              @clickedSidebarButton="toggleSidebar"
            />

          <callout
            v-if="shouldRenderCalloutMessage"
            :message="job.callout_message"
          />

        <stuck-block
          v-if="job.stuck"
          class="js-job-stuck"
          :has-no-runners-for-project="hasRunnersForProject"
          :tags="job.tags"
          :runners-path="runnerSettingsUrl"
        />

        <environments-block
          v-if="hasEnvironment"
          class="js-job-environment"
          :deployment-status="job.deployment_status"
          :icon-status="job.status"
        />

        <erased-block
          v-if="job.erased_at"
          class="js-job-erased-block"
          :user="job.erased_by"
          :erased-at="job.erased_at"
        />

          <icon
            name="lock"
            class="align-text-bottom"
          />

          {{ __('This job is archived. Only the complete pipeline can be retried.') }}

          <log-top-bar
            :class="{
              'sidebar-expanded': isSidebarOpen,
              'sidebar-collapsed': !isSidebarOpen,
              'has-archived-block': job.archived
            }"
            :erase-path="job.erase_path"
            :size="traceSize"
            :raw-path="job.raw_path"
            :is-scroll-bottom-disabled="isScrollBottomDisabled"
            :is-scroll-top-disabled="isScrollTopDisabled"
            :is-trace-size-visible="isTraceSizeVisible"
            :is-scrolling-down="isScrollingDown"
            @scrollJobLogTop="scrollTop"
            @scrollJobLogBottom="scrollBottom"
          />
          <log
            :trace="trace"
            :is-complete="isTraceComplete"
          />

        <empty-state
          v-if="!hasTrace"
          class="js-job-empty-state"
          :illustration-path="emptyStateIllustration.image"
          :illustration-size-class="emptyStateIllustration.size"
          :title="emptyStateIllustration.title"
          :content="emptyStateIllustration.content"
          :action="emptyStateAction"
        />

    </template>

    <sidebar
      v-if="shouldRenderContent"
      class="js-job-sidebar"
      :class="{
        'right-sidebar-expanded': isSidebarOpen,
        'right-sidebar-collapsed': !isSidebarOpen
      }"
      :runner-help-url="runnerHelpUrl"
    />

</template>


Removed unused .vue file

Removed unused .vue file

<template>

        {{title_bar.title}}
        Home

        {{user.first_name}}

              {{item.text}}

        {{ item.text }}

</template>


prevent scrolling on calendar page

prevent scrolling on calendar page

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aligerum/clockwork.git/'


Adds validator function for Perseus item data.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/christianmemije/kolibri-exercise-perseus-plugin.git/'


栏目列表添加类型

栏目列表添加类型

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/3tnet/t-cms.git/'


Add drought map. Entire US only?

Add drought map. Entire US only?

<template>
  <svg></svg>
</template>

<script>
  import * as d3 from 'd3';
  import {tip} from './utilities/tip';

  export default {
    name: 'DroughtMap',

    data() {
      return {
        graph_height: 500 - this.margins().top -this. margins().bottom,
        graph_width: 600 - this.margins().left - this.margins().right,
        graph_translate: `translate(${this.margins().left},${this.margins().top})`
      }
    },

    props: {
      dataFile: String,
      mapFile: String
    },

    methods: {
      draw() {
        let vm = this;
        let tip_div = tip.tipDiv();

        let svg = d3.select('#map');
        let width = svg.attr('width');
        let height = svg.attr('height');

        let scale = 1,
          projection = d3.geoAlbers()
            .scale(scale)
            .translate([0,0]);

        d3.queue()
          .defer(d3.json, `static/data/maps/${this.mapFile}`)
         // .defer(d3.csv, `static/data/drought/${this.dataFile}`)
          .await(function(error, map, stations, data) {
            let path = d3.geoPath().projection(projection);
            let bounds = path.bounds(map);
            scale = .95 / Math.max((bounds[1][0] - bounds[0][0]) / width, (bounds[1][1] - bounds[0][1]) / height);

            let state = vm.whichState;

            let translation = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2,
              (height - scale * (bounds[1][1] + bounds[0][1])) / 2];

            // update projection
            projection = d3.geoAlbersUsa()
              .scale(scale)
              .translate(translation);
            path = path.projection(projection);

            let maps = svg.selectAll('path')
              .data(map.features).call(zoom);

            maps.enter()
              .append('path')
              .merge(maps)
              .attr('d', path);

            maps.exit().remove();
          });
      }
    }
  }
</script>

error: pathspec 'src/components/DroughtMap.vue' did not match any file(s) known to git


docs(kitchen): add VTabs pan (#6239)

docs(kitchen): add VTabs pan (#6239)

<template>
  <v-container>
    <v-layout column>
      <main-header>Tabs</main-header>

      <core-title>Simple</core-title>
      <core-section>
        <v-tabs
          v-model="active1"
        >
          <v-tab
            v-for="n in 3"
            :key="n"
            ripple
          >
            Item {{ n }}

          </v-tab>
          <v-tab-item
            v-for="n in 3"
            :key="n"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>
      </core-section>

      <core-title>Colors & slider colors</core-title>
      <core-section>
        <v-tabs
          v-model="active2"
          color="cyan"
          dark
          slider-color="yellow"
        >
          <v-tab
            v-for="n in 3"
            :key="n"
            ripple
          >
            Item {{ n }}

          </v-tab>
          <v-tab-item
            v-for="n in 3"
            :key="n"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>

        <v-tabs
          v-model="active3"
          color="success"
          dark
          slider-color="error"
        >
          <v-tab
            v-for="n in 3"
            :key="n"
            ripple
          >
            Item {{ n }}

          </v-tab>
          <v-tab-item
            v-for="n in 3"
            :key="n"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>

        <v-tabs
          v-model="active4"
          color="cyan lighten-2"
          dark
          slider-color="orange"
        >
          <v-tab
            v-for="n in 3"
            :key="n"
            ripple
          >
            Item {{ n }}

          </v-tab>
          <v-tab-item
            v-for="n in 3"
            :key="n"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>
      </core-section>

      <core-title>Programmatic control</core-title>
      <core-section>
        <v-tabs
          v-model="active5"
        >
          <v-tab
            v-for="n in 3"
            :key="n"
            ripple
          >
            Item {{ n }}

          </v-tab>
          <v-tab-item
            v-for="n in 3"
            :key="n"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>

        <div class="text-xs-center mt-3">
          <v-btn @click="next">next tab</v-btn>
        </div>
      </core-section>

      <core-title>Fixed</core-title>
      <core-section>
        <v-tabs fixed-tabs>
          <v-tab
            v-for="n in 3"
            :key="n"
          >
            Item {{ n }}
          </v-tab>
        </v-tabs>
      </core-section>

      <core-title>Right aligned</core-title>
      <core-section>
        <v-tabs right>
          <v-tab>
            <v-icon>mdi-face</v-icon>
            Profile
          </v-tab>
        </v-tabs>
      </core-section>

      <core-title>Icons and text</core-title>
      <core-section>
        <v-tabs
          centered
          color="cyan"
          dark
          icons-and-text
        >
          <v-tabs-slider color="yellow" />

          <v-tab href="#tab-1">
            Recents
            <v-icon>mdi-phone</v-icon>
          </v-tab>

          <v-tab href="#tab-2">
            Favorites
            <v-icon>mdi-heart</v-icon>
          </v-tab>

          <v-tab href="#tab-3">
            Nearby
            <v-icon>mdi-account-box</v-icon>
          </v-tab>

          <v-tab-item
            v-for="i in 3"
            :key="i"
            :value="'tab-' + i"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>
      </core-section>

      <core-title>Grow</core-title>
      <core-section>
        <v-tabs
          centered
          color="cyan"
          dark
          icons-and-text
          grow
        >
          <v-tabs-slider color="yellow" />

          <v-tab href="#tab-1">
            Recents
            <v-icon>mdi-phone</v-icon>
          </v-tab>

          <v-tab href="#tab-2">
            Favorites
            <v-icon>mdi-heart</v-icon>
          </v-tab>

          <v-tab href="#tab-3">
            Nearby
            <v-icon>mdi-account-box</v-icon>
          </v-tab>

          <v-tab-item
            v-for="i in 3"
            :key="i"
            :value="'tab-' + i"
          >
            <v-card flat>
              <v-card-text>{{ text }}</v-card-text>
            </v-card>
          </v-tab-item>
        </v-tabs>
      </core-section>

      <core-title>Pagination</core-title>
      <core-section>
        <v-tabs
          dark
          color="cyan"
          show-arrows
        >
          <v-tabs-slider color="yellow" />

          <v-tab
            v-for="i in 30"
            :key="i"
            :href="'#tab-' + i"
          >
            Item {{ i }}
          </v-tab>

          <v-tabs-items>
            <v-tab-item
              v-for="i in 30"
              :key="i"
              :value="'tab-' + i"
            >
              <v-card flat>
                <v-card-text>{{ text }}</v-card-text>
              </v-card>
            </v-tab-item>
          </v-tabs-items>
        </v-tabs>
      </core-section>

      <core-title>Custom icons</core-title>
      <core-section>
        <v-tabs
          color="cyan"
          dark
          next-icon="mdi-arrow-right-bold-box-outline"
          prev-icon="mdi-arrow-left-bold-box-outline"
          show-arrows
        >
          <v-tabs-slider color="yellow" />
          <v-tab
            v-for="i in 30"
            :key="i"
            :href="'#tab-' + i"
          >
            Item {{ i }}
          </v-tab>

          <v-tabs-items>
            <v-tab-item
              v-for="i in 30"
              :key="i"
              :value="'tab-' + i"
            >
              <v-card flat>
                <v-card-text>{{ text }}</v-card-text>
              </v-card>
            </v-tab-item>
          </v-tabs-items>
        </v-tabs>
      </core-section>
    </v-layout>
  </v-container>
</template>

<script>
  export default {
    name: 'Tabs',

    data: () => ({
      active1: null,
      active2: null,
      active3: null,
      active4: null,
      active5: null,
      text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
    }),

    methods: {
      next () {
        const active = parseInt(this.active5)
        this.active5 = (active < 2 ? active + 1 : 0)
      }
    }
  }
</script>

error: pathspec 'packages/kitchen/src/pan/Tabs.vue' did not match any file(s) known to git


fix: prefix sidebar

fix: prefix sidebar

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/buckless-team/admin.git/'


feature: added Palette and moved a lot of DndPanel.vue logic to new component DndPalette.vue

error: pathspec 'frontend/src/components/zetalayout/model/model-editor/components/dndPanel/DndPalette.vue' did not match any file(s) known to git


update title for how are you using... to use new props on base wrapper

<template>

  <OnboardingStepBase
    dir="auto"
    :noBackAction="true"
    :title="$tr('howAreYouUsingKolibriTitle')"
    @continue="handleContinue"
  >
    <KRadioButton
      v-model="selected"
      style="margin-bottom: 1em"
      :value="Options.PERSONAL"
      :label="$tr('onMyOwnLabel')"
      :description="$tr('onMyOwnDescription')"
    />
    <KRadioButton
      v-model="selected"
      :value="Options.PUBLIC"
      :label="$tr('groupLearningLabel')"
      :description="$tr('groupLearningDescription')"
    />
  </OnboardingStepBase>

</template>

<script>

  import { Presets } from '../../constants';
  import OnboardingStepBase from '../OnboardingStepBase';

  const Options = Object.freeze({
    PUBLIC: 'PUBLIC',
    PERSONAL: 'PERSONAL',
  });

  export default {
    name: 'HowAreYouUsingKolibri',
    components: { OnboardingStepBase },
    data() {
      let selected;
      const { preset } = this.$store.state.onboardingData;
      if (preset === null || preset === Presets.PERSONAL) {
        selected = Options.PERSONAL;
      } else {
        selected = Options.PUBLIC;
      }
      return {
        selected,
        Options,
      };
    },
    inject: ['wizardService'],
    computed: {
      isPersonal() {
        return this.selected === Options.PERSONAL;
      },
    },
    methods: {
      handleContinue() {
        this.$store.commit('SET_FACILITY_PRESET', this.isPersonal ? Presets.PERSONAL : '');
        this.goToNextStep();
      },
      goToNextStep() {
        this.wizardService.send({ type: 'CONTINUE', value: this.isPersonal });
      },
    },
    $trs: {
      howAreYouUsingKolibriTitle: {
        message: 'How are you using Kolibri?',
        context: 'hello',
      },
      onMyOwnLabel: {
        message: 'On my own',
        context: 'Label for a radio button...',
      },
      onMyOwnDescription: {
        message:
          'For homeschooling, supplementary individual learning, and other self-directed use',
        context: 'Description',
      },
      groupLearningLabel: {
        message: 'Group learning',
        context: 'label',
      },
      groupLearningDescription: {
        message:
          'This device will need to connect with other devices using Kolibri in schools, educational programs, organizations, or other group learning settings',
        context: 'desc',
      },
    },
  };

</script>

error: pathspec 'kolibri/plugins/setup_wizard/assets/src/views/onboarding-forms/HowAreYouUsingKolibri.vue' did not match any file(s) known to git


:sparkles: IconButton

:sparkles: IconButton

<template lang="pug">
clickable.v-iconbutton(:class="{ loading, disabled }")
  button(:disabled="{ disabled: 'disabled' }")
    i(:class="iconName")
</template>

<script>
import Clickable from '@/components/Clickable';

export default {
  name: 'IconButton',
  props: ['icon', 'loading', 'disabled', 'icon-disabled'],
  components: {
    Clickable,
  },
  computed: {
    iconName() {
      if (this.loading) {
        return 'ion-load-d';
      } else if (this.disabled) {
        return this.iconDisabled ? this.iconDisabled : this.icon;
      }
      return this.icon;
    },
  },
};
</script>

<style lang="stylus" scoped>
.v-iconbutton
  display flex
  justify-content center
  line-height 1
  button
    display flex
    justify-content center
    color inherit
    font inherit
    margin 0
    padding 3px
    text-align inherit
    line-height 1
    background none
    overflow visible
    border none
    cursor pointer
    i
      min-width 1em
      text-align center
</style>

error: pathspec 'spa/src/components/IconButton.vue' did not match any file(s) known to git


fix validate field errors

fix validate field errors

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/notadd/administration.git/'


fix vertical centering on login page

fix vertical centering on login page

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aligerum/sentry.git/'


Fix details footer display

Fix details footer display

<template>
<box :title="title" icon="cubes" boxclass="box-solid" :footer="toggled">

{{dataset.title}}

                {{ _('Tags') }}:

            {{tag}}

                {{ _('Badges') }}:

            {{badges[b.kind]}}

    <dataset-form v-ref:form v-show="toggled" :dataset="dataset"></dataset-form>

        <button type="submit" class="btn btn-primary"
            @click="save($event)" v-i18n="Save"></button>

</box>
</template>

<template>
<box :title="title" icon="cubes" boxclass="box-solid">

{{dataset.title}}

                {{ _('Tags') }}:

            {{tag}}

                {{ _('Badges') }}:

            {{badges[b.kind]}}

    <dataset-form v-ref:form v-show="toggled" :dataset="dataset"></dataset-form>

        <button type="submit" class="btn btn-primary"
            @click="save($event)" v-i18n="Save"></button>

</box>
</template>


Dropdown: init

Dropdown: init

error: pathspec 'src/components/ui/Dropdown.vue' did not match any file(s) known to git


Correct link

Correct link

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/casid/mazebert-ladder.git/'


perfect logic of uninstall and install module


Update icon

Update icon

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ytet5uy4/portfolio.git/'


IE11 console test

IE11 console test

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ICJIA/icjia-gata.git/'


Initial commit

Initial commit

<template>
<b-field :label="label">
  <b-select v-model="selected">
      <option
        v-for="option in options"
        :value="option.value"
        :key="option.value">
        {{ option.label }}
      </option>
  </b-select>
</b-field>
</template>

<script>
  export default {
    name: 'qSelect',
    data() { return {
      selected: this.value,
    };},
    props: {
        'label': String,
        'value': {
            type: [String, Number, Boolean, Object, Array, Symbol, Function],
            default: null
        },
        'options': {
          type: Array,
          default: []
        }
    },
    watch:{
      selected(value) {
        this.$emit('input', value)
      }
    }
  }
</script>

error: pathspec 'src/components/form/Select.vue' did not match any file(s) known to git


fix article post ad put

fix article post ad put

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ilyq/vue-blog.git/'


remove invalid toggle option for expansion list #215

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/praneetloke/vue-material.git/'


Removed empty file

Removed empty file

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/gaspoweredkiwi/tab-tracker.git/'


Add a max-width to the channel-switcher menu.

<template>

     0">
      <ui-button
        class="app-bar-button"
        icon="view_module"
        type="secondary"
        color="white"
        :ariaLabel="$tr('switchChannels')"
        has-dropdown
        ref="buttonLarge">
        {{ currentChannelName }}
        <ui-menu
          class="channel-switcher-menu"
          contain-focus
          contains-icons
          slot="dropdown"
          :options="channelOptions"
          @close="$refs.buttonLarge.closeDropdown()"
          @select="channelSelected"/>
      </ui-button>

      <ui-icon-button
        icon="view_module"
        type="secondary"
        color="white"
        :ariaLabel="$tr('switchChannels')"
        has-dropdown
        ref="button">
        <ui-menu
          class="channel-switcher-menu"
          contain-focus
          contains-icons
          slot="dropdown"
          :options="channelOptions"
          @close="$refs.button.closeDropdown()"
          @select="channelSelected"/>
      </ui-icon-button>

</template>


get current version from url

get current version from url


Fix #179 broken search filter button

Fix #179 broken search filter button

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mplusmuseum/mplusmuseum-stories.git/'


Remove console errors.

Remove console errors.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/buccfer/redmine-timetracker.git/'


rules

rules

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/wensonchen/vuedemo.git/'


Removes feedback window

Removes feedback window

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NathanielDavid/Sumie.git/'


fixing bug. issue #869

fixing bug. issue #869

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jaceks-iRonin/vue-material-test.git/'


src: Notification, improve comments

src: Notification, improve comments

<template>
  <div :class="['notification', 'animated', type ? `is-${type}` : '']" :transition="transition" transition-mode="in-out">
    <button class="delete touchable" @click="close()"></button>

{{ title }}

    {{ message }}

</template>


Add background on hover, link on list of ingredients and variable to update

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/barprive/barprive.com.git/'


Added todo?

Added todo?

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/frontools/magnolia-megaton.git/'


finsh pay image upload feature

finsh pay image upload feature

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/joriscai/myblog-vue.git/'


设置主题名为标题名

设置主题名为标题名

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lijy91/daza-frontend.git/'


add(login): 加入login组件

add(login): 加入login组件

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/maple5233/LetsChat.git/'


fix(MdProgressSpinner): undefined navigator on SSR (#1441)

<template>
  <transition name="md-progress-spinner" appear>
    <div class="md-progress-spinner" :class="[progressClasses, $mdActiveTheme]">
      <svg
        class="md-progress-spinner-draw"
        preserveAspectRatio="xMidYMid meet"
        focusable="false"
        :viewBox="`0 0 ${mdDiameter} ${mdDiameter}`"
        :style="svgStyles">
        <circle class="md-progress-spinner-circle" cx="50%" cy="50%" :r="circleRadius" :style="circleStyles"></circle>
      </svg>
    </div>
  </transition>
</template>

<script>
  import MdComponent from 'core/MdComponent'
  import MdPropValidator from 'core/utils/MdPropValidator'
  import INDETERMINATE_ANIMATION_TEMPLATE from './MdProgressSpinnerAnimation'

  const MdProgressSpinner = {
    styleTag: null,
    diameters: new Set()
  }

  export default new MdComponent({
    name: 'MdProgressSpinner',
    props: {
      mdValue: {
        type: Number,
        default: 0
      },
      mdDiameter: {
        type: Number,
        default: 60
      },
      mdStroke: {
        type: Number,
        default: 6
      },
      mdMode: {
        type: String,
        default: 'determinate',
        ...MdPropValidator('md-mode', [
          'determinate',
          'indeterminate'
        ])
      }
    },
    computed: {
      isDeterminate () {
        return this.mdMode === 'determinate'
      },
      isIndeterminate () {
        return this.mdMode === 'indeterminate'
      },
      isIE () {
        if (!this.$isServer) {
          return navigator.userAgent.toLowerCase().includes('trident')
        }
        return false
      },
      progressClasses () {
        let animationClass = 'md-progress-spinner-indeterminate'

        if (this.isIE) {
          animationClass += '-fallback'
        }

        return {
          [animationClass]: true,
          ['md-' + this.mdMode]: true
        }
      },
      svgStyles () {
        const size = `${this.mdDiameter}px`

        return {
          width: size,
          height: size
        }
      },
      circleStyles () {
        return {
          'stroke-dashoffset': this.circleStrokeDashOffset,
          'stroke-dasharray': this.circleStrokeDashArray,
          'stroke-width': this.circleStrokeWidth,
          'animation-name': 'md-progress-spinner-stroke-rotate-' + this.mdDiameter
        }
      },
      circleRadius () {
        return (this.mdDiameter - this.mdStroke) / 2
      },
      circleStrokeWidth () {
        return this.mdStroke + 'px'
      },
      circleCircumference () {
        return 2 * Math.PI * this.circleRadius
      },
      circleStrokeDashArray () {
        return this.circleCircumference + 'px'
      },
      circleStrokeDashOffset () {
        if (this.isDeterminate) {
          return this.circleCircumference * (100 - this.mdValue) / 100 + 'px'
        }

        if (this.isIndeterminate && this.isIE) {
          return this.circleCircumference * 0.2 + 'px'
        }

        return null
      }
    },
    watch: {
      mdDiameter () {
        this.attachStyleTag()
      }
    },
    methods: {
      getAnimationCSS () {
        return INDETERMINATE_ANIMATION_TEMPLATE
            .replace(/START_VALUE/g, `${0.95 * this.circleCircumference}`)
            .replace(/END_VALUE/g, `${0.2 * this.circleCircumference}`)
            .replace(/DIAMETER/g, `${this.mdDiameter}`);
      },
      attachStyleTag () {
        let styleTag = MdProgressSpinner.styleTag

        if (!styleTag) {
          styleTag = document.getElementById('md-progress-spinner-styles')
        }

        if (!styleTag) {
          styleTag = document.createElement('style')

          styleTag.id = 'md-progress-spinner-styles'
          document.head.appendChild(styleTag)
          MdProgressSpinner.styleTag = styleTag
        }

        if (styleTag && styleTag.sheet) {
          styleTag.sheet.insertRule(this.getAnimationCSS(), 0)
        }

        MdProgressSpinner.diameters.add(this.mdDiameter)
      }
    },
    mounted () {
      this.attachStyleTag()
    }
  })
</script>

<style lang="scss">
  @import "~components/MdAnimation/variables";

  @keyframes md-progress-spinner-rotate {
    0% {
      transform: rotate(0)
    }

    100% {
      transform: rotate(360deg)
    }
  }

  @keyframes md-progress-spinner-initial-rotate {
    0% {
      opacity: 0;
      transform: rotate(-90deg) translateZ(0);
    }

    20% {
      opacity: 1;
    }

    100% {
      transform: rotate(270deg) translateZ(0);
    }
  }

  @keyframes md-progress-spinner-stroke-rotate-fallback {
    0% {
      transform: rotate(0)
    }
    25% {
      transform: rotate(1170deg)
    }
    50% {
      transform: rotate(2340deg)
    }
    75% {
      transform: rotate(3510deg)
    }
    100% {
      transform: rotate(4680deg)
    }
  }

  .md-progress-spinner {
    display: inline-flex;
    position: relative;

    &.md-indeterminate {
      animation: md-progress-spinner-rotate 2s linear infinite;

      &.md-progress-spinner-enter,
      &.md-progress-spinner-leave-active {
        transition-duration: .4s;

        .md-progress-spinner-draw {
          opacity: 0;
          transform: scale(.1);
        }
      }

      .md-progress-spinner-circle {
        animation: 4s infinite $md-transition-stand-timing;
      }
    }

    &.md-determinate {
      &.md-progress-spinner-enter-active,
      &.md-progress-spinner-leave-active {
        transition-duration: 2s;

        .md-progress-spinner-draw {
          animation: md-progress-spinner-initial-rotate 1.98s $md-transition-stand-timing forwards;
        }
      }

      .md-progress-spinner-draw {
        transition: none;
      }
    }
  }

  .md-progress-spinner-draw {
    overflow: visible;
    transform: scale(1) rotate(-90deg);
    transform-origin: center;
    transition: .4s $md-transition-stand-timing;
    will-change: opacity, transform;
  }

  .md-progress-spinner-circle {
    fill: none;
    transform-origin: center;
    transition: stroke-dashoffset .25s $md-transition-stand-timing;
    will-change: stroke-dashoffset, stroke-dasharray, stroke-width, animation-name, r;
  }
</style>

<template>
  <transition name="md-progress-spinner" appear>
    <div class="md-progress-spinner" :class="[progressClasses, $mdActiveTheme]">
      <svg
        class="md-progress-spinner-draw"
        preserveAspectRatio="xMidYMid meet"
        focusable="false"
        :viewBox="`0 0 ${mdDiameter} ${mdDiameter}`"
        :style="svgStyles">
        <circle class="md-progress-spinner-circle" cx="50%" cy="50%" :r="circleRadius" :style="circleStyles"></circle>
      </svg>
    </div>
  </transition>
</template>

<script>
  import MdComponent from 'core/MdComponent'
  import MdPropValidator from 'core/utils/MdPropValidator'
  import INDETERMINATE_ANIMATION_TEMPLATE from './MdProgressSpinnerAnimation'

  const MdProgressSpinner = {
    styleTag: null,
    diameters: new Set()
  }

  export default new MdComponent({
    name: 'MdProgressSpinner',
    props: {
      mdValue: {
        type: Number,
        default: 0
      },
      mdDiameter: {
        type: Number,
        default: 60
      },
      mdStroke: {
        type: Number,
        default: 6
      },
      mdMode: {
        type: String,
        default: 'determinate',
        ...MdPropValidator('md-mode', [
          'determinate',
          'indeterminate'
        ])
      }
    },
    computed: {
      isDeterminate () {
        return this.mdMode === 'determinate'
      },
      isIndeterminate () {
        return this.mdMode === 'indeterminate'
      },
      isIE () {
        return navigator.userAgent.toLowerCase().includes('trident')
      },
      progressClasses () {
        let animationClass = 'md-progress-spinner-indeterminate'

        if (this.isIE) {
          animationClass += '-fallback'
        }

        return {
          [animationClass]: true,
          ['md-' + this.mdMode]: true
        }
      },
      svgStyles () {
        const size = `${this.mdDiameter}px`

        return {
          width: size,
          height: size
        }
      },
      circleStyles () {
        return {
          'stroke-dashoffset': this.circleStrokeDashOffset,
          'stroke-dasharray': this.circleStrokeDashArray,
          'stroke-width': this.circleStrokeWidth,
          'animation-name': 'md-progress-spinner-stroke-rotate-' + this.mdDiameter
        }
      },
      circleRadius () {
        return (this.mdDiameter - this.mdStroke) / 2
      },
      circleStrokeWidth () {
        return this.mdStroke + 'px'
      },
      circleCircumference () {
        return 2 * Math.PI * this.circleRadius
      },
      circleStrokeDashArray () {
        return this.circleCircumference + 'px'
      },
      circleStrokeDashOffset () {
        if (this.isDeterminate) {
          return this.circleCircumference * (100 - this.mdValue) / 100 + 'px'
        }

        if (this.isIndeterminate && this.isIE) {
          return this.circleCircumference * 0.2 + 'px'
        }

        return null
      }
    },
    watch: {
      mdDiameter () {
        this.attachStyleTag()
      }
    },
    methods: {
      getAnimationCSS () {
        return INDETERMINATE_ANIMATION_TEMPLATE
            .replace(/START_VALUE/g, `${0.95 * this.circleCircumference}`)
            .replace(/END_VALUE/g, `${0.2 * this.circleCircumference}`)
            .replace(/DIAMETER/g, `${this.mdDiameter}`);
      },
      attachStyleTag () {
        let styleTag = MdProgressSpinner.styleTag

        if (!styleTag) {
          styleTag = document.getElementById('md-progress-spinner-styles')
        }

        if (!styleTag) {
          styleTag = document.createElement('style')

          styleTag.id = 'md-progress-spinner-styles'
          document.head.appendChild(styleTag)
          MdProgressSpinner.styleTag = styleTag
        }

        if (styleTag && styleTag.sheet) {
          styleTag.sheet.insertRule(this.getAnimationCSS(), 0)
        }

        MdProgressSpinner.diameters.add(this.mdDiameter)
      }
    },
    mounted () {
      this.attachStyleTag()
    }
  })
</script>

<style lang="scss">
  @import "~components/MdAnimation/variables";

  @keyframes md-progress-spinner-rotate {
    0% {
      transform: rotate(0)
    }

    100% {
      transform: rotate(360deg)
    }
  }

  @keyframes md-progress-spinner-initial-rotate {
    0% {
      opacity: 0;
      transform: rotate(-90deg) translateZ(0);
    }

    20% {
      opacity: 1;
    }

    100% {
      transform: rotate(270deg) translateZ(0);
    }
  }

  @keyframes md-progress-spinner-stroke-rotate-fallback {
    0% {
      transform: rotate(0)
    }
    25% {
      transform: rotate(1170deg)
    }
    50% {
      transform: rotate(2340deg)
    }
    75% {
      transform: rotate(3510deg)
    }
    100% {
      transform: rotate(4680deg)
    }
  }

  .md-progress-spinner {
    display: inline-flex;
    position: relative;

    &.md-indeterminate {
      animation: md-progress-spinner-rotate 2s linear infinite;

      &.md-progress-spinner-enter,
      &.md-progress-spinner-leave-active {
        transition-duration: .4s;

        .md-progress-spinner-draw {
          opacity: 0;
          transform: scale(.1);
        }
      }

      .md-progress-spinner-circle {
        animation: 4s infinite $md-transition-stand-timing;
      }
    }

    &.md-determinate {
      &.md-progress-spinner-enter-active,
      &.md-progress-spinner-leave-active {
        transition-duration: 2s;

        .md-progress-spinner-draw {
          animation: md-progress-spinner-initial-rotate 1.98s $md-transition-stand-timing forwards;
        }
      }

      .md-progress-spinner-draw {
        transition: none;
      }
    }
  }

  .md-progress-spinner-draw {
    overflow: visible;
    transform: scale(1) rotate(-90deg);
    transform-origin: center;
    transition: .4s $md-transition-stand-timing;
    will-change: opacity, transform;
  }

  .md-progress-spinner-circle {
    fill: none;
    transform-origin: center;
    transition: stroke-dashoffset .25s $md-transition-stand-timing;
    will-change: stroke-dashoffset, stroke-dasharray, stroke-width, animation-name, r;
  }
</style>


googleAutocomplete.vue file

googleAutocomplete.vue file

<script>
	export default {

		props: ['class', 'placeholder'],

		data: function ()
		{
			return {
				//input bound to autocomplete
				'address': '',
				//google autocomplete object
				'autocomplete': '',
				//google inputs retrieved
				'inputs': {
					route: 'long_name',
					country: 'long_name',
					administrative_area_level_1: 'long_name',
					locality: 'long_name',
					postal_code: 'short_name'
				},
				api: {
					domain: 'https://maps.googleapis.com/maps/api/js',
					key: gpon.google.map_key,
					libraries: 'places'
				}
			};
		},

		ready: function ()
		{
			console.log('key', this.api.key);
			window.onload = this.loadScript(
				this.api.domain + '?key=' + this.api.key + '&libraries=' + this.api.libraries,
				this.bindAutocomplete
			);
		},

		watch: {
			address: function ()
			{
				this.$dispatch('setAddress', this.address);
			}
		},

		methods:
		{
			loadScript: function(src, callback)
			{
				var script = document.createElement("script");
				document.body.appendChild(script);
				if (callback) script.onload = callback;
				script.src = src;
			},
			bindAutocomplete: function ()
			{
				this.autocomplete = new google.maps.places.Autocomplete(
			        this.$els.complete,
			        {
			            types: ['geocode']
			        }
			    );

			    this.autocomplete.addListener('place_changed', this.pipeAddress);
			},
			pipeAddress: function ()
			{
				console.log('pipe');
				var data  = {};
				var place = this.autocomplete.getPlace();

				if (place.address_components !== undefined) {

					for (var i = 0; i < place.address_components.length; i++) {

						var input = place.address_components[i].types[0];
						if (this.inputs[input]) {

							data[input] = place.address_components[i][this.inputs[input]];
						}
					}

					data = JSON.stringify(data);
					this.$dispatch('setAddress', JSON.parse(data));
				}
			},
			geolocate: function()
			{
				if (navigator.geolocation) {

					var vm = this;
					navigator.geolocation.getCurrentPosition(function(position)
					{
						var geolocation = {
							lat: position.coords.latitude,
							lng: position.coords.longitude
						};

						var circle = new google.maps.Circle({
							center: geolocation,
							radius: position.coords.accuracy
						});

						vm.autocomplete.setBounds(circle.getBounds());
					});
				}
			}
		}
	};

</script>

<template>
	<input
		type="text"
		v-bind:class="class"
		v-el:complete
		v-model="address"
		placeholder="{{ placeholder }}"
		debounce="500"
		@focus="geolocate()"
	>
</template>

error: pathspec 'googleAutocomplete.vue' did not match any file(s) known to git


Added the code samples for Demo in List Components (Multiple options, Multiple Expand) (#725)


fix(MdField): improve icon position

fix(MdField): improve icon position

<template>

    <slot />

    {{ valueLength }} / {{ state.maxlength }}

    <transition name="md-input-action" appear>
      <md-button tabindex="-1" class="md-icon-button md-dense md-input-action md-clear" @click="clearInput" v-if="hasValue && mdClearable">
        <md-clear-icon />
      </md-button>
    </transition>

    <transition name="md-input-action" appear>
      <md-button tabindex="-1" class="md-icon-button md-dense md-input-action md-toggle-password" @click="togglePassword" v-if="hasPasswordToggle">
        <md-password-off-icon v-if="state.togglePassword" />
        <md-password-on-icon v-else />
      </md-button>
    </transition>

</template>


A landing editor that allows navigation to either simple or dzi example

// Examples.vue
// Component presents a grid of options that the user can select to load a
// different type of example into the editor.
<template lang="html">

  <v-container
    fill-height
    fluid
  >
    <v-layout
      row
      fill-height
      justify-space-around
    >
      <v-flex
        xs10
        sm5
      >
        <v-card
          to="/example/dzi"
        >
          <v-card-media
            src="/static/img/dzi_example.png"
            height="200px"/>
          <v-card-title primary-title>

                Deep Zoom

                Annotate a super hi-res Deep Zoom image with multiple tiled
                layers.

          </v-card-title>
          <v-card-actions>
            <v-btn
              flat
              color="primary"> Try it out
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-flex>
      <v-flex
        xs10
        sm5
      >
        <v-card
          to="/example/simple"
        >
          <v-card-media
            src="/static/img/simple_example.png"
            height="200px"/>
          <v-card-title primary-title>

                Simple

                Annotate a standard image (no fancy Deep Zooming).

          </v-card-title>
          <v-card-actions>
            <v-btn
              flat
              color="primary"> Try it out
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-flex>
    </v-layout>
  </v-container>
</template>

error: pathspec 'src/components/editor/Examples.vue' did not match any file(s) known to git


Made the toolbar buttons an array

Made the toolbar buttons an array

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/riggerthegeek/ci-menu.git/'


add scrollbar in phone viewport

add scrollbar in phone viewport


disable ripple on buttons

disable ripple on buttons

<template>

 {{header}}

         {{subheader}}

        <ui-icon-button
        class="previous-button"
        v-show="!isFirstSet"
        :disabled="isFirstSet"
        :disable-ripple="true"
        icon="arrow_back"
        size="large" />

        <ui-icon-button
        class="next-button"
        v-show="!isLastSet"
        :disabled="isLastSet"
        :disable-ripple="true"
        icon="arrow_forward"
        size="large"/>

    <transition-group
      :style="widthOfCarousel"
      class="content-carousel-set"
      tag="div"
      @leave="slide"
      @before-enter="setStartPosition"
      @enter="slide">

          <slot
            :title="content.title"
            :thumbnail="content.thumnail"
            :kind="content.kind"
            :progress="content.progress"
            :id="content.id">

            <content-card
            :title="content.title"
            :thumbnail="content.thumbnail"
            :kind="content.kind"
            :progress="content.progress"
            :link="genLink(content.id, content.kind)"/>
          </slot>

    </transition-group>

</template>

<template>

 {{header}}

         {{subheader}}

        <ui-icon-button
        class="previous-button"
        v-show="!isFirstSet"
        :disabled="isFirstSet"
        icon="arrow_back"
        size="large" />

        <ui-icon-button
        class="next-button"
        v-show="!isLastSet"
        :disabled="isLastSet"
        icon="arrow_forward"
        size="large"/>

    <transition-group
      :style="widthOfCarousel"
      class="content-carousel-set"
      tag="div"
      @leave="slide"
      @before-enter="setStartPosition"
      @enter="slide">

          <slot
            :title="content.title"
            :thumbnail="content.thumnail"
            :kind="content.kind"
            :progress="content.progress"
            :id="content.id">

            <content-card
            :title="content.title"
            :thumbnail="content.thumbnail"
            :kind="content.kind"
            :progress="content.progress"
            :link="genLink(content.id, content.kind)"/>
          </slot>

    </transition-group>

</template>


去掉<keep-alive>

去掉<keep-alive>

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/yi28/bookList.git/'


the lib can be reloaded after page refresh

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jarvisniu/Weblab.git/'


Header select properly binds when selected.

Due to a bug in the vue-template-compiler (4369) the :value syntax will not work with selects. I've had to explicitly set the selected option to 'selected'.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/codeweavers/Consign.git/'


fix something

fix something

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/notadd/administration.git/'


[UNFINISHED] translation: component/time-picker

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/iview/iview-doc.git/'


Use proper date stuff

Use proper date stuff

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/JonathanTroyer/OC-Summer-2017-Table-Web.git/'


Add keydown listener to modal component

Add keydown listener to modal component

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mplusmuseum/mplusmuseum-stories.git/'


setting the logout

setting the logout

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cloudfreexiao/tab-tracker.git/'


fix 解决无法滚动的bug

fix 解决无法滚动的bug


chore(quasar): Add QInput debounce test page to /dev

<template>

Click "Start" then use QInput

{{ i }}

      <q-btn label="start" @click="start" />
      <q-btn label="stop" @click="stop" />

    <q-input filled v-model="text" debounce="300" label="Label" />

      {{ text }}

</template>

error: pathspec 'quasar/dev/components/form/input-debounce-test.vue' did not match any file(s) known to git


change: attribute prefix from "sv-*" to "data-*"

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/amatelus/swipevideo.git/'


Adds login functionality

Adds login functionality

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NathanielDavid/Sumie.git/'


update

update


Create Dropdown component

Create Dropdown component

<template>

    <button class="dropdown__toggle" :class="{ 'dropdown__toggle--active': isOpen }" @click="toggleDropdown">
      <slot name="button"/>
    </button>

      <slot />

</template>

error: pathspec 'lib/assets/javascripts/new-dashboard/components/Dropdowns/Dropdown.vue' did not match any file(s) known to git


Update ProxiesHttp.vue

Update ProxiesHttp.vue

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/KunTengRom/xfrps.git/'


Add OtherDecisionsGeneral component

Add OtherDecisionsGeneral component

<template>

      <normative-type></normative-type>

      <publish-via></publish-via>

</template>

error: pathspec 'n3-composer/components/specific-decision-fields/OtherDecisionsGeneral.vue' did not match any file(s) known to git


vuejs: -fixed "other" text position for checkbox #558

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/dmitrykurmanov/surveyjs.git/'


Updates attributes to accept props

Updates attributes to accept props


refactor: case sensitive

refactor: case sensitive

<template>

    JsonEditor is base on  CodeMirrorr , lint base on json-lint

      <json-editor ref="jsonEditor" v-model="value"></json-editor>

</template>

error: pathspec 'src/views/components/jsonEditor.vue' did not match any file(s) known to git


fix(MdTable): emit selected/update event only when selected items really changed (#1585)

* fix(MdTable): only emit selected / update event when selected item(s) really changed

fix #1559

* refactor(MdTable): selectedItems check changed beautify

<template>
  <md-tag-switcher :md-tag="contentTag" class="md-table">
    <slot name="md-table-toolbar" />

    <keep-alive>
      <md-table-alternate-header v-if="$scopedSlots['md-table-alternate-header'] && selectedCount">
        <slot name="md-table-alternate-header" :count="selectedCount" />
      </md-table-alternate-header>
    </keep-alive>

        <md-table-thead />

    <md-content class="md-table-content md-scrollbar" :class="contentClasses" :style="contentStyles" @scroll="setScroll">

        <md-table-thead :class="headerClasses" v-if="!mdFixedHeader && $scopedSlots['md-table-row']" />

          <slot />

          <md-table-row-ghost
            v-for="(item, index) in value"
            :key="getRowId(item[mdModelId])"
            :md-id="getRowId(item[mdModelId])"
            :md-index="index"
            :md-item="item">
            <slot name="md-table-row" :item="item" />
          </md-table-row-ghost>

              <slot name="md-table-empty-state" />

      <slot name="md-table-pagination" />
    </md-content>

    <slot v-if="value" />
  </md-tag-switcher>
</template>


group theme text and fix height of codepen example

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/praneetloke/vue-material.git/'


fixing Input docs

fixing Input docs

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jaceks-iRonin/vue-material-test.git/'


Changed the overflow-y scroll to auto

Changed the overflow-y scroll to auto

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/riggerthegeek/ci-menu.git/'


implemented app-card component

implemented app-card component

<template>

        <icon v-if="headerIcon" :name="headerIcon"></icon>
        {{ header }}

        <slot></slot>

</template>

error: pathspec 'frontend/src/components/AppCard.vue' did not match any file(s) known to git


Add component for editing/displaying menu items in our menu editor.

<template>

	<scroll-input
		:placeholder="placeholder"
		v-model="item[nestedKey]"
		@blur="validate(index)"
		@change="validate(index)"
	>
		<template slot="prepend">{{ name }}</template>
	</scroll-input>

		{{ errors[index][nestedKey].map((error) => error.message).join(' ') }}

</template>

error: pathspec 'resources/assets/js/components/menu-editor/MenuItemField.vue' did not match any file(s) known to git


add types view

add types view

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Luncher/BlogAdmin.git/'


fix(VTabs): text field icon in example

fix(VTabs): text field icon in example

<template>
  <div>
    <v-toolbar
      color="purple"
      dark
      tabs
    >
      <v-text-field
        append-icon="mic"
        class="mx-3"
        flat
        label="Search"
        prepend-inner-icon="search"
        solo-inverted
      ></v-text-field>

      <v-tabs
        slot="extension"
        v-model="tabs"
        centered
        color="transparent"
        slider-color="white"
      >
        <v-tab
          v-for="n in 3"
          :key="n"
        >
          Item {{ n }}
        </v-tab>
      </v-tabs>
    </v-toolbar>

    <v-tabs-items v-model="tabs">
      <v-tab-item
        v-for="n in 3"
        :key="n"
      >
        <v-card>
          <v-card-text>
            {{ text }}
          </v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        tabs: null,
        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
      }
    }
  }
</script>

<template>
  <div>
    <v-toolbar
      color="purple"
      dark
      tabs
    >
      <v-text-field
        append-icon="mic"
        class="mx-3"
        flat
        label="Search"
        prepend-icon="search"
        solo-inverted
      ></v-text-field>

      <v-tabs
        slot="extension"
        v-model="tabs"
        centered
        color="transparent"
        slider-color="white"
      >
        <v-tab
          v-for="n in 3"
          :key="n"
        >
          Item {{ n }}
        </v-tab>
      </v-tabs>
    </v-toolbar>

    <v-tabs-items v-model="tabs">
      <v-tab-item
        v-for="n in 3"
        :key="n"
      >
        <v-card>
          <v-card-text>
            {{ text }}
          </v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        tabs: null,
        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
      }
    }
  }
</script>


fix fieldset

fix fieldset

<template>

            <slot></slot>

</template>

<template>

            <slot></slot>

        <slot></slot>

</template>


properly specify current channel, and link to channel page instead of root page

<template>

        <breadcrumb :linkobject="learnRootLink" text="Learn"></breadcrumb>

      <template v-if="pageName === PageNames.EXPLORE_TOPIC">

          <breadcrumb :showarrow='false' :linkobject="exploreRootLink" text="Explore"></breadcrumb>

          <breadcrumb :linkobject="parentExploreLink"></breadcrumb>

          {{ crumb.title }}

      </template>

        <breadcrumb :linkobject="parentExploreLink"></breadcrumb>

</template>

<template>

        <breadcrumb :linkobject="learnRootLink" text="Learn"></breadcrumb>

      <template v-if="pageName === PageNames.EXPLORE_TOPIC">

          <breadcrumb :showarrow='false' :linkobject="exploreRootLink" text="Explore"></breadcrumb>

          <breadcrumb :linkobject="parentLink"></breadcrumb>

          {{ crumb.title }}

      </template>

        <breadcrumb :linkobject="parentLink"></breadcrumb>

</template>


fix(timepicker): update timepicker for range

<template lang="pug">
.c-timepicker__timerange(@click="openPanel")
  .c-timerange__wrapper
    c-input(
      v-model="startTime"
      @change="startInputChange"
    )
    span 至
    c-input(
      v-model="endTime"
      @change="endInputChange"
    )
  .c-timerange__panel(:class="{show: isOpen}")
    .c-timerange__container
      .c-timepicker__wrap
        p 开始时间
        c-timepanel(
          :isShown="isOpen"
          :hour="startHour"
          :minute="startMinute"
          :second="startSecond"
          :format="format"
          :secondStep="secondStep"
          :minuteStep="minuteStep"
          :hourStep="hourStep"
          :maxTime="endTime"
          @change="startTimeChange"
        )
      .c-timepicker__wrap
        p 结束时间
        c-timepanel(
          :isShown="isOpen"
          :hour="endHour"
          :minute="endMinute"
          :second="endSecond"
          :format="format"
          :minTime="startTime"
          :secondStep="secondStep"
          :minuteStep="minuteStep"
          :hourStep="hourStep"
          @change="endTimeChange"
        )
    .c-timerange__btns
      c-button(
        @click="confirmRange"
        size="sm"
        outline
        primary
      ) 确定
      c-button(
        size="sm"
        @click="cancel"
        outline
      ) 取消
</template>
<script>
import './index.css'
import { getScrollBarSize } from '@util'
import ZIndexManager from '../../scripts/utils/zIndexManager.js'
export default {
  name: 'c-timerange',
  props: {
    value: Array,
    format: String,
    hourStep: {
      type: Number,
      default: 1
    },
    minuteStep: {
      type: Number,
      default: 1
    },
    secondStep: {
      type: Number,
      default: 1
    }
  },
  data () {
    return {
      isOpen: false,
      startHour: '',
      startMinute: '',
      startSecond: '',
      endHour: '',
      endMinute: '',
      endSecond: '',
      timerange: '',
      startTime: '',
      endTime: ''
    }
  },
  mounted () {
    if (typeof document === 'object') {
      this.timerange = this.$el.querySelector('.c-timerange__panel')
      document.body.appendChild(this.timerange)
      this.resize()
      window.addEventListener('resize', this.resize, false)
    }
    this.initTime()
  },
  watch: {
    value (newVal) {
      this.initTime()
    },
    isOpen () {
      if (this.isOpen) {
        this.resize()
        window.addEventListener('mouseup', this.onBodyClick, true)
      } else {
        window.removeEventListener('mouseup', this.onBodyClick, true)
      }
    }
  },
  methods: {
    initTime () {
      if (this.value.length === 2) {
        this.startTime = this.value[0]
        this.endTime = this.value[1]
      }
      if (this.startTime) {
        [this.startHour, this.startMinute, this.startSecond] = this.startTime.split(':')
      }
      if (this.endTime) {
        [this.endHour, this.endMinute, this.endSecond] = this.endTime.split(':')
      }
    },
    confirmRange () {
      console.log('confirm')
      // 验证数据合法性
      if (this.checkValue(this.startTime) && this.checkValue(this.endTime)) {
        this.emitEvent()
        this.close()
      } else {
        this.cancel()
      }
    },
    checkValue (value) {
      if (!value) return false
      const [hour, minute, second] = value
      return !(second > 59 || minute > 59 || hour > 23)
    },
    cancel () {
      this.initTime()
      this.emitEvent()
      this.close()
    },
    openPanel () {
      this.isOpen = true
    },
    close () {
      this.isOpen = false
    },
    onBodyClick (e) {
      const isInPicker = this.$el.contains(e.target)
      const isInPanel = this.timerange.contains(e.target)
      if (!isInPicker && !isInPanel) {
        this.confirmRange()
        this.$el.focus()
      }
    },
    getStyle () {
      const clientRect = this.$parent.$refs.timepicker.getBoundingClientRect()
      const windowH = window.innerHeight
      const windowW = window.innerWidth
      const marginTop = 2
      const scrollHeight = document.body.scrollWidth > window.innerWidth ? 20 : 0
      const droplistHeight = this.timerange.clientHeight
      const droplistWidth = this.timerange.clientWidth
      const defaultTop = clientRect.top + clientRect.height + marginTop + window.pageYOffset
      const clientHeight = clientRect.height + marginTop

      const clientY = clientRect.y
      const compTop = windowH - droplistHeight - scrollHeight
      const marginRight = getScrollBarSize() + 5 // scrollbar width
      const left = droplistWidth + clientRect.left + marginRight + window.pageXOffset > windowW ? windowW - droplistWidth - marginRight : clientRect.left + window.pageXOffset
      const top = droplistHeight + clientHeight + clientY + scrollHeight > windowH ? compTop : defaultTop
      const zIndex = ZIndexManager.next()
      return `
        position: absolute;
        top: ${top}px;
        left: ${left}px;
        z-index: ${zIndex};
      `
    },
    resize () {
      this.$nextTick(() => {
        this.timerange.style.cssText = this.getStyle()
      })
    },
    generateValue (hour, minute, second) {
      const result = []
      hour && result.push(hour)
      minute && result.push(minute)
      second && result.push(second)
      return result.join(':')
    },
    startInputChange (value) {
      const regValid = /^\d{2}:\d{2}:\d{2}$/.test(value)
      if (regValid && this.checkValue(value)) {
        [this.startHour, this.startMinute, this.startSecond] = value.split(':')
      }
    },
    endInputChange (value) {
      const regValid = /^\d{2}:\d{2}:\d{2}$/.test(value)
      if (regValid && this.checkValue(value)) {
        [this.endHour, this.endMinute, this.endSecond] = value.split(':')
      }
    },
    startTimeChange ({ hour, minute, second }) {
      this.startHour = hour
      this.startMinute = minute
      this.startSecond = second
      this.startTime = this.generateValue(hour, minute, second)
    },
    endTimeChange ({ hour, minute, second }) {
      this.endHour = hour
      this.endMinute = minute
      this.endSecond = second
      this.endTime = this.generateValue(hour, minute, second)
    },
    emitEvent () {
      // this.$emit('input', [this.startTime, this.endTime])
      this.$emit('change', [this.startTime, this.endTime])
    }
  }
}
</script>

error: pathspec 'src/components/timepicker/timerange.vue' did not match any file(s) known to git


Adjust animation easing

Adjust animation easing


Added Validator mixin

Added Validator mixin

<script type="text/ecmascript-6">
    export default {
        methods: {
            isIPAddress: val => /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/.test(val)
        }
    }
</script>

error: pathspec 'resources/assets/js/mixins/Validators.vue' did not match any file(s) known to git


update

update

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/fernandoxu/oracleen-wx.git/'


Add a better content to table docs

Add a better content to table docs


removed App.vue from demo

removed App.vue from demo

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Glovo/vue-multianalytics.git/'


404 page to return 404 on prerender

404 page to return 404 on prerender

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/barprive/barprive.com.git/'


add selection ability to component Article

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/notadd/administration.git/'


[modify] ファイル名変更

[modify] ファイル名変更

<template>

Hello from Toronto

                    From {{ store.state.currentVisitorInfo.member ? store.state.currentVisitorInfo.member.name : '' }} at 3:56pm, April 3, 2012

                <button v-if="!store.state.currentVisitorInfo.read"
                    class="secondary-button pure-button"
                    @click="setRead">
                    確認済みにする
                </button>

                    {{ dateOfRead }} 確認

</template>

error: pathspec 'src/component/visitor-info-item.vue' did not match any file(s) known to git


Adding Parameter component

Adding Parameter component

<template lang="pug">
  span
</template>

<script>
  export default {
    props: ['item']
  }
</script>

error: pathspec 'src/components/Parameter.vue' did not match any file(s) known to git


Update Search button & Search input styling

<template>

          <input
            type="search"
            v-el:search
            aria-label="Type to find content"
            placeholder="Find content..."
            autocomplete="off"
            v-focus="searchOpen"
            v-model="localSearchTerm"
            id="search"
            name="search"
            @keyup="search() | debounce 500"
            @keydown.esc.prevent="clear()">

        <button aria-label="Reset" class="reset" type="reset" @click="clear()" :style="{ visibility: localSearchTerm ? 'inherit' : 'hidden' }">
        <svg height="24" viewbox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
          <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
          <path d="M0 0h24v24H0z" fill="none"></path>
        </svg>
      </button>
        <search-button class='search-btn'>Cancel</search-button>

        {{ message }}

      <card-grid v-if="topics.length && showTopics">
        <topic-list-item
          v-for="topic in topics"
          class="card"
          :id="topic.id"
          :title="topic.title"
          :ntotal="topic.n_total"
          :ncomplete="topic.n_complete">
        </topic-list-item>
      </card-grid>

      <card-grid v-if="contents.length">
        <content-grid-item
          v-for="content in contents"
          class="card"
          :title="content.title"
          :thumbnail="content.thumbnail"
          :kind="content.kind"
          :progress="content.progress"
          :id="content.id">
        </content-grid-item>
      </card-grid>

</template>


adding new readonly on docs

adding new readonly on docs


fix apply width

fix apply width

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/gzdaijie/fdu-red-carpet-vote.git/'


Fix apostroph display for blockquotes

Fix apostroph display for blockquotes

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stefanjudis/stefan-judis-website.git/'


Fix eslint error

Fix eslint error


components: add transiton for header icon of Collapse

<template>

{{ title }}

        <slot></slot>

</template>


add addWebMaster method

add addWebMaster method

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ije/web-studio.git/'


Finish error page

Finish error page

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/praneetloke/vue-material.git/'


Demo file

Demo file

<template>

Hello vetur

</template>

<template lang="jade">
// h1(name=maintainer.name)
//   | Maintainer:
//   = ' ' + maintainer.name
table
  tr
    td(style='width: '+(100/2)+'%').
      Twitter
    td= maintainer.twitter
  tr
    td(style='width: '+(100/2)+'%').
      Blog
    td= maintainer.blog

- var user = { name: 'John' }
if user
  div.welcomebox
    // Filtered inline output
    p.
      Welcome, #{user.name}
else
  div.loginbox
    form(name="login", action="/login", method="post")
      input(type="text", name="user")
      input(type="password", name="pass")
      input(type="submit", value="login")

p #[code samp] — Regular text. #[samp This is sample text] more text.
</template>

error: pathspec 'demo/vetur.vue' did not match any file(s) known to git


- fixed cookie banner not saving cookies correctly

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/frontools/magnolia-megaton.git/'


Delete swipe.vue

Delete swipe.vue

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cljmomo/zhunxuefen.git/'


Added Price component

Added Price component

<template>

    {{ symbol }}
    {{ price }}

</template>

error: pathspec 'src/DatePicker/components/Price.vue' did not match any file(s) known to git


IssueNotesRefactor: Flip toggle discussions chevron when discussion toggled.

<template>

        {{author.name}}

        @{{author.username}}

        <template v-if="actionText">
          {{actionText}}
        </template>

          <time-ago-tooltip
            :time="createdAt"
            tooltipPlacement="bottom" />

      <button
        @click="handleToggle"
        class="note-action-button discussion-toggle-button js-toggle-button"
        type="button">

          Toggle discussion
      </button>

</template>

<template>

        {{author.name}}

        @{{author.username}}

        <template v-if="actionText">
          {{actionText}}
        </template>

          <time-ago-tooltip
            :time="createdAt"
            tooltipPlacement="bottom" />

      <button
        @click="toggleHandler"
        class="note-action-button discussion-toggle-button js-toggle-button"
        type="button">

          Toggle discussion
      </button>

</template>