<template>
  <div class="app-container">
    <div style="margin-top: 10px">
      <grid-layout
        :layout.sync="layout"
        :col-num="12"
        :row-height="30"
        :is-draggable="draggable"
        :is-resizable="resizable"
        :vertical-compact="true"
        :use-css-transforms="true"
        @layout-created="layoutCreatedEvent"
        @layout-before-mount="layoutBeforeMountEvent"
        @layout-mounted="layoutMountedEvent"
        @layout-ready="layoutReadyEvent"
        @layout-updated="layoutUpdatedEvent"
      >
        <grid-item
          :x="0"
          :y="0"
          :w="6"
          :h="5"
          i="1"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <p class="item-title">DEVICE</p>
          <div style="padding: 15px">
            <el-form :inline="true">
              <el-form-item label="选择设备">
                <el-select
                  size="mini"
                  v-model="device"
                  @change="onSelectChange"
                  placeholder="请选择设备"
                >
                  <el-option
                    v-for="(item, index) in deviceList"
                    :key="index"
                    :label="item"
                    :value="item"
                  ></el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="资源监控报告">
                <el-button size="mini" @click="getReport">导出报告</el-button>
              </el-form-item>
              <el-form-item label="页面图片显示设置">
                <el-switch
                  v-model="pngShowMode"
                  active-text="自动显示当前页面"
                  inactive-text="手动选择页面"
                >
                </el-switch>
              </el-form-item>
            </el-form>
          </div>
        </grid-item>
        <grid-item
          :x="6"
          :y="0"
          :w="6"
          :h="5"
          i="2"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <p class="item-title">SYSTEM</p>
          <div class="list-element">
            <div v-for="(field, index) in Object.keys(system)" :key="index">
              <label>{{ field }}</label>
              <p>{{ system[field] }}</p>
            </div>
          </div>
        </grid-item>
        <grid-item
          :x="0"
          :y="5"
          :w="6"
          :h="5"
          i="3"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <p class="item-title">EVM</p>
          <div class="list-element">
            <div v-for="(field, index) in Object.keys(evm)" :key="index" :style="{background: colors[index]}">
              <label>{{ field }}</label>
              <p>{{ evm[field] }}{{ field | retouch }}</p>
            </div>
          </div>
        </grid-item>
        <grid-item
          :x="6"
          :y="5"
          :w="6"
          :h="5"
          i="4"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <p class="item-title">LVGL</p>
          <div class="list-element">
            <div v-for="(field, index) in Object.keys(lvgl)" :key="index">
              <label>{{ field }}</label>
              <p>{{ lvgl[field] }}{{ field | retouch }}</p>
            </div>
          </div>
        </grid-item>
        <grid-item
          :x="0"
          :y="10"
          :w="8"
          :h="10"
          i="5"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <div style="width: 100%; height: 100%; overflow-y: auto">
            <p class="item-title">APP</p>
            <el-table
              element-loading-text="Loading"
              :data="imageList"
              size="mini"
              border
              fit
              :row-class-name="tableRowClassName"
              @row-click="onTableRowClick"
            >
              <el-table-column
                prop="uri"
                label="uri"
                min-width="150"
                show-overflow-tooltip
              ></el-table-column>
              <el-table-column
                prop="png_total_count"
                label="png_total_count"
                min-width="110"
                show-overflow-tooltip
              ></el-table-column>
              <el-table-column
                label="heap_used_size"
                min-width="110"
                show-overflow-tooltip
              >
                <template slot-scope="scope"
                  >{{ scope.row.heap_used_size }}(KB)</template
                >
              </el-table-column>
              <el-table-column
                label="stack_used_size"
                min-width="110"
                show-overflow-tooltip
              >
                <template slot-scope="scope"
                  >{{ scope.row.stack_used_size }}(KB)</template
                >
              </el-table-column>
              <el-table-column
                label="ext_used_size"
                min-width="100"
                show-overflow-tooltip
              >
                <template slot-scope="scope"
                  >{{ scope.row.ext_used_size }}(KB)</template
                >
              </el-table-column>
              <el-table-column
                label="evue file"
                min-width="80"
                show-overflow-tooltip
              >
                <template slot-scope="scope"
                  >{{ scope.row.length }}(KB)</template
                >
              </el-table-column>
              <el-table-column
                label="png_uncompressed_size"
                min-width="150"
                show-overflow-tooltip
              >
                <template slot-scope="scope"
                  >{{ scope.row.png_uncompressed_size }}(KB)</template
                >
              </el-table-column>
              <el-table-column
                label="app_size"
                min-width="110"
                show-overflow-tooltip
              >
                <template slot-scope="scope"
                  >{{ scope.row.app_size }}(KB)</template
                >
              </el-table-column>
            </el-table>
          </div>
        </grid-item>
        <grid-item
          :x="8"
          :y="10"
          :w="4"
          :h="10"
          i="6"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <div style="width: 100%; height: 100%; overflow-y: auto">
            <el-table :data="pngList" style="width: 100%">
              <el-table-column
                prop="uri"
                label="uri"
                min-width="180"
              ></el-table-column>
              <el-table-column
                prop="filesize"
                label="file size"
                width="100"
              ></el-table-column>
              <el-table-column
                prop="uncompressed_size"
                label="origin size"
                width="100"
              ></el-table-column>
              <el-table-column prop="ratio" label="ratio" width="100"></el-table-column>
            </el-table>
          </div>
        </grid-item>
        <grid-item
          :x="0"
          :y="20"
          :w="12"
          :h="7"
          i="9"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <EvmChart :chartData="evm"></EvmChart>
        </grid-item>
        <grid-item
          :x="0"
          :y="27"
          :w="4"
          :h="14"
          i="7"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <div>
            <p class="item-title">应用大小</p>
            <el-table :data="appList" size="mini" style="width: 100%">
              <el-table-column
                prop="appName"
                label="应用名称"
                width="180"
              ></el-table-column>
              <el-table-column
                prop="fileSize"
                label="应用大小(KB)"
              ></el-table-column>
              <el-table-column prop="fileCount" label="文件个数" width="100"></el-table-column>
            </el-table>
          </div>
        </grid-item>
        <grid-item
          :x="4"
          :y="27"
          :w="8"
          :h="7"
          i="7"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <SystemChart
            :chartData="system"
          ></SystemChart>
        </grid-item>
        <grid-item
          :x="4"
          :y="34"
          :w="8"
          :h="7"
          i="8"
          @resize="resizeEvent"
          @move="moveEvent"
          @resized="resizedEvent"
          @container-resized="containerResizedEvent"
          @moved="movedEvent"
        >
          <LvglChart :chartData="lvgl"></LvglChart>
        </grid-item>
      </grid-layout>
    </div>
  </div>
</template>
<script>
import {
  getWatchList,
  getMonitorData,
  getReport,
  getTemplate,
  setTemplate,
} from "@/api/store";
import EvmChart from "./components/EvmChart";
import LvglChart from "./components/LvglChart";
import SystemChart from "./components/SystemChart";
import { GridLayout, GridItem } from "vue-grid-layout";
import { wsNotify } from "@/utils/eventBus.js";
import { deepClone, download } from "@/utils/index";
import Database from "@/utils/indexedDB";

const dbObject = {
  dbName: "evmiot", // 数据库名
  version: 1, // 版本号
  primaryKey: "id", // 主键
  keyNames: [
    { // 需要存储的数据字段对象
      key: "system.timestamp", // 字段名
      unique: false, // 当前这条数据是否能重复 (最常用) 默认false
    },
    {
      key: "imei",
      unique: false,
    },
  ],
};

const indexedDb = Database(),
  jsonFile = "evue-monitor.json";
let monitor = new indexedDb(dbObject);

function isNumber(value) {
  return typeof value === "number" && !isNaN(value);
}

function byteToKiloByte(obj) {
  Object.prototype.toString.call(obj) === "[object Object]" && Object.keys(obj).forEach(k => {
      if ((k.indexOf("size") !== -1 || k === "length") && isNumber(obj[k])) {
        obj[k] = Math.ceil(obj[k] / 1024)
      }
    })
}

function calculate(obj, name, list) {
  result[name] = [{ title: "最新值" }, { title: "最旧值" }, { title: "最大值" }, { title: "最小值" }, { title: "平均值" }]; // new old max min avg

  Object.keys(obj).forEach((k) => {
    result[name][0][k] = 0;
    result[name][1][k] = 0;
    result[name][2][k] = 0;
    result[name][3][k] = 0;
    result[name][4][k] = 0;

    let first = 0, last = Date.now();
    const t = list.map((item) => {
      if (item.ts > first) {
        first = item.ts;
        result[name][0][k] = item[k];
      }
      if (item.ts < last) {
        last = item.ts;
        result[name][1][k] = item[k];
      }
      return item[k];
    });

    result[name][2][k] = Math.max.apply(null, t);
    result[name][3][k] = Math.min.apply(null, t);
    result[name][4][k] = Math.ceil(t.reduce((prev, curr) => prev + curr) / t.length);
  });
}

function resetResult() {
  return {
    evm: [],
    lvgl: [],
    system: [],
    evmImg: null,
    lvglImg: null,
    systemImg: null,
    imageList: [],
  };
}

// 统计使用
const result = resetResult();

export default {
  name: "Monitor",
  data() {
    return {
      watchs: [],
      pngList: [],
      globalData: null,
      device: null,
      deviceList: null,
      system: {
        host: null,
        timestamp: null,
        free_size: null,
        free_space_size: null,
        used_space_size: null,
      },
      evm: {
        app_size: 0,
        evue_free_size: 0,
        evue_total_size: 0,
        evue_used_size: 0,
        ext_total_size: 0,
        ext_used_size: 0,
        heap_total_size: 0,
        heap_used_size: 0,
        stack_total_size: 0,
        stack_used_size: 0,
      },
      lvgl: {
        frag_pct: 0,
        free_biggest_size: 0,
        free_cnt: 0,
        free_size: 0,
        total_size: 0,
        used_cnt: 0,
        used_pct: 0
      },
      image: {},
      imageList: [],
      colors: ["yellow", "yellow", "yellowgreen", "yellowgreen", "orange", "orange", "paleturquoise", "paleturquoise", "paleturquoise", "darksalmon"],
      pngShowMode: true,
      currentPngList: [],
      socket: null,
      layout: [
        { x: 0, y: 0, w: 6, h: 5, i: "1", static: false },
        { x: 6, y: 0, w: 6, h: 5, i: "2", static: true },
        { x: 0, y: 5, w: 6, h: 5, i: "3", static: false },
        { x: 6, y: 5, w: 6, h: 5, i: "4", static: false },
        { x: 0, y: 10, w: 8, h: 10, i: "5", static: false },
        { x: 8, y: 10, w: 4, h: 10, i: "6", static: false },
        { x: 0, y: 20, w: 12, h: 7, i: "7", static: false },
        { x: 0, y: 27, w: 12, h: 7, i: "8", static: false },
        { x: 0, y: 34, w: 12, h: 7, i: "9", static: false },
      ],
      draggable: true,
      resizable: true,
      appList: [],
    };
  },
  filters: {
    byte2kb(val) {
      return Math.ceil(val / 1024)
    },
    retouch(key) {
      if (key.indexOf("size") > -1) {
        return "KB"
      } else if (key.indexOf("pct") > -1) {
        return "%"
      } else {
        return ""
      }
    }
  },
  components: {
    GridLayout,
    GridItem,
    EvmChart,
    LvglChart,
    SystemChart,
  },
  methods: {
    onTableRowClick(row) {
      this.pngShowMode = false;
      this.pngList = this.currentPngList[row.uri];
    },
    getTemplate() {
      getTemplate()
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          this.$message.error(err.msg);
        });
    },
    getReport() {
      setTemplate({ templateName: jsonFile })
        .then((res) => {
          console.log(res.msg);
        })
        .catch((err) => {
          console.error(err.msg);
        });

      wsNotify.eventBus.$emit("export-picture");
      monitor
        .getAllData((params) => {
          return params.imei && params.imei == this.device;
        })
        .then((res) => {
          console.log(res);

          // 最大值 最小值 平均值 第一次 最后一次
          const systemList = [],
            evmList = [],
            lvglList = [];
          let appList = [];

          res.forEach((item) => {
            systemList.push(
              Object.assign(
                { ts: Date.parse(item.system.timestamp) },
                item.system
              )
            );
            evmList.push(
              Object.assign({ ts: Date.parse(item.system.timestamp) }, item.evm)
            );
            lvglList.push(
              Object.assign(
                { ts: Date.parse(item.system.timestamp) },
                item.lvgl
              )
            );
          });

          appList = appList.concat(
            this.imageList.map((img) => {
              if (img.png_detail && img.png_detail.length) {
                result.imageList = result.imageList.concat(
                  img.png_detail.map((p) => {
                    p.page = img.uri;
                    return p;
                  })
                );
              }
              return Object.assign({
                ts: Date.parse(this.globalData.system.timestamp),
                ...img,
              });
            })
          );

          result.appList = appList;

          calculate(this.evm, "evm", evmList);
          calculate(this.lvgl, "lvgl", lvglList);
          calculate(this.system, "system", systemList);

          result.imei = this.globalData.imei;
          result.timestamp = this.globalData.system.timestamp;

          return getReport({
            templateJson: jsonFile,
            dataJson: result,
          });
        })
        .then((res) => {
          if (res.code == 200) {
            download(res.data.file, res.data.url)
              .then((res) => {
                console.log(res);
              })
              .catch((err) => {
                console.error(err);
              });
          }
          console.log(res);
        })
        .catch((err) => {
          console.error(err);
        });
    },
    tableRowClassName({ row }) {
      return row.highlight ? "success-row" : "";
    },
    moveEvent(i, newX, newY) {
      console.log(i, newX, newY);
    },
    movedEvent(i, newX, newY) {
      console.log(i, newX, newY);
    },
    resizeEvent(i, newH, newW, newHPx, newWPx) {
      console.log(i, newH, newW, newHPx, newWPx);
    },
    resizedEvent(i, newX, newY, newHPx, newWPx) {
      console.log(i, newX, newY, newHPx, newWPx);
    },
    containerResizedEvent(i, newH, newW, newHPx, newWPx) {
      console.log(i, newH, newW, newHPx, newWPx);
    },
    layoutCreatedEvent(newLayout) {
      console.log("Created layout: ", newLayout);
    },
    layoutBeforeMountEvent(newLayout) {
      console.log("beforeMount layout: ", newLayout);
    },
    layoutMountedEvent(newLayout) {
      console.log("Mounted layout: ", newLayout);
    },
    layoutReadyEvent(newLayout) {
      console.log("Ready layout: ", newLayout);
    },
    layoutUpdatedEvent(newLayout) {
      console.log("Updated layout: ", newLayout);
    },
    fetchData() {
      this.isLoading = true;
      getWatchList()
        .then((res) => {
          if (res.code == 200) this.watchs = res.data;
        })
        .catch((err) => {
          this.$message.warning(err.msg);
        })
        .finally(() => {
          this.isLoading = false;
        });
    },
    onChange(res) {
      if (!res) return null;

      var t = this.watchs.find((item) => {
        return item.id == res;
      });
      if (t) this.device = t.imei;

      // 清空之前数据
      this.resetData();
    },
    onSubmit() {
      getMonitorData({
        watch: this.device,
      })
        .then((res) => {
          if (res.type == "object") {
            this.evm = res.data.evm;
            this.lvgl = res.data.lvgl;
            this.image = res.data.image;
          }
        })
        .catch((err) => {
          this.$message.warning(err.msg);
        });
    },
    onReset(formName) {
      this.$refs[formName].resetFields();
      this.fetchData();
    },
    sendMsg() {
      let message = JSON.stringify({
        type: "auth",
        token: this.$store.getters.token,
      });
      this.socket.send(message);
    },
    handleMessage(msg) {
      if (msg.code === 401) {
        this.$store.dispatch("user/removeRole");
        this.$store.dispatch("user/removeToken");
        // this.$router.push("/login?action=refresh");
        wsNotify.$emit("reconnect");
      }
      if (msg.type !== "report" || !msg.imei) return null;

      // 将设备发送过来的消息存储到浏览器中
      // 这里可以优化,将所有数据,保存到indexed datebase中
      const m = deepClone(msg);
      if (!this.deviceList) {
        this.deviceList = [];
      }
      if (!this.deviceList.includes(msg.imei)) {
        this.deviceList.push(msg.imei);
      }
      if (!this.device) {
        if (this.deviceList && this.deviceList.length)
          this.device = this.deviceList[0];
        else this.device = msg.imei;
      }

      // 处理单位
      this.processData(m);
      if (monitor.db) monitor.set(m);

      // 如果接收到的数据不是当前选中的设备,那么则直接丢弃
      if (msg.imei != this.device) {
        return null;
      }

      this.globalData = msg;
      deepClone(msg).image.forEach((item) => {
        if (item.png_detail && item.png_detail.length) {
          this.currentPngList[item.uri] = item.png_detail;
        } else {
          this.currentPngList[item.uri] = [];
        }
      });
      this.resetData(m);
    },
    processData(msg) {
      if (Object.prototype.toString.call(msg) !== "[object Object]") return null;

      Object.keys(msg).forEach((key) => {
        if (Array.isArray(msg[key])) {
          msg[key].forEach(item => {
            byteToKiloByte(item)
          })
        } else {
          byteToKiloByte(msg[key])
        }
      });

      msg.image.forEach((item) => {
        if (item.png_detail && item.png_detail.length) {
          item.png_detail = item.png_detail.map((png) => {
            png.ratio = Math.floor(png.ratio * 100) / 100;
            return png;
          });
        }
      });

      // 处理appList
      // 一、统计每个页面有多少个资源文件;二、累加每个资源文件的size;三、以表格形式展示统计信息
      if (msg.appList && msg.appList.length) {
        this.appList = msg.appList.map((item) => {
          item.fileCount = item.files.length;
          item.fileSize = item.files.reduce((total, file) => {
            return total + file.size;
          }, 0);
          item.fileSize = item.fileSize / 1024;
          return item;
        });
      }
    },
    onSelectChange(res) {
      this.device = res;

      // 清空图表数据
      wsNotify.eventBus.$emit("clear-evm-chart");
      wsNotify.eventBus.$emit("clear-lvgl-chart");
      wsNotify.eventBus.$emit("clear-system-chart");

      // 清空各个表格数据
      this.imageList = [];
      this.pngList = [];
    },
    resetData(m) {
      if (!m) return;

      wsNotify.eventBus.$emit("resize");

      // 这里需要特殊处理下,先判断uri是否存在,不存在则添加,存在则更新
      let uris = [], pngSize = 0;
      this.imageList.forEach((item) => {
        item.highlight = false;
        uris.push(item.uri);
      });
      m.image &&
        m.image.forEach((item, index) => {
          if (m.image.length - 1 === index) {
            item.highlight = true;
          } else {
            item.highlight = false;
          }

          if (m.evm) {
            item.heap_used_size = m.evm.heap_used_size
            item.stack_used_size = m.evm.stack_used_size
            item.ext_used_size = m.evm.ext_used_size
          } else {
            item.heap_used_size = 0;
            item.stack_used_size = 0;
            item.ext_used_size = 0;
          }

          if (item.png_detail && Array.isArray(item.png_detail)) {
            pngSize += item.png_detail.reduce((total, png) => total + png.uncompressed_size, 0)
          }
          item.app_size = item.heap_used_size + item.stack_used_size + item.ext_used_size + Math.ceil(pngSize / 1024)
          item.png_uncompressed_size = Math.ceil(pngSize / 1024)

          const target = this.imageList.find((img) => img.uri === item.uri);
          if (target) {
            Object.keys(item).forEach(k => target[k] = item[k])
          } else {
            this.imageList.push(item);
          }
        });

      if (m.evm) this.evm = m.evm;
      if (m.lvgl) this.lvgl = m.lvgl;
      if (m.image) this.image = m.image;
      if (m.system) this.system = m.system;

      this.evm.app_size = this.evm.heap_used_size + this.evm.stack_used_size + this.evm.ext_used_size + Math.ceil(pngSize / 1024);
      if (this.system.timestamp) this.system.timestamp = this.system.timestamp.substring(11, 20);
    },
  },
  mounted() {},
  destroyed() {
    // 页面关闭则销毁该数据库
    monitor.deleteDB();
    // monitor.clearData();
    // monitor.close();
  },
  created() {
    monitor
      .init()
      .then((res) => {
        console.log(res);
        if (monitor.db) {
          monitor.set({
            system: {
              free_size: 0,
              free_space_size: 0,
              used_space_size: 0,
            },
          });
        }
      })
      .catch((err) => {
        console.error(err);
      });

    this.socket = wsNotify;
    wsNotify.eventBus.$on("exported", (res) => {
      if (res.type === "evm") result.evmImg = res.data;
      else if (res.type === "lvgl") result.lvglImg = res.data;
      else if (res.type === "system") result.systemImg = res.data;
    });
    wsNotify.eventBus.$on("open", (message) => {
      this.sendMsg();
      this.$nextTick(() => {
        console.log(message);
      });
      // 这里启动一个定时器,10秒钟后,如果没有消息进来,说明当前没有在线设备
    });
    wsNotify.eventBus.$on("close", (message) => {
      this.$nextTick(() => {
        console.log(message);
      });
    });
    wsNotify.eventBus.$on("message", (message) => {
      this.$nextTick(() => {
        this.handleMessage(deepClone(message));
      });
    });
  },
};
</script>
<style lang="scss" scoped>

.el-table .warning-row {
  background: red;
}

.el-table .success-row {
  background: #87e8de;
}

.app-container {
  & > div.page-wrapper {
    margin: 10px 0px;
  }
  div.list-element {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(2, 70px);
    & > div {
      text-align: center;
      border: 1px solid;
      margin: 2px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      background: #cce;
      & > label {
        font-weight: thin;
        font-size: 15px;
      }
      & > p {
        height: 20px;
        margin: 5px;
        font-size: 16px;
      }
    }
  }
}

.vue-grid-layout {
  background: none;
}
.vue-grid-item:not(.vue-grid-placeholder) {
  background: #fff;
  border: 0px solid #eee;
}
.vue-grid-item .resizing {
  opacity: 0.9;
}
.vue-grid-item .static {
  background: #cce;
}
.vue-grid-item .text {
  font-size: 24px;
  text-align: center;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  height: 100%;
  width: 100%;
}
.vue-grid-item .item-title {
  margin-left: 15px;
}
.vue-grid-item .no-drag {
  height: 100%;
  width: 100%;
}
.vue-grid-item .minMax {
  font-size: 12px;
}
.vue-grid-item .add {
  cursor: pointer;
}
.vue-draggable-handle {
  position: absolute;
  width: 20px;
  height: 20px;
  top: 0;
  left: 0;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>")
    no-repeat;
  background-position: bottom right;
  padding: 0 8px 8px 0;
  background-repeat: no-repeat;
  background-origin: content-box;
  box-sizing: border-box;
  cursor: pointer;
}
</style>