@antv/dumi-theme-antv 0.8.0-beta.2 → 0.8.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/builtins/Playground/index.module.less +0 -1
  2. package/dist/components/AI/HomeDialog/AntVBanner/index.module.less +2 -2
  3. package/dist/components/AI/HomeDialog/ModeSelector/index.module.less +39 -22
  4. package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.module.less +0 -1
  5. package/dist/components/AI/HomeDialog/PromptTextarea/DatasourceCard/index.module.less +3 -3
  6. package/dist/components/AI/HomeDialog/PromptTextarea/index.js +10 -23
  7. package/dist/components/AI/HomeDialog/PromptTextarea/index.module.less +8 -8
  8. package/dist/components/AI/HomeDialog/RecommendCase/card.module.less +1 -1
  9. package/dist/components/AI/HomeDialog/RecommendCase/index.module.less +2 -2
  10. package/dist/components/Login/Captcha/index.js +199 -0
  11. package/dist/components/Login/Captcha/index.less +91 -0
  12. package/dist/components/Login/CheckCode/index.js +262 -0
  13. package/dist/components/Login/CheckCode/index.less +137 -0
  14. package/dist/components/Login/CountDownButton/index.js +115 -0
  15. package/dist/components/Login/CountDownButton/index.less +8 -0
  16. package/dist/components/Login/LoginForm.js +245 -0
  17. package/dist/components/Login/LoginForm.less +409 -0
  18. package/dist/components/Login/index.js +20 -0
  19. package/dist/components/Login/openAuthWindow.js +54 -0
  20. package/dist/components/Login/types.js +5 -0
  21. package/dist/components/Login/utils.js +47 -0
  22. package/dist/hooks/useProducts.js +3 -2
  23. package/dist/layouts/DocLayout.js +2 -1
  24. package/dist/layouts/GlobalLayout/index.js +8 -4
  25. package/dist/locales/en.json +52 -1
  26. package/dist/locales/zh.json +52 -1
  27. package/dist/model/AIChat.js +2 -2
  28. package/dist/model/auth.js +89 -0
  29. package/dist/pages/AIPlayground/components/ConversationsMenu/index.module.less +2 -0
  30. package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.js +7 -5
  31. package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.module.less +1 -2
  32. package/dist/pages/AIPlayground/components/MsgBox/index.js +179 -140
  33. package/dist/pages/AIPlayground/components/MsgBox/index.module.less +3 -2
  34. package/dist/pages/AIPlayground/components/MsgBox/useAutoScroll.js +46 -0
  35. package/dist/pages/AIPlayground/components/SessionLayout/index.module.less +1 -2
  36. package/dist/pages/AIPlayground/components/TaskBox/generateCode.js +7 -1
  37. package/dist/pages/AIPlayground/components/TaskBox/index.js +78 -55
  38. package/dist/pages/AIPlayground/components/TaskBox/index.module.less +1 -0
  39. package/dist/pages/Examples/components/Accouncement/index.module.less +1 -1
  40. package/dist/pages/Examples/index.module.less +11 -11
  41. package/dist/pages/Index/components/Cases/index.module.less +8 -8
  42. package/dist/pages/Index/components/Companies/index.module.less +4 -3
  43. package/dist/pages/Index/components/Features/FeatureCard.module.less +4 -5
  44. package/dist/pages/Index/components/Features/index.module.less +5 -5
  45. package/dist/pages/Index/components/_.less +9 -9
  46. package/dist/slots/Banner/Notification.module.less +8 -8
  47. package/dist/slots/Banner/index.module.less +10 -9
  48. package/dist/slots/CodeEditor/Toolbar.js +5 -3
  49. package/dist/slots/CodeEditor/index.js +10 -7
  50. package/dist/slots/CodeEditor/index.module.less +3 -0
  51. package/dist/slots/CodePreview/index.module.less +0 -3
  52. package/dist/slots/CodeRunner/index.js +5 -2
  53. package/dist/slots/ContentTable/index.module.less +2 -1
  54. package/dist/slots/Detail/News.module.less +9 -9
  55. package/dist/slots/Detail/index.module.less +11 -14
  56. package/dist/slots/ExampleSider/index.module.less +3 -4
  57. package/dist/slots/Footer/index.module.less +2 -2
  58. package/dist/slots/Header/Products/Product.module.less +2 -2
  59. package/dist/slots/Header/Search/SearchResult.js +7 -0
  60. package/dist/slots/Header/Search/SearchResult.module.less +1 -0
  61. package/dist/slots/Header/index.module.less +5 -5
  62. package/dist/slots/LiveExample/index.module.less +1 -1
  63. package/dist/slots/Loading/index.module.less +30 -28
  64. package/dist/slots/ManualContent/index.module.less +14 -17
  65. package/dist/slots/_.less +9 -9
  66. package/dist/utils/auth.js +10 -0
  67. package/dist/utils/env.js +24 -0
  68. package/dist/utils/request.js +104 -0
  69. package/package.json +7 -2
  70. package/dist/static/SearchAiIcon.svg +0 -14
@@ -0,0 +1,54 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
4
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
5
+ import { pickBy } from 'lodash';
6
+ export var AuthScene = /*#__PURE__*/function (AuthScene) {
7
+ AuthScene["LOGIN"] = "login";
8
+ AuthScene["GET_ACCESS_TOKEN"] = "get_access_token";
9
+ return AuthScene;
10
+ }({});
11
+ var AUTH_BROADCAST_CHANNEL_NAME = 'WeaveFox-Auth';
12
+ var AuthSceneUrlMap = _defineProperty(_defineProperty({}, AuthScene.LOGIN, '/login/github/oauth'), AuthScene.GET_ACCESS_TOKEN, '/login/github/access_token');
13
+ export function openAuthWindow(params) {
14
+ try {
15
+ var _ref = params || {},
16
+ onSuccess = _ref.onSuccess,
17
+ onFail = _ref.onFail,
18
+ scene = _ref.scene,
19
+ sceneParams = _ref.sceneParams;
20
+ var broadcast = new BroadcastChannel(AUTH_BROADCAST_CHANNEL_NAME);
21
+ var cleanedParams = pickBy(sceneParams, function (val) {
22
+ return val !== undefined && val !== null;
23
+ });
24
+ var sceneParamsString = new URLSearchParams(cleanedParams).toString();
25
+ sceneParamsString = sceneParamsString ? "?".concat(sceneParamsString) : '';
26
+ window.open(AuthSceneUrlMap[scene] + sceneParamsString, 'github_auth', 'left=0,top=0,width=600,height=600');
27
+ var handler = function handler(event) {
28
+ if (event.data.source !== 'WeaveFox-Auth') return;
29
+ // 验证来源是否可信
30
+ if (event.origin !== window.location.origin) {
31
+ console.warn('Untrusted origin: ', event.origin);
32
+ return;
33
+ }
34
+ if (event.data.success) {
35
+ if (onSuccess) {
36
+ onSuccess(event.data);
37
+ }
38
+ } else if (onFail) {
39
+ onFail(event.data);
40
+ }
41
+ window.removeEventListener('message', handler);
42
+ broadcast.removeEventListener('message', handler);
43
+ };
44
+ window.addEventListener('message', handler, false);
45
+ broadcast.addEventListener('message', handler, false);
46
+
47
+ // 未解之谜,窗口可能会丢失 opener 信息,暂时用 5s 后强制刷新解决
48
+ setTimeout(function () {
49
+ window.location.reload();
50
+ }, 5000);
51
+ } catch (e) {
52
+ console.error('auth unexpected error', e);
53
+ }
54
+ }
@@ -0,0 +1,5 @@
1
+ export var STEP = /*#__PURE__*/function (STEP) {
2
+ STEP["Login"] = "Login";
3
+ STEP["CompleteUserInfo"] = "CompleteUserInfo";
4
+ return STEP;
5
+ }({});
@@ -0,0 +1,47 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ import FingerprintJS from '@fingerprintjs/fingerprintjs';
6
+ export var chinaMobilePhoneRE = /^(13\d|14\d|15[012356789]|16[567]|17[01235678]|18\d|19\d)\d{8}(\+\d+)?$/;
7
+ export var SignupRegion = /*#__PURE__*/function (SignupRegion) {
8
+ SignupRegion["oversea"] = "oversea";
9
+ SignupRegion["possible_oversea"] = "possible_oversea";
10
+ return SignupRegion;
11
+ }({}); // 可能是海外(不确定/待确认)
12
+ export function getFingerprint() {
13
+ return _getFingerprint.apply(this, arguments);
14
+ }
15
+ function _getFingerprint() {
16
+ _getFingerprint = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
17
+ var fp, result;
18
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
19
+ while (1) switch (_context.prev = _context.next) {
20
+ case 0:
21
+ _context.next = 2;
22
+ return FingerprintJS.load();
23
+ case 2:
24
+ fp = _context.sent;
25
+ _context.next = 5;
26
+ return fp.get();
27
+ case 5:
28
+ result = _context.sent;
29
+ return _context.abrupt("return", result);
30
+ case 7:
31
+ case "end":
32
+ return _context.stop();
33
+ }
34
+ }, _callee);
35
+ }));
36
+ return _getFingerprint.apply(this, arguments);
37
+ }
38
+ export var NC_SCENE = /*#__PURE__*/function (NC_SCENE) {
39
+ NC_SCENE["login"] = "login";
40
+ NC_SCENE["register"] = "register";
41
+ NC_SCENE["verifyUser"] = "verify_user";
42
+ NC_SCENE["registerH5"] = "nc_register_h5";
43
+ NC_SCENE["loginH5"] = "nc_login_h5";
44
+ NC_SCENE["reset"] = "nc_reset";
45
+ return NC_SCENE;
46
+ }({});
47
+ export var UIA_UA_RE = /Macaca UI Robot/;
@@ -1,8 +1,9 @@
1
1
  import { useQuery } from '@tanstack/react-query';
2
2
  export function getProducts() {
3
3
  // 如需要修改产品信息,请到 https://yuyan.antfin-inc.com/antv/site-data/sprints 修改区块内容
4
- return fetch('https://assets.antv.antgroup.com/antv/products.json' // 生产环境
5
- // 'https://site-data-pre.alipay.com/antv/products.json', // 预发测试
4
+ return fetch(
5
+ // 'https://assets.antv.antgroup.com/antv/products.json', // 生产环境
6
+ 'https://site-data-pre.alipay.com/antv/products.json' // 预发测试
6
7
  ).then(function (res) {
7
8
  return res.json();
8
9
  });
@@ -14,6 +14,7 @@ import ManualLayout from "./ManualLayout";
14
14
  import GlobalStyles from "../common/GlobalStyles";
15
15
  import { defaultToken } from "../common/styles/theme";
16
16
  import "../static/style";
17
+ import { LoginModal } from "../components/Login";
17
18
  /**
18
19
  * DocLayout 是 dumi2 的内置 layout 入口,在这里使用页面路径进行区分成自己不同的 Layout。
19
20
  */
@@ -107,5 +108,5 @@ export default (function () {
107
108
  token: defaultToken,
108
109
  hashed: false
109
110
  }
110
- }, /*#__PURE__*/React.createElement(GlobalStyles, null), content)));
111
+ }, /*#__PURE__*/React.createElement(GlobalStyles, null), content, /*#__PURE__*/React.createElement(LoginModal, null))));
111
112
  });
@@ -1,12 +1,16 @@
1
- import React, { useEffect } from 'react';
2
- import { useOutlet } from 'dumi';
3
1
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
4
- import { initializeStore } from "../../model/AIChat";
2
+ import * as antd from 'antd';
3
+ import { useOutlet } from 'dumi';
4
+ import React, { useEffect } from 'react';
5
+ import { initializeAIChat } from "../../model/AIChat";
6
+ import { initializeAuth } from "../../model/auth";
5
7
  var queryClient = new QueryClient();
8
+ window.antd = antd;
6
9
  var GlobalLayout = function GlobalLayout() {
7
10
  var outlet = useOutlet();
8
11
  useEffect(function () {
9
- initializeStore();
12
+ initializeAIChat();
13
+ initializeAuth();
10
14
  }, []);
11
15
  return outlet && /*#__PURE__*/React.createElement(QueryClientProvider, {
12
16
  client: queryClient
@@ -268,5 +268,56 @@
268
268
  "feedback.result.demo.error": "Demo code error, please check",
269
269
  "feedback.result.reading.time": "Reading needs",
270
270
  "feedback.result.minutes": "minutes",
271
- "feedback.result.no.results": "No query result found"
271
+ "feedback.result.no.results": "No query result found",
272
+ "login.user.protocol.title": "User Agreement",
273
+ "login.user.protocol.content": "To better protect your legitimate rights and interests, please read and agree to WeaveFox ",
274
+ "login.user.protocol.link": "User Agreement",
275
+ "login.protocol.agree": "Agree",
276
+ "login.protocol.disagree": "Disagree",
277
+ "login.placeholder.phone": "Please enter your mobile number",
278
+ "login.placeholder.phone.or.email": "Please enter your mobile number or email",
279
+ "login.error.invalid.phone": "Please enter a valid mobile number",
280
+ "login.error.invalid.phone.or.email": "Please enter a valid mobile number or email",
281
+ "login.button.login.or.register": "Sign In / Sign Up",
282
+ "login.button.login.or.register.en": "Sign In / Sign Up",
283
+ "login.button.github": "Login With GitHub",
284
+ "login.button.github.en": "Login With GitHub",
285
+ "login.button.google": "Login With Google",
286
+ "login.button.google.en": "Login With Google",
287
+ "login.protocol.read.agree": "I have read and agree to AntV ",
288
+ "login.protocol.link": "User Agreement",
289
+ "login.link.home": "Return to Home Page",
290
+ "login.link.home.en": "Return to Home Page",
291
+ "login.checkcode.get": "Get Code",
292
+ "login.checkcode.get.en": "Get Code",
293
+ "login.checkcode.send.success": "Verification code sent successfully",
294
+ "login.checkcode.send.success.en": "Verification code sent successfully",
295
+ "login.checkcode.error.incomplete": "Please complete the captcha verification first",
296
+ "login.checkcode.error.incomplete.en": "Please complete the captcha verification first",
297
+ "login.checkcode.sent": "The Verification code has been sent",
298
+ "login.checkcode.sent.en": "The Verification code has been sent",
299
+ "login.checkcode.required": "Verification code is required",
300
+ "login.checkcode.required.en": "Verification code is required",
301
+ "login.checkcode.invalid": "Please enter a valid 6-digit verification code",
302
+ "login.checkcode.invalid.en": "Verification code not valid",
303
+ "login.checkcode.placeholder": "Verification code",
304
+ "login.checkcode.placeholder.en": "Verification code",
305
+ "login.countdown.resend": "Resend({time})",
306
+ "login.countdown.resend.en": "Resend({time})",
307
+ "login.countdown.resend.simple": "Resend",
308
+ "login.countdown.resend.simple.en": "Resend",
309
+ "login.captcha.drag": "Hold and drag the slider right",
310
+ "login.captcha.drag.en": "Hold and drag the slider right",
311
+ "login.captcha.success": "Verification successful",
312
+ "login.captcha.success.en": "Verification successful",
313
+ "login.captcha.loading": "Loading...",
314
+ "login.captcha.loading.en": "Loading...",
315
+ "login.captcha.error.wrong": "Oops! Something went wrong. Click",
316
+ "login.captcha.error.wrong.en": "Oops! Something went wrong. Click",
317
+ "login.captcha.error.network": "Poor connection. Click",
318
+ "login.captcha.error.network.en": "Poor connection. Click",
319
+ "login.captcha.error.refresh": "Refresh",
320
+ "login.captcha.error.refresh.en": "Refresh",
321
+ "login.captcha.required": "Please drag the slider to verify",
322
+ "login.captcha.required.en": "Please drag the slider to verify"
272
323
  }
@@ -267,5 +267,56 @@
267
267
  "feedback.result.demo.error": "演示代码报错,请检查",
268
268
  "feedback.result.reading.time": "阅读时间约",
269
269
  "feedback.result.minutes": "分钟",
270
- "feedback.result.no.results": "没有找到查询结果"
270
+ "feedback.result.no.results": "没有找到查询结果",
271
+ "login.user.protocol.title": "用户协议 ",
272
+ "login.user.protocol.content": "为更好地保护你的合法权益,请阅读并同意 WeaveFox ",
273
+ "login.user.protocol.link": "用户协议 ",
274
+ "login.protocol.agree": "同意",
275
+ "login.protocol.disagree": "不同意",
276
+ "login.placeholder.phone": "请输入手机号",
277
+ "login.placeholder.phone.or.email": "请输入手机号或邮箱",
278
+ "login.error.invalid.phone": "请输入正确的手机号",
279
+ "login.error.invalid.phone.or.email": "请输入正确的手机号或邮箱",
280
+ "login.button.login.or.register": "登录 / 注册",
281
+ "login.button.login.or.register.en": "Sign In / Sign Up",
282
+ "login.button.github": "GitHub 登录",
283
+ "login.button.github.en": "Login With GitHub",
284
+ "login.button.google": "Google 登录",
285
+ "login.button.google.en": "Login With Google",
286
+ "login.protocol.read.agree": "我已阅读并同意 AntV ",
287
+ "login.protocol.link": "用户协议 ",
288
+ "login.link.home": "返回首页",
289
+ "login.link.home.en": "Return to Home Page",
290
+ "login.checkcode.get": "获取验证码",
291
+ "login.checkcode.get.en": "Get Code",
292
+ "login.checkcode.send.success": "验证码发送成功",
293
+ "login.checkcode.send.success.en": "Verification code sent successfully",
294
+ "login.checkcode.error.incomplete": "先完成滑块验证",
295
+ "login.checkcode.error.incomplete.en": "Please complete the captcha verification first",
296
+ "login.checkcode.sent": "已发送验证码",
297
+ "login.checkcode.sent.en": "The Verification code has been sent",
298
+ "login.checkcode.required": "验证码不能为空",
299
+ "login.checkcode.required.en": "Verification code is required",
300
+ "login.checkcode.invalid": "请输入有效的 6 位数字验证码",
301
+ "login.checkcode.invalid.en": "Verification code not valid",
302
+ "login.checkcode.placeholder": "6 位验证码",
303
+ "login.checkcode.placeholder.en": "Verification code",
304
+ "login.countdown.resend": "重新获取({time})",
305
+ "login.countdown.resend.en": "Resend({time})",
306
+ "login.countdown.resend.simple": "重新获取",
307
+ "login.countdown.resend.simple.en": "Resend",
308
+ "login.captcha.drag": "按住滑块,拖动到最右边",
309
+ "login.captcha.drag.en": "Hold and drag the slider right",
310
+ "login.captcha.success": "验证通过",
311
+ "login.captcha.success.en": "Verification successful",
312
+ "login.captcha.loading": "加载中",
313
+ "login.captcha.loading.en": "Loading...",
314
+ "login.captcha.error.wrong": "哎呀,出错了,单击",
315
+ "login.captcha.error.wrong.en": "Oops!something went wrong. Click",
316
+ "login.captcha.error.network": "网络不给力,单击",
317
+ "login.captcha.error.network.en": "Poor connection. Click",
318
+ "login.captcha.error.refresh": "刷新",
319
+ "login.captcha.error.refresh.en": "Refresh",
320
+ "login.captcha.required": "拖动滑块验证",
321
+ "login.captcha.required.en": "Please drag the slider to verify"
271
322
  }
@@ -55,7 +55,7 @@ export var clearEmptySession = function clearEmptySession() {
55
55
  };
56
56
 
57
57
  // --- 初始化逻辑 ---
58
- export var initializeStore = /*#__PURE__*/function () {
58
+ export var initializeAIChat = /*#__PURE__*/function () {
59
59
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
60
60
  var persistedState, fp, result, newSession, _AIChatStore$sessions;
61
61
  return _regeneratorRuntime().wrap(function _callee$(_context) {
@@ -129,7 +129,7 @@ export var initializeStore = /*#__PURE__*/function () {
129
129
  }
130
130
  }, _callee, null, [[5, 15]]);
131
131
  }));
132
- return function initializeStore() {
132
+ return function initializeAIChat() {
133
133
  return _ref.apply(this, arguments);
134
134
  };
135
135
  }();
@@ -0,0 +1,89 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ import { proxy } from 'valtio';
6
+ import request from "../utils/request";
7
+
8
+ /**
9
+ * 检查当前 URL 是否包含 'skipLogin=1' 参数
10
+ * @returns {boolean} 如果包含则返回 true, 否则返回 false
11
+ */
12
+ function hasSkipLoginParam() {
13
+ // 1. 获取当前 URL 的查询字符串 (例如 "?foo=bar&skipLogin=1")
14
+ var queryString = window.location.search;
15
+
16
+ // 2. 创建一个 URLSearchParams 实例
17
+ var urlParams = new URLSearchParams(queryString);
18
+
19
+ // 3. 使用 .get() 方法获取 'skipLogin' 参数的值,并判断是否为 '1'
20
+ // 注意:URL参数的值总是字符串类型,所以我们用 '1' 而不是 1 进行比较。
21
+ return urlParams.get('skipLogin') === '1';
22
+ }
23
+
24
+ // 1. 定义 State (只包含数据)
25
+ export var authStore = proxy({
26
+ isModalOpen: false,
27
+ isAuthenticated: false,
28
+ token: localStorage.getItem('authToken')
29
+ });
30
+
31
+ // 2. 定义 Actions (作为独立函数)
32
+ export var showLoginModal = function showLoginModal() {
33
+ authStore.isModalOpen = true;
34
+ };
35
+ export var hideLoginModal = function hideLoginModal() {
36
+ authStore.isModalOpen = false;
37
+ };
38
+ export var loginOrRegister = /*#__PURE__*/function () {
39
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(params) {
40
+ var result;
41
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
42
+ while (1) switch (_context.prev = _context.next) {
43
+ case 0:
44
+ _context.prev = 0;
45
+ _context.next = 3;
46
+ return request.post('/api/modules/user/api/accounts/login_or_register', params);
47
+ case 3:
48
+ result = _context.sent;
49
+ authStore.token = result.token;
50
+ authStore.isAuthenticated = true;
51
+ if (typeof window !== 'undefined') {
52
+ localStorage.setItem('authToken', result.token);
53
+ }
54
+ hideLoginModal();
55
+ return _context.abrupt("return", true);
56
+ case 11:
57
+ _context.prev = 11;
58
+ _context.t0 = _context["catch"](0);
59
+ console.error('Login failed in store:', _context.t0);
60
+ return _context.abrupt("return", false);
61
+ case 15:
62
+ case "end":
63
+ return _context.stop();
64
+ }
65
+ }, _callee, null, [[0, 11]]);
66
+ }));
67
+ return function loginOrRegister(_x) {
68
+ return _ref.apply(this, arguments);
69
+ };
70
+ }();
71
+ export var logout = function logout() {
72
+ try {
73
+ request.delete('/api/modules/user/api/accounts/logout');
74
+ } catch (e) {
75
+ console.error('Logout failed in store:', e);
76
+ } finally {
77
+ authStore.token = null;
78
+ authStore.isAuthenticated = false;
79
+ localStorage.removeItem('authToken');
80
+ }
81
+ };
82
+ export function sendValidationCode(data) {
83
+ return request.post('/api/modules/user/api/validation_code/send', data);
84
+ }
85
+ export var initializeAuth = function initializeAuth() {
86
+ if (authStore.token || hasSkipLoginParam()) {
87
+ authStore.isAuthenticated = true;
88
+ }
89
+ };
@@ -1,5 +1,6 @@
1
1
  .container {
2
2
  background: #fff;
3
+
3
4
  :global {
4
5
  .ant-menu {
5
6
  width: 16vw;
@@ -38,6 +39,7 @@
38
39
  border-radius: 50%;
39
40
  transition: background-color 0.3s ease;
40
41
  cursor: pointer;
42
+
41
43
  &:hover{
42
44
  background-color: #fbfcfd;
43
45
  }
@@ -10,7 +10,7 @@ import { a11yLight } from "react-syntax-highlighter/dist/cjs/styles/hljs";
10
10
  import { AIChatStore } from "../../../../model/AIChat";
11
11
  import { useCopyToClipboard } from "react-use";
12
12
  import { CheckOutlined, CopyOutlined, PlaySquareOutlined } from "@ant-design/icons";
13
- import { Space, Tooltip } from "antd";
13
+ import { Button, Space, Tooltip } from "antd";
14
14
  import styles from "./MarkdownCodeBlock.module.less";
15
15
  import { useIntl } from 'dumi';
16
16
 
@@ -60,8 +60,9 @@ export var MarkdownCodeBlock = function MarkdownCodeBlock(_ref) {
60
60
  title: intl.formatMessage({
61
61
  id: 'ai.markdown.copy'
62
62
  })
63
- }, /*#__PURE__*/React.createElement("button", {
64
- type: "button",
63
+ }, /*#__PURE__*/React.createElement(Button, {
64
+ variant: "link",
65
+ size: "small",
65
66
  onClick: function onClick() {
66
67
  return copyToClipboard(codeString);
67
68
  },
@@ -72,8 +73,9 @@ export var MarkdownCodeBlock = function MarkdownCodeBlock(_ref) {
72
73
  title: intl.formatMessage({
73
74
  id: 'ai.markdown.run'
74
75
  })
75
- }, /*#__PURE__*/React.createElement("button", {
76
- type: "button",
76
+ }, /*#__PURE__*/React.createElement(Button, {
77
+ variant: "link",
78
+ size: "small",
77
79
  onClick: handleRunCode,
78
80
  title: intl.formatMessage({
79
81
  id: 'ai.markdown.run'
@@ -3,9 +3,8 @@
3
3
  top: 0.5em;
4
4
  right: 0.5em;
5
5
  z-index: 1;
6
+
6
7
  button {
7
- background-color: #4a4a4a;
8
- color: white;
9
8
  border: none;
10
9
  border-radius: 5px;
11
10
  cursor: pointer;