├── .eslintignore ├── CHANGELOG ├── assets ├── usage.png ├── usage2.png ├── usage3.png ├── overview.png └── overview2.png ├── server.yml ├── src ├── css │ └── common.less ├── images │ └── icon.png ├── scripts │ ├── utils │ │ ├── toast.js │ │ └── storage.js │ ├── constants │ │ ├── regExp.js │ │ └── defaultData.js │ ├── components │ │ ├── Menu │ │ │ └── index.js │ │ └── ListItem │ │ │ ├── Content.js │ │ │ └── Header.js │ ├── pages │ │ ├── Home │ │ │ └── index.js │ │ └── Group │ │ │ └── index.js │ └── models │ │ ├── ListItem.js │ │ └── List.js ├── popup.js ├── popup.html ├── manifest.json ├── background.js ├── forward.js └── lib │ ├── react.js │ └── react-dom.js ├── .coveralls.yml ├── .gitignore ├── .travis.yml ├── package.json ├── test └── unit │ ├── demo.js │ └── forward.test.js ├── .dawn └── pipe.yml ├── LICENSE.md ├── README.md ├── doc └── usages.md ├── .eslintrc.yml ├── README-EN.md └── .eslintrc.json /.eslintignore: -------------------------------------------------------------------------------- 1 | /src/lib/ -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | https://github.com/xdlrt/xproxy/wiki/Changelog -------------------------------------------------------------------------------- /assets/usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdlrt/xproxy/HEAD/assets/usage.png -------------------------------------------------------------------------------- /assets/usage2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdlrt/xproxy/HEAD/assets/usage2.png -------------------------------------------------------------------------------- /assets/usage3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdlrt/xproxy/HEAD/assets/usage3.png -------------------------------------------------------------------------------- /server.yml: -------------------------------------------------------------------------------- 1 | proxy: 2 | rules: 3 | ^/api(.*): 'https://www.aliyun.com/' -------------------------------------------------------------------------------- /src/css/common.less: -------------------------------------------------------------------------------- 1 | .ant-list-split .ant-list-item { 2 | border-bottom: 0; 3 | } -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | repo_token: xUkmPXxSeo7kOFrrZZNoF1NXDG0zrrSI5 -------------------------------------------------------------------------------- /assets/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdlrt/xproxy/HEAD/assets/overview.png -------------------------------------------------------------------------------- /assets/overview2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdlrt/xproxy/HEAD/assets/overview2.png -------------------------------------------------------------------------------- /src/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdlrt/xproxy/HEAD/src/images/icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules/ 4 | .nyc_output/ 5 | coverage/ 6 | build/ -------------------------------------------------------------------------------- /src/scripts/utils/toast.js: -------------------------------------------------------------------------------- 1 | import { message } from 'antd'; 2 | 3 | message.config({ 4 | top: 180, 5 | duration: 2, 6 | maxCount: 3 7 | }); 8 | 9 | export default message; -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | before_install: 5 | - npm install -g dawn 6 | script: 7 | - npm test 8 | after_script: 9 | - npm run coveralls 10 | notifications: 11 | email: 12 | on_success: never -------------------------------------------------------------------------------- /src/scripts/constants/regExp.js: -------------------------------------------------------------------------------- 1 | // check if url is legal 2 | export const CHECK_IS_LEGAL = /http(s?):\/\/.*\.(js|css|json|jsonp)/; 3 | 4 | // check if originUrl include regExp 5 | // check if [ ] ( ) \ * ^ $ exist 6 | export const ORIGIN_URL_REG = /\\|\[|]|\(|\)|\*|\$|\^/i; -------------------------------------------------------------------------------- /src/popup.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import 'antd/dist/antd.css'; 4 | import './css/common.less'; 5 | import Home from './scripts/pages/Home'; 6 | 7 | render( 8 | , 9 | document.getElementById('app') 10 | ); 11 | -------------------------------------------------------------------------------- /src/scripts/constants/defaultData.js: -------------------------------------------------------------------------------- 1 | const defaultData = { 2 | id: 'ioahsfioh', 3 | proxyList: [{ 4 | title: '样例', 5 | checked: false, 6 | url: 'https://baidu.com', 7 | redirectUrl: 'https://taobao.com' 8 | }] 9 | }; 10 | 11 | export default defaultData; -------------------------------------------------------------------------------- /src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | xproxy 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xproxy", 3 | "version": "0.0.1", 4 | "description": "", 5 | "scripts": { 6 | "test": "dn test", 7 | "coveralls": "nyc report --reporter=text-lcov | coveralls" 8 | }, 9 | "author": { 10 | "name": "yeshu", 11 | "email": "yeshu.lrt@alibaba-inc.com" 12 | }, 13 | "license": "MIT", 14 | "devDependencies": { 15 | "coveralls": "^3.0.1", 16 | "nyc": "^11.8.0" 17 | }, 18 | "dependencies": { 19 | "antd": "^3.5.2", 20 | "mota": "^0.6.0", 21 | "react": "^16.3.2", 22 | "react-dom": "^16.3.2", 23 | "styled-components": "^3.2.6", 24 | "uuid": "^3.2.1" 25 | } 26 | } -------------------------------------------------------------------------------- /src/scripts/components/Menu/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Menu, Icon } from 'antd'; 3 | 4 | export default class MenuComponent extends React.Component { 5 | 6 | render() { 7 | return ( 8 | 9 | 10 | 11 | Option 1 12 | 13 | 14 | 15 | Option 2 16 | 17 | 18 | 19 | Option 3 20 | 21 | 22 | ); 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /src/scripts/pages/Home/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { model } from 'mota'; 3 | import styled from 'styled-components'; 4 | import Group from '../Group'; 5 | // import Menu from '../../components/Menu'; 6 | 7 | const Container = styled.div` 8 | position: relative; 9 | margin: 0 auto; 10 | padding: 16px; 11 | width: 600px; 12 | height: 600px; 13 | `; 14 | 15 | // const CustomMenu = styled(Menu)` 16 | // position: absolute; 17 | // left: 16px; 18 | // width: 240px; 19 | // `; 20 | 21 | @model 22 | export default class Home extends React.Component { 23 | 24 | render() { 25 | return ( 26 | 27 | {/* */} 28 | 29 | 30 | ); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /test/unit/demo.js: -------------------------------------------------------------------------------- 1 | // // 相等或不相等 2 | // expect(4 + 5).to.be.equal(9); 3 | // expect(4 + 5).to.be.not.equal(10); 4 | // expect(foo).to.be.deep.equal({ bar: 'baz' }); 5 | 6 | // // 布尔值为true 7 | // expect('everthing').to.be.ok; 8 | // expect(false).to.not.be.ok; 9 | 10 | // // typeof 11 | // expect('test').to.be.a('string'); 12 | // expect({ foo: 'bar' }).to.be.an('object'); 13 | // expect(foo).to.be.an.instanceof(Foo); 14 | 15 | // // include 16 | // expect([1, 2, 3]).to.include(2); 17 | // expect('foobar').to.contain('foo'); 18 | // expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); 19 | 20 | // // empty 21 | // expect([]).to.be.empty; 22 | // expect('').to.be.empty; 23 | // expect({}).to.be.empty; 24 | 25 | // // match 26 | // expect('foobar').to.match(/^foo/); -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "xproxy", 4 | "version": "0.0.5", 5 | "description": "A Chrome Extension for forwarding request urls.", 6 | "icons": { 7 | "16": "images/icon.png", 8 | "48": "images/icon.png", 9 | "128": "images/icon.png" 10 | }, 11 | "background": { 12 | "scripts": ["background.js", "forward.js"] 13 | }, 14 | "browser_action": { 15 | "default_icon": "images/icon.png", 16 | "default_title": "chrome请求转发插件", 17 | "default_popup": "popup.html" 18 | }, 19 | "permissions": [ 20 | "webRequest", 21 | "storage", 22 | "webRequestBlocking", 23 | "browsingData", 24 | "" 25 | ], 26 | "homepage_url": "https://github.com/xdlrt/xproxy", 27 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" 28 | } -------------------------------------------------------------------------------- /src/scripts/components/ListItem/Content.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { model, binding, watch } from 'mota'; 3 | import styled from 'styled-components'; 4 | import { Input } from 'antd'; 5 | 6 | const Container = styled.div``; 7 | 8 | const CustomInput = styled(Input) ` 9 | margin-bottom: 8px; 10 | `; 11 | 12 | @model 13 | @binding 14 | export default class PanelItem extends React.Component { 15 | 16 | @watch(model => model.url + model.redirectUrl) 17 | watchItem() { 18 | this.model.list.saveItems(this.model.list.items); 19 | } 20 | 21 | render() { 22 | return ( 23 | 24 | 25 | 26 | 27 | ); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /.dawn/pipe.yml: -------------------------------------------------------------------------------- 1 | init: 2 | - name: pkginfo 3 | 4 | dev: 5 | - name: clean 6 | - name: webpack 7 | watch: true 8 | common: 9 | disabled: true 10 | sourceMap: false 11 | template: ./src/*.html 12 | folders: 13 | js: ./ 14 | - name: copy 15 | files: 16 | ./build/(0).json: ./src/*.json 17 | ./build/images/: ./src/images/* 18 | ./build/lib/: ./src/lib/* 19 | - name: server 20 | - name: browser-sync 21 | 22 | build: 23 | - name: clean 24 | - name: webpack 25 | common: 26 | disabled: true 27 | sourceMap: false 28 | template: ./src/*.html 29 | folders: 30 | js: ./ 31 | - name: copy 32 | files: 33 | ./build/(0).json: ./src/*.json 34 | ./build/images/: ./src/images/* 35 | ./build/lib/: ./src/lib/* 36 | 37 | test: 38 | - name: lint 39 | global: chrome:true 40 | - name: unit -------------------------------------------------------------------------------- /src/scripts/models/ListItem.js: -------------------------------------------------------------------------------- 1 | import uuid from 'uuid'; 2 | 3 | export default class ListItemModel { 4 | id; 5 | url; 6 | redirectUrl; 7 | checked = false; 8 | title; 9 | description; 10 | 11 | _list = {}; 12 | _titleEditing = false; 13 | 14 | constructor(list, item) { 15 | this.id = uuid(); 16 | this._list = list || {}; 17 | this.title = item.title || this.id; 18 | this.description = item.description; 19 | this.url = item.url || ''; 20 | this.redirectUrl = item.redirectUrl || ''; 21 | this.checked = item.checked || false; 22 | } 23 | 24 | get list() { 25 | return this._list; 26 | } 27 | 28 | get titleEditing() { 29 | return this._titleEditing; 30 | } 31 | 32 | removeItem = () => { 33 | this.list.removeItem(this.id); 34 | } 35 | 36 | editTitle = () => { 37 | this._titleEditing = true; 38 | } 39 | 40 | exitEditTitle = () => { 41 | this._titleEditing = false; 42 | } 43 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present yeshu (xdlrt0111@163.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/scripts/utils/storage.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | import defaultData from '../constants/defaultData'; 3 | 4 | export function getListData(listModel) { 5 | chrome.storage.sync.get('xproxyConfig', (res) => { 6 | if (!res.xproxyConfig) { 7 | defaultData.proxyList.forEach(item => listModel.addItem(item)); 8 | chrome.storage.sync.set( 9 | { xproxyConfig: defaultData }, 10 | () => { console.log('保存默认数据成功'); } 11 | ); 12 | } 13 | else { 14 | res.xproxyConfig.proxyList.forEach(item => listModel.addItem(item)); 15 | } 16 | }); 17 | } 18 | 19 | export function saveListData(items = []) { 20 | const proxyList = items.map(item => { 21 | const { title, url, redirectUrl, checked } = item; 22 | return { title, url, redirectUrl, checked }; 23 | }); 24 | chrome.storage.sync.set({ 25 | xproxyConfig: { proxyList } 26 | }, () => { console.log('设置 xproxyConfig 成功') }); 27 | } 28 | 29 | export function saveXproxyDisabled(bool) { 30 | chrome.storage.sync.set({ 31 | xproxyDisabled: bool ? '' : 'disabled' 32 | }, () => { console.log('设置 xproxyDisabled 成功') }); 33 | } -------------------------------------------------------------------------------- /src/scripts/models/List.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | import uuid from 'uuid'; 3 | import ListItemModel from './listItem'; 4 | import { saveListData, saveXproxyDisabled } from '../utils/storage'; 5 | 6 | class ListModel { 7 | id = ''; 8 | items = []; 9 | 10 | // 开关状态,on = true 11 | _listState = false; 12 | 13 | constructor() { 14 | this.id = uuid(); 15 | } 16 | 17 | get listState() { 18 | chrome.storage.sync.get('xproxyDisabled', (result) => { 19 | if ('xproxyDisabled' in result){ 20 | this._listState = result.xproxyDisabled === 'disabled' ? false : true; 21 | } 22 | }); 23 | return this._listState; 24 | } 25 | 26 | changeListState = (val) => { 27 | saveXproxyDisabled(val); 28 | this._listState = val; 29 | } 30 | 31 | addItem = (item = {}) => { 32 | this.items.push(new ListItemModel(this, item)); 33 | this.saveItems(this.items); 34 | } 35 | 36 | removeItem = (id) => { 37 | this.items = this.items.filter(item => item.id !== id); 38 | this.saveItems(this.items); 39 | } 40 | 41 | saveItems = () => { 42 | saveListData(this.items); 43 | } 44 | } 45 | 46 | const listModel = new ListModel(); 47 | 48 | export default listModel; -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | /* global chrome */ 2 | window.xproxyDisabled = 'disabled'; // if 'disabled',this extension will be disabled 3 | window.isCacheCleaning = false; // check if cleaning cache 4 | window.xproxyConfig = {}; // config 5 | 6 | chrome.storage.onChanged.addListener(changes => { 7 | if (changes.xproxyConfig) { 8 | window.xproxyConfig = changes.xproxyConfig.newValue; 9 | } 10 | if (changes.xproxyDisabled) { 11 | window.xproxyDisabled = changes.xproxyDisabled.newValue; 12 | } 13 | }); 14 | 15 | chrome.storage.sync.get('xproxyConfig', result => { 16 | window.xproxyConfig = result.xproxyConfig; 17 | }); 18 | 19 | chrome.storage.sync.get('xproxyDisabled', result => { 20 | window.xproxyDisabled = result.xproxyDisabled; 21 | }); 22 | 23 | // clear browser cache 24 | function clearCache() { 25 | if (!window.isCacheCleaning) { 26 | window.isCacheCleaning = true; 27 | const millisecondsPerWeek = 1000 * 60 * 60 * 24 * 7; 28 | const oneWeekAgo = new Date().getTime() - millisecondsPerWeek; 29 | chrome.browsingData.removeCache({ 30 | since: oneWeekAgo 31 | }, () => { 32 | window.isCacheCleaning = false; 33 | }); 34 | } 35 | } 36 | 37 | chrome.webRequest.onBeforeRequest.addListener( 38 | (details) => { 39 | if (window.xproxyDisabled !== 'disabled') { 40 | clearCache(); 41 | return window.onBeforeRequestCallback(details); 42 | } 43 | return {}; 44 | }, 45 | { 46 | urls: [''] 47 | }, 48 | ['blocking'] 49 | ); 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | ![license](https://img.shields.io/badge/license-MIT-blue.svg) 5 | ![npm](https://img.shields.io/badge/npm-v5.4.2-blue.svg) 6 | [![Build Status](https://travis-ci.org/xdlrt/xproxy.svg?branch=master)](https://travis-ci.org/xdlrt/xproxy) 7 | [![Coverage Status](https://coveralls.io/repos/github/xdlrt/xproxy/badge.svg?branch=master)](https://coveralls.io/github/xdlrt/xproxy?branch=master) 8 | [![inspired by](https://img.shields.io/badge/inspired%20by-xswitch-lightgrey.svg)](https://github.com/yize/xswitch) 9 | 10 |
11 | 12 | [English README](./README-EN.md) 13 | 14 | 一个通过制定的规则来重定向请求的 Chrome 浏览器插件,灵感来源于[xswitch](https://github.com/yize/xswitch),并且利用 React 重构整个项目。 15 | 16 | ## 解决的痛点 17 | 在日常开发和调试过程中,由于测试环境的文件变更需要使用 CDN 上的静态文件,修改后需要重新发布,十分低效和繁琐,因此需要把线上或者测试环境的 CSS、JS 等静态文件转发到本地服务器,因此需要一个方便快捷的可以管理 url 转发的工具。 18 | 19 | ## 特点 20 | 21 | - 规则组开关控制 22 | - 灵活的单个规则开关控制 23 | - 通过规则来控制请求的url重定向 24 | - 规则灵活,支持字符串匹配和正则表达式 25 | - 当此插件生效时禁用浏览器缓存 26 | - UI 界面更加简洁易用 27 | - 完备的单元测试来保障重定向规则的准确性 28 | 29 | ## 安装 30 | 31 | 在 chrome 应用商店中安装:[xproxy](https://chrome.google.com/webstore/detail/xproxy/hafgnnmjcganjajbeilchhdcmnpdmdkm) 32 | 33 | 也可以下载最新的 release 并在 Chrome 浏览器中以未打包的形式安装。 34 | 35 | ## 使用 36 | 37 |

38 | 39 |

40 | 41 | - 规则1: 42 | 请求 `https://baidu.com` 时,浏览器会将它重定向为 `https://taobao.com`. 43 | 44 | - 规则2: 45 | 请求 `https://g.alicdn.com/a.js` 时,浏览器会将它重定向为 `https://aliyun.alicdn.com/a.js` 46 | 47 | 详细用法请见:[usages](./doc/usages.md) 48 | 49 | tips: 目前只支持 http(s) 协议请求的转发 50 | 51 | ## License 52 | [MIT](https://opensource.org/licenses/MIT) © [yeshu.lrt](https://xdlrt.github.io/) 53 | -------------------------------------------------------------------------------- /doc/usages.md: -------------------------------------------------------------------------------- 1 | # 使用说明 2 | 3 | 注意: 4 | - 不填写 redirect url 是不会触发重定向的 5 | - `chrome-extension://` 开头的 url 是不会触发重定向的 6 | - 规则未选中是不会触发重定向的 7 | - 目前只支持 http(s) 的请求转发 8 | 9 | ## 示例 10 | 分为两种模式,一种为全匹配模式,一种为正则表达式模式。 11 | 12 | ### 全匹配模式 13 | 全匹配模式较为简单,当前请求的 url 中包含 origin url 规则时,会将 origin url 的规则对应替换为 redirect url 规则。 14 | 15 | 例如: 16 | ``` 17 | url: g.alicdn.com 18 | redirectUrl: g.alicdn.com?t=2 19 | ``` 20 | 21 | 对应转发的结果如下: 22 | 23 | | origin | redirect | 24 | | ---------- | --- | 25 | | https://g.alicdn.com | https://g.alicdn.com?t=2 | 26 | | https://g.alicdn.com?t=1 | https://g.alicdn.com?t=2 | 27 | | https://g.alicdn.com#aaaa | https://g.alicdn.com?t=2#aaaa | 28 | | https://g.alicdn.com/??a.js,b.js,c.js | https://g.alicdn.com?t=2/??a.js,b.js,c.js | 29 | 30 | ### 正则表达式模式 31 | 正则表达式模式中,origin url 规则和 rediect url 规则均可使用正则表达式进行转发规则的制订。 32 | 33 | 例如: 34 | ``` 35 | url: g.(\\w+).com 36 | redirectUrl: g.alicdn.com?t=2 37 | ``` 38 | 39 | 对应的转发结果如下: 40 | 41 | | origin | redirect | 42 | | ---------- | --- | 43 | | https://g1.alicdn.com | none | 44 | | https://g.alicdn.com | https://g.alicdn.com?t=2 | 45 | | https://g.alicdn.com?t=1 | https://g.alicdn.com?t=2 | 46 | | https://g.alicdn.com#aaaa | https://g.alicdn.com?t=2#aaaa | 47 | | https://g.alicdn.com/??a.js,b.js,c.js | https://g.alicdn.com?t=2/??a.js,b.js,c.js | 48 | 49 | 又例如: 50 | 51 | ``` 52 | url: (.*)g.(.*).com\\?t=1 53 | redirectUrl: $1g.alicdn.com?t=2 54 | ``` 55 | 56 | | origin | redirect | 57 | | ---------- | --- | 58 | | https://g1.alicdn.com | none | 59 | | http://g.alicdn.com?t=1&k=2 | http://g.alicdn.com?t=2&k=2| 60 | | https://g.alicdn.com?t=1 | https://g.alicdn.com?t=2 | 61 | | https://g.alicdn.com#aaaa | none | 62 | | https://g.alicdn.com?t=1/??a.js,b.js,c.js | https://g.alicdn.com?t=2/??a.js,b.js,c.js | -------------------------------------------------------------------------------- /src/scripts/components/ListItem/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { model, binding, watch, bindable } from 'mota'; 3 | import styled from 'styled-components'; 4 | import { Icon, Input, Checkbox } from 'antd'; 5 | const BindCheckbox = bindable('checkbox', Checkbox); 6 | 7 | const Container = styled.div` 8 | position: relative; 9 | height: 24px; 10 | `; 11 | 12 | const CustomIcon = styled(Icon)` 13 | float: right; 14 | line-height: 26px; 15 | cursor: pointer; 16 | `; 17 | 18 | const Title = styled.span` 19 | display: inline-block; 20 | width: 300px; 21 | overflow: hidden; 22 | text-overflow: ellipsis; 23 | white-space: nowrap; 24 | vertical-align: bottom; 25 | `; 26 | 27 | const TitleInput = styled(Input)` 28 | position: absolute; 29 | top: 0; 30 | left: 0; 31 | `; 32 | 33 | @model 34 | @binding 35 | export default class PanelItem extends React.Component { 36 | 37 | exitEditTitle = (event) => { 38 | if (event.keyCode !== 13 || !this.model.title) return; 39 | this.model.exitEditTitle(); 40 | } 41 | 42 | @watch(model => model.title + model.checked) 43 | watchItem() { 44 | this.model.list.saveItems(this.model.list.items); 45 | } 46 | 47 | render() { 48 | const { title, titleEditing } = this.model; 49 | return ( 50 | 51 | 52 | {title} 53 | 54 | {titleEditing 55 | ? 60 | : null} 61 | 62 | ); 63 | } 64 | } -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | parser: babel-eslint 2 | plugins: 3 | - react 4 | - html 5 | env: 6 | es6: true 7 | browser: true 8 | commonjs: true 9 | extends: 10 | - 'eslint:recommended' 11 | ecmaFeatures: 12 | jsx: true 13 | modules: true 14 | experimentalObjectRestSpread: true 15 | parserOptions: 16 | ecmaVersion: 6 17 | sourceType": module 18 | ecmaFeatures: 19 | jsx: true 20 | modules: true 21 | experimentalObjectRestSpread: true 22 | rules: 23 | strict: 24 | - 0 25 | indent: 26 | - 2 27 | - 2 28 | - SwitchCase: 1 29 | quotes: 30 | - 2 31 | - single 32 | linebreak-style: 33 | - 2 34 | - unix 35 | semi: 36 | - 2 37 | - always 38 | no-multi-spaces: 39 | - 2 40 | no-self-compare: 41 | - 2 42 | max-depth: 43 | - 2 44 | - 4 45 | max-nested-callbacks: 46 | - 2 47 | - 4 48 | max-params: 49 | - 2 50 | - 4 51 | max-statements: 52 | - 2 53 | - 25 54 | max-statements-per-line: 55 | - 2 56 | max-len: 57 | - 2 58 | - 120 59 | multiline-ternary: 60 | - 0 61 | callback-return: 62 | - 2 63 | handle-callback-err: 64 | - 2 65 | array-bracket-spacing: 66 | - 2 67 | no-const-assign: 68 | - 2 69 | no-return-assign: 70 | - 0 71 | no-inner-declarations: 72 | - 2 73 | no-var: 74 | - 2 75 | no-console: 76 | - 1 77 | no-lonely-if: 78 | - 2 79 | require-jsdoc: 80 | - 0 81 | - require: 82 | FunctionDeclaration: true 83 | MethodDefinition: true 84 | ClassDeclaration: true 85 | valid-jsdoc: 86 | - 2 87 | comma-dangle: 88 | - 2 89 | - never 90 | no-undef: 91 | - 2 92 | react/jsx-uses-react: 93 | - 2 94 | react/jsx-uses-vars: 95 | - 2 96 | react/jsx-no-undef: 97 | - 2 98 | -------------------------------------------------------------------------------- /src/forward.js: -------------------------------------------------------------------------------- 1 | import { CHECK_IS_LEGAL, ORIGIN_URL_REG } from './scripts/constants/regExp'; 2 | 3 | window.lastRequestId = null; 4 | window.urls = new Array(200); // for cache 5 | 6 | const redirectToMatchingRule = (details) => { 7 | const rules = window.xproxyConfig.proxyList; 8 | const originUrl = details.url; 9 | let redirectUrl; 10 | 11 | // exclude chrome extension 12 | if (!rules || !rules.length || /^chrome-extension:\/\//i.test(originUrl)) { 13 | return {}; 14 | } 15 | 16 | // check if url is legal 17 | if (CHECK_IS_LEGAL.test(originUrl) && window.urls.indexOf(originUrl) < 0) { 18 | window.urls.shift(); 19 | window.urls.push(originUrl); 20 | } 21 | 22 | rules.forEach(rule => { 23 | 24 | if (!rule.url || !rule.redirectUrl || rule.checked === false) { 25 | return; 26 | } 27 | 28 | let reg = rule.url; 29 | let isMatched = false; 30 | 31 | // check if [ ] ( ) \ * ^ $ exist 32 | if (ORIGIN_URL_REG.test(rule.url)) { 33 | // transform originUrl into regExp 34 | // check if ?? exist, if true, transform ?? to regExp format 35 | reg = new RegExp(reg.replace('??', '\\?\\?'), 'i'); 36 | isMatched = reg.test(originUrl); 37 | } else { 38 | // originUrl rules directly include rule.url 39 | isMatched = originUrl.indexOf(reg) > -1; 40 | } 41 | 42 | if (isMatched && details.requestId !== window.lastRequestId) { 43 | // console.log(redirectUrl, reg, rule.redirectUrl); 44 | redirectUrl = redirectUrl 45 | ? redirectUrl.replace(reg, rule.redirectUrl) 46 | : originUrl.replace(reg, rule.redirectUrl); 47 | } 48 | 49 | }); 50 | 51 | window.lastRequestId = details.requestId; 52 | 53 | if (!redirectUrl) { 54 | redirectUrl = originUrl; 55 | } 56 | 57 | return redirectUrl === details.url ? {} : { redirectUrl }; 58 | }; 59 | 60 | window.onBeforeRequestCallback = (details) => redirectToMatchingRule(details); 61 | 62 | export default { redirectToMatchingRule }; -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | ![license](https://img.shields.io/badge/license-MIT-blue.svg) 5 | ![npm](https://img.shields.io/badge/npm-v5.4.2-blue.svg) 6 | [![Build Status](https://travis-ci.org/xdlrt/xproxy.svg?branch=master)](https://travis-ci.org/xdlrt/xproxy) 7 | [![Coverage Status](https://coveralls.io/repos/github/xdlrt/xproxy/badge.svg?branch=master)](https://coveralls.io/github/xdlrt/xproxy?branch=master) 8 | [![inspired by](https://img.shields.io/badge/inspired%20by-xswitch-lightgrey.svg)](https://github.com/yize/xswitch) 9 | 10 |
11 | 12 | A Chrome extension for forward requests by rules which was inspired by [xswitch](https://github.com/yize/xswitch) and reconstruct with React. 13 | 14 | ## The problem 15 | 16 | In the daily development and debugging process, due to the file change of the test environment, the static files on the CDN are needed, and they need to be republished after modification. This is very inefficient and cumbersome. Therefore, it is necessary to forward static files such as CSS and JS on the online or test environment to the local server, so you need a convenient tool that can manage url forwarding. 17 | 18 | ## Features 19 | 20 | - Group switch control 21 | - Flexible single-rule switch control 22 | - Redirect request.url by forwarding rules 23 | - Flexible rules, support for string matching and regular expressions 24 | - Disable browser cache when this tool is activated 25 | - A more friendly UI interface 26 | - Complete unit testing to ensure accuracy of forwarding rules 27 | 28 | ## Install 29 | 30 | you can install this extension in chrome app store: [xproxy](https://chrome.google.com/Pebstore/detail/xproxy/hafgnnmjcganjajbeilchhdcmnpdmdkm) 31 | 32 | You can also download the lastest realease and load unpacked extension in Chrome. 33 | 34 | ## Usage 35 | 36 |

37 | 38 |

39 | 40 | - rule 1: 41 | request `https://baidu.com` and browser will redirect it to `https://taobao.com`. 42 | 43 | - rule 2: 44 | request `https://g.alicdn.com/a.js` and browser will redirect it to `https://aliyun.alicdn.com/a.js`. 45 | 46 | more details will be find here: [usages](./doc/usages.md) 47 | 48 | tips: only support forwarding http(s) request urls 49 | 50 | ## License 51 | 52 | [MIT](https://opensource.org/licenses/MIT) © [yeshu.lrt](https://xdlrt.github.io/) 53 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "plugins": [ 4 | "react", 5 | "html" 6 | ], 7 | "env": { 8 | "es6": true, 9 | "browser": true, 10 | "commonjs": true 11 | }, 12 | "extends": [ 13 | "eslint:recommended" 14 | ], 15 | "ecmaFeatures": { 16 | "jsx": true, 17 | "modules": true, 18 | "experimentalObjectRestSpread": true 19 | }, 20 | "parserOptions": { 21 | "ecmaVersion": 6, 22 | "sourceType\"": "module", 23 | "ecmaFeatures": { 24 | "jsx": true, 25 | "modules": true, 26 | "experimentalObjectRestSpread": true 27 | } 28 | }, 29 | "rules": { 30 | "strict": [ 31 | 0 32 | ], 33 | "indent": [ 34 | 2, 35 | 2, 36 | { 37 | "SwitchCase": 1 38 | } 39 | ], 40 | "quotes": [ 41 | 2, 42 | "single" 43 | ], 44 | "linebreak-style": [ 45 | 2, 46 | "unix" 47 | ], 48 | "semi": [ 49 | 2, 50 | "always" 51 | ], 52 | "no-multi-spaces": [ 53 | 2 54 | ], 55 | "no-self-compare": [ 56 | 2 57 | ], 58 | "max-depth": [ 59 | 2, 60 | 4 61 | ], 62 | "max-nested-callbacks": [ 63 | 2, 64 | 4 65 | ], 66 | "max-params": [ 67 | 2, 68 | 4 69 | ], 70 | "max-statements": [ 71 | 2, 72 | 25 73 | ], 74 | "max-statements-per-line": [ 75 | 2 76 | ], 77 | "max-len": [ 78 | 2, 79 | 120 80 | ], 81 | "multiline-ternary": [ 82 | 0 83 | ], 84 | "callback-return": [ 85 | 2 86 | ], 87 | "handle-callback-err": [ 88 | 2 89 | ], 90 | "array-bracket-spacing": [ 91 | 2 92 | ], 93 | "no-const-assign": [ 94 | 2 95 | ], 96 | "no-return-assign": [ 97 | 0 98 | ], 99 | "no-inner-declarations": [ 100 | 2 101 | ], 102 | "no-var": [ 103 | 2 104 | ], 105 | "no-console": [ 106 | 1 107 | ], 108 | "no-lonely-if": [ 109 | 2 110 | ], 111 | "require-jsdoc": [ 112 | 0, 113 | { 114 | "require": { 115 | "FunctionDeclaration": true, 116 | "MethodDefinition": true, 117 | "ClassDeclaration": true 118 | } 119 | } 120 | ], 121 | "valid-jsdoc": [ 122 | 2 123 | ], 124 | "comma-dangle": [ 125 | 2, 126 | "never" 127 | ], 128 | "no-undef": [ 129 | 2 130 | ], 131 | "react/jsx-uses-react": [ 132 | 2 133 | ], 134 | "react/jsx-uses-vars": [ 135 | 2 136 | ], 137 | "react/jsx-no-undef": [ 138 | 2 139 | ] 140 | } 141 | } -------------------------------------------------------------------------------- /src/scripts/pages/Group/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { model } from 'mota'; 3 | import styled from 'styled-components'; 4 | import ListModel from '../../models/List'; 5 | import { Switch, Button, List } from 'antd'; 6 | import ItemHeader from '../../components/ListItem/Header'; 7 | import ItemContent from '../../components/ListItem/Content'; 8 | import { getListData } from '../../utils/storage'; 9 | const Item = List.Item; 10 | 11 | // const Container = styled.div` 12 | // position: absolute; 13 | // top: 16px; 14 | // right: 16px; 15 | // width: 500px; 16 | // `; 17 | 18 | const Container = styled.div` 19 | margin: 0 auto; 20 | width: 500px; 21 | `; 22 | 23 | const Header = styled.div` 24 | margin-bottom: 16px; 25 | `; 26 | 27 | const HeaderButton = styled(Button) ` 28 | margin-right: 8px; 29 | `; 30 | 31 | const HeaderSwitch = styled(Switch) ` 32 | float: right; 33 | margin-top: 5px; 34 | `; 35 | 36 | // const CustomList = styled(List) ` 37 | // position: absolute; 38 | // top: 60px; 39 | // right: 0; 40 | // width: 100%; 41 | // height: 500px; 42 | // padding: 2px 1px 20px; 43 | // overflow-x: hidden; 44 | // overflow-y: auto; 45 | // `; 46 | 47 | const CustomList = styled(List)` 48 | width: 100%; 49 | height: 500px; 50 | padding: 2px 1px 20px; 51 | overflow-x: hidden; 52 | overflow-y: auto; 53 | `; 54 | 55 | const CustomItem = styled(Item) ` 56 | margin-bottom: 16px; 57 | padding: 16px 16px 0; 58 | border: 0; 59 | border-radius: 5px; 60 | background: #f7f7f7; 61 | box-shadow: 0 0 0 1px rgba(0, 0, 0, .1); 62 | overflow: hidden; 63 | `; 64 | 65 | @model(ListModel) 66 | export default class Group extends React.Component { 67 | 68 | componentDidMount() { 69 | // this timer is to avoid chrome bug 70 | // https://bugs.chromium.org/p/chromium/issues/detail?id=428044 71 | setTimeout(() => { 72 | getListData(this.model); 73 | }, 100); 74 | } 75 | 76 | render() { 77 | return ( 78 | 79 |
80 | 添加规则 81 | 86 |
87 | ( 92 | 93 | } 95 | description={item.description} 96 | /> 97 | 98 | 99 | )} 100 | /> 101 |
102 | ); 103 | } 104 | 105 | } -------------------------------------------------------------------------------- /src/lib/react.js: -------------------------------------------------------------------------------- 1 | /** @license React v16.3.2 2 | * react.production.min.js 3 | * 4 | * Copyright (c) 2013-present, Facebook, Inc. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';(function(p,h){"object"===typeof exports&&"undefined"!==typeof module?module.exports=h():"function"===typeof define&&define.amd?define(h):p.React=h()})(this,function(){function p(a){for(var b=arguments.length-1,e="http://reactjs.org/docs/error-decoder.html?invariant\x3d"+a,c=0;cu.length&&u.push(a)}function t(a,b,e,c){var f=typeof a;if("undefined"===f||"boolean"===f)a=null;var k=!1;if(null===a)k=!0;else switch(f){case "string":case "number":k=!0;break;case "object":switch(a.$$typeof){case r:case Q:k=!0}}if(k)return e(c,a,""===b?"."+y(a,0):b),1;k=0;b=""===b?".":b+":";if(Array.isArray(a))for(var d=0;da;a++)b["_"+String.fromCharCode(a)]=a;if("0123456789"!==Object.getOwnPropertyNames(b).map(function(a){return b[a]}).join(""))return!1;var e={};"abcdefghijklmnopqrst".split("").forEach(function(a){e[a]=a});return"abcdefghijklmnopqrst"!==Object.keys(Object.assign({},e)).join("")?!1:!0}catch(c){return!1}}()?Object.assign:function(a,b){if(null===a||void 0===a)throw new TypeError("Object.assign cannot be called with null or undefined");var e= 16 | Object(a);for(var c,f=1;f { 6 | 7 | beforeEach(function () { 8 | // 在本区块的每个测试用例之前执行 9 | window.xproxyConfig = {}; 10 | window.lastRequestId = null; 11 | window.urls = new Array(200); 12 | }); 13 | 14 | it('no forwarding when no rules', () => { 15 | window.xproxyConfig = {}; 16 | expect(redirectToMatchingRule({ url: 'g.alicdn.com' })).to.deep.equal({}); 17 | expect(redirectToMatchingRule({ 18 | url: 'https://g.alicdn.com??a.js,b.js,c.js', 19 | requestId: 2 20 | })).to.deep.equal({}); 21 | }); 22 | 23 | it('redirectUrl does not exist', () => { 24 | window.xproxyConfig = { 25 | id: 'ioahsfioh', 26 | proxyList: [ 27 | { 28 | title: 'test0', 29 | url: 'https://g.alicdn.com' 30 | }, 31 | { 32 | title: 'test', 33 | url: 'https://baidu.com', 34 | redirectUrl: 'https://taobao.com' 35 | } 36 | ] 37 | }; 38 | expect(redirectToMatchingRule({ 39 | url: 'g.alicdn.com', 40 | requestId: 1 41 | })).to.deep.equal({}); 42 | expect(redirectToMatchingRule({ 43 | url: 'https://g.alicdn.com??a.js,b.js,c.js', 44 | requestId: 2 45 | })).to.deep.equal({}); 46 | }); 47 | 48 | it('chrome-extension:// should not forward', () => { 49 | window.xproxyConfig = { 50 | id: 'ioahsfioh', 51 | proxyList: [ 52 | { 53 | title: 'test', 54 | url: '(.*).js', 55 | redirectUrl: '$1.js' 56 | }, 57 | { 58 | title: 'test1', 59 | url: 'xxxxx', 60 | redirectUrl: 'xxxx' 61 | } 62 | ] 63 | }; 64 | expect(redirectToMatchingRule({ 65 | url: 'chrome-extension://xxxxx/a.js', 66 | requestId: 1 67 | })).to.deep.equal({}); 68 | }); 69 | 70 | it('same request id should not forwarding', () => { 71 | window.xproxyConfig = { 72 | id: 'ioahsfioh', 73 | proxyList: [ 74 | { 75 | title: 'test0', 76 | url: 'https://g.alicdn.com', 77 | redirectUrl: 'https://taobao.com' 78 | } 79 | ] 80 | }; 81 | expect(redirectToMatchingRule({ 82 | url: 'g.alicdn.com', 83 | requestId: 1 84 | })).to.deep.equal({}); 85 | expect(redirectToMatchingRule({ 86 | url: 'https://g.alicdn.com??a.js,b.js,c.js', 87 | requestId: 1 88 | })).to.deep.equal({}); 89 | }); 90 | 91 | it('when checked is false should not forward', () => { 92 | window.xproxyConfig = { 93 | id: 'ioahsfioh', 94 | proxyList: [ 95 | { 96 | title: 'test0', 97 | checked: true, 98 | url: 'www.baidu.com', 99 | redirectUrl: 'taobao.com' 100 | }, 101 | { 102 | title: 'test0', 103 | checked: false, 104 | url: 'www.douban.com', 105 | redirectUrl: 'tmall.com' 106 | } 107 | ] 108 | }; 109 | expect( 110 | redirectToMatchingRule({ 111 | url: 'https://www.baidu.com', 112 | requestId: 1 113 | }).redirectUrl 114 | ).to.be.equal('https://taobao.com'); 115 | expect(redirectToMatchingRule({ 116 | url: 'https://www.douban.com', 117 | requestId: 2 118 | })).to.deep.equal({}); 119 | }); 120 | 121 | }); 122 | 123 | describe('normal urls which should forward', () => { 124 | 125 | beforeEach(function () { 126 | // 在本区块的每个测试用例之前执行 127 | window.xproxyConfig = {}; 128 | window.lastRequestId = null; 129 | window.urls = new Array(200); 130 | }); 131 | 132 | it('should forwarding url without query string', () => { 133 | window.xproxyConfig = { 134 | id: 'ioahsfioh', 135 | proxyList: [ 136 | { 137 | title: 'test0', 138 | url: 'g.alicdn.com', 139 | redirectUrl: 'g.alicdn.com?t=2' 140 | } 141 | ] 142 | }; 143 | expect( 144 | redirectToMatchingRule({ 145 | url: 'https://g.alicdn.com', 146 | requestId: 1 147 | }).redirectUrl 148 | ).to.be.equal('https://g.alicdn.com?t=2'); 149 | expect( 150 | redirectToMatchingRule({ 151 | url: 'https://g.alicdn.com#aaaa', 152 | requestId: 2 153 | }).redirectUrl 154 | ).to.be.equal('https://g.alicdn.com?t=2#aaaa'); 155 | expect( 156 | redirectToMatchingRule({ 157 | url: 'https://g.alicdn.com/??a.js,b.js,c.js', 158 | requestId: 3 159 | }).redirectUrl 160 | ).to.be.equal('https://g.alicdn.com?t=2/??a.js,b.js,c.js'); 161 | }); 162 | 163 | it('should forwarding url with query string', () => { 164 | window.xproxyConfig = { 165 | id: 'ioahsfioh', 166 | proxyList: [ 167 | { 168 | title: 'test0', 169 | url: 'https://g.alicdn.com?t=1', 170 | redirectUrl: 'https://g.alicdn.com?t=2' 171 | } 172 | ] 173 | }; 174 | expect( 175 | redirectToMatchingRule({ 176 | url: 'https://g.alicdn.com?t=1', 177 | requestId: 1 178 | }).redirectUrl 179 | ).to.be.equal('https://g.alicdn.com?t=2'); 180 | expect( 181 | redirectToMatchingRule({ 182 | url: 'https://g.alicdn.com?t=1&k=2', 183 | requestId: 2 184 | }).redirectUrl 185 | ).to.be.equal('https://g.alicdn.com?t=2&k=2'); 186 | expect( 187 | redirectToMatchingRule({ 188 | url: 'https://g.alicdn.com?t=1/??a.js,b.js,c.js', 189 | requestId: 3 190 | }).redirectUrl 191 | ).to.be.equal('https://g.alicdn.com?t=2/??a.js,b.js,c.js'); 192 | expect( 193 | redirectToMatchingRule({ 194 | url: 'https://g.alicdn.com#aaaa', 195 | requestId: 1 196 | }) 197 | ).to.deep.equal({}); 198 | }); 199 | 200 | it('should forwarding url with ?? ', () => { 201 | window.xproxyConfig = { 202 | id: 'ioahsfioh', 203 | proxyList: [ 204 | { 205 | title: 'test0', 206 | url: 'https://a.com/??a.js,b.js', 207 | redirectUrl: 'https://b.com/??a.js,b.js' 208 | } 209 | ] 210 | }; 211 | expect( 212 | redirectToMatchingRule({ 213 | url: 'https://a.com/??a.js,b.js', 214 | requestId: 1 215 | }).redirectUrl 216 | ).to.be.equal('https://b.com/??a.js,b.js'); 217 | expect( 218 | redirectToMatchingRule({ 219 | url: 'https://g.alicdn.com/#aaaa', 220 | requestId: 2 221 | }) 222 | ).to.deep.equal({}); 223 | expect( 224 | redirectToMatchingRule({ 225 | url: 'https://a.com/??a.js,b.js?t=1#aaa', 226 | requestId: 3 227 | }).redirectUrl 228 | ).to.be.equal('https://b.com/??a.js,b.js?t=1#aaa'); 229 | }); 230 | 231 | }); 232 | 233 | describe('reg urls which should forward', () => { 234 | 235 | beforeEach(function () { 236 | // 在本区块的每个测试用例之前执行 237 | window.xproxyConfig = {}; 238 | window.lastRequestId = null; 239 | window.urls = new Array(200); 240 | }); 241 | 242 | it('should forward reg url without query string', () => { 243 | window.xproxyConfig = { 244 | id: 'ioahsfioh', 245 | proxyList: [ 246 | { 247 | title: 'test0', 248 | url: 'g.(\\w+).com', 249 | redirectUrl: 'g.alicdn.com?t=2' 250 | } 251 | ] 252 | }; 253 | expect( 254 | redirectToMatchingRule({ 255 | url: 'https://g1.alicdn.com', 256 | requestId: 1 257 | }) 258 | ).to.deep.equal({}); 259 | expect( 260 | redirectToMatchingRule({ 261 | url: 'https://g.alicdn.com', 262 | requestId: 2 263 | }).redirectUrl 264 | ).to.be.equal('https://g.alicdn.com?t=2'); 265 | expect( 266 | redirectToMatchingRule({ 267 | url: 'https://g.alicdn.com#aaaa', 268 | requestId: 3 269 | }).redirectUrl 270 | ).to.be.equal('https://g.alicdn.com?t=2#aaaa'); 271 | expect( 272 | redirectToMatchingRule({ 273 | url: 'https://g.alicdn.com/??a.js,b.js,c.js', 274 | requestId: 4 275 | }).redirectUrl 276 | ).to.be.equal('https://g.alicdn.com?t=2/??a.js,b.js,c.js'); 277 | }); 278 | 279 | it('should forward reg url with query string', () => { 280 | window.xproxyConfig = { 281 | id: 'ioahsfioh', 282 | proxyList: [ 283 | { 284 | title: 'test0', 285 | url: '(.*)g.(.*).com\\?t=1', 286 | redirectUrl: '$1g.alicdn.com?t=2' 287 | } 288 | ] 289 | }; 290 | expect( 291 | redirectToMatchingRule({ 292 | url: 'http://g.alicdn.com?t=1&k=2', 293 | requestId: 1 294 | }).redirectUrl 295 | ).to.be.equal('http://g.alicdn.com?t=2&k=2'); 296 | expect( 297 | redirectToMatchingRule({ 298 | url: 'https://g.alicdn.com?t=1&k=2', 299 | requestId: 2 300 | }).redirectUrl 301 | ).to.be.equal('https://g.alicdn.com?t=2&k=2'); 302 | expect( 303 | redirectToMatchingRule({ 304 | url: 'https://g.alicdn.com#aaaa', 305 | requestId: 3 306 | }) 307 | ).to.deep.equal({}); 308 | expect( 309 | redirectToMatchingRule({ 310 | url: 'https://g.alicdn.com?t=1#aaaa', 311 | requestId: 4 312 | }).redirectUrl 313 | ).to.be.equal('https://g.alicdn.com?t=2#aaaa'); 314 | }); 315 | 316 | it('should forwarding reg url with ??', () => { 317 | window.xproxyConfig = { 318 | id: 'ioahsfioh', 319 | proxyList: [ 320 | { 321 | title: 'test0', 322 | url: '(.*)g.alicdn.com/??(.*)', 323 | redirectUrl: '$1aliyun.alicdn.com/??$2' 324 | } 325 | ] 326 | }; 327 | expect( 328 | redirectToMatchingRule({ 329 | url: 'https://g.alicdn.com/??a.js,b.js?t=1', 330 | requestId: 1 331 | }).redirectUrl 332 | ).to.be.equal('https://aliyun.alicdn.com/??a.js,b.js?t=1'); 333 | expect( 334 | redirectToMatchingRule({ 335 | url: 'https://g.alicdn.com/#aaaa', 336 | requestId: 2 337 | }), 338 | ).to.deep.equal({}); 339 | expect( 340 | redirectToMatchingRule({ 341 | url: 'https://g.alicdn.com/??a.js,b.js?t=1#aaa', 342 | requestId: 3 343 | }).redirectUrl 344 | ).to.be.equal('https://aliyun.alicdn.com/??a.js,b.js?t=1#aaa'); 345 | }); 346 | 347 | }); 348 | 349 | 350 | describe('combined rules', () => { 351 | it('should support combined rules', () => { 352 | window.xproxyConfig = { 353 | id: 'ioahsfioh', 354 | proxyList: [ 355 | { 356 | title: 'test0', 357 | url: '//g.alicdn.com/platform/daily-test/(.*).js$', 358 | redirectUrl: '//g.alicdn.com/platform/daily-test/$1.json' 359 | }, 360 | { 361 | title: 'test0', 362 | url: 'g.alicdn.com', 363 | redirectUrl: 'aliyun.alicdn.com' 364 | } 365 | ] 366 | }; 367 | expect( 368 | redirectToMatchingRule({ 369 | url: 'https://g.alicdn.com/platform/daily-test/isDaily.js', 370 | requestId: 1 371 | }).redirectUrl, 372 | ).to.be.equal('https://aliyun.alicdn.com/platform/daily-test/isDaily.json'); 373 | }); 374 | }); 375 | -------------------------------------------------------------------------------- /src/lib/react-dom.js: -------------------------------------------------------------------------------- 1 | /** @license React v16.3.2 2 | * react-dom.production.min.js 3 | * 4 | * Copyright (c) 2013-present, Facebook, Inc. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | /* 10 | Modernizr 3.0.0pre (Custom Build) | MIT 11 | */ 12 | 'use strict';(function(pa,l){"object"===typeof exports&&"undefined"!==typeof module?module.exports=l(require("react")):"function"===typeof define&&define.amd?define(["react"],l):pa.ReactDOM=l(pa.React)})(this,function(pa){function l(a){for(var b=arguments.length-1,c="http://reactjs.org/docs/error-decoder.html?invariant\x3d"+a,d=0;dthis.eventPool.length&&this.eventPool.push(a)}function Sc(a){a.eventPool= 22 | [];a.getPooled=Fe;a.release=Ge}function Tc(a,b){switch(a){case "topKeyUp":return-1!==He.indexOf(b.keyCode);case "topKeyDown":return 229!==b.keyCode;case "topKeyPress":case "topMouseDown":case "topBlur":return!0;default:return!1}}function Uc(a){a=a.detail;return"object"===typeof a&&"data"in a?a.data:null}function Ie(a,b){switch(a){case "topCompositionEnd":return Uc(b);case "topKeyPress":if(32!==b.which)return null;Vc=!0;return Wc;case "topTextInput":return a=b.data,a===Wc&&Vc?null:a;default:return null}} 23 | function Je(a,b){if(ia)return"topCompositionEnd"===a||!Mb&&Tc(a,b)?(a=Qc(),H._root=null,H._startText=null,H._fallbackText=null,ia=!1,a):null;switch(a){case "topPaste":return null;case "topKeyPress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1b}return!1}function J(a,b,c,d,e){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b}function Rb(a,b,c,d){var e=F.hasOwnProperty(b)?F[b]:null;var f=null!==e?0===e.type:d?!1:!(2jb.length&&jb.push(a)}}}function kb(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;c["ms"+a]="MS"+b;c["O"+a]="o"+b.toLowerCase();return c}function lb(a){if(Zb[a])return Zb[a];if(!T[a])return a;var b=T[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Ed)return Zb[a]=b[c];return a}function Fd(a){Object.prototype.hasOwnProperty.call(a,mb)||(a[mb]=af++,Gd[a[mb]]={});return Gd[a[mb]]}function Hd(a,b){return a&&b?a===b?!0:Id(a)?!1:Id(b)?Hd(a,b.parentNode): 42 | "contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function Jd(a){for(;a&&a.firstChild;)a=a.firstChild;return a}function Kd(a,b){var c=Jd(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;if(a<=b&&d>=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Jd(c)}}function $b(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&"text"===a.type||"textarea"===b||"true"=== 43 | a.contentEditable)}function Ld(a,b){if(ac||null==ka||ka!==bc())return null;var c=ka;"selectionStart"in c&&$b(c)?c={start:c.selectionStart,end:c.selectionEnd}:window.getSelection?(c=window.getSelection(),c={anchorNode:c.anchorNode,anchorOffset:c.anchorOffset,focusNode:c.focusNode,focusOffset:c.focusOffset}):c=void 0;return Na&&cc(Na,c)?null:(Na=c,a=I.getPooled(Md.select,dc,a,b),a.type="select",a.target=ka,ya(a),a)}function sa(a,b,c,d){this.tag=a;this.key=c;this.stateNode=this.type=null;this.sibling= 44 | this.child=this["return"]=null;this.index=0;this.ref=null;this.pendingProps=b;this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.effectTag=0;this.lastEffect=this.firstEffect=this.nextEffect=null;this.expirationTime=0;this.alternate=null}function nb(a,b,c){var d=a.alternate;null===d?(d=new sa(a.tag,b,a.key,a.mode),d.type=a.type,d.stateNode=a.stateNode,d.alternate=a,a.alternate=d):(d.pendingProps=b,d.effectTag=0,d.nextEffect=null,d.firstEffect=null,d.lastEffect=null);d.expirationTime= 45 | c;d.child=a.child;d.memoizedProps=a.memoizedProps;d.memoizedState=a.memoizedState;d.updateQueue=a.updateQueue;d.sibling=a.sibling;d.index=a.index;d.ref=a.ref;return d}function ec(a,b,c){var d=a.type,e=a.key;a=a.props;var f=void 0;if("function"===typeof d)f=d.prototype&&d.prototype.isReactComponent?2:0;else if("string"===typeof d)f=5;else switch(d){case Y:return ob(a.children,b,c,e);case bf:f=11;b|=3;break;case cf:f=11;b|=2;break;case jd:f=7;break;case kd:f=9;break;default:if("object"===typeof d&& 46 | null!==d)switch(d.$$typeof){case df:f=13;break;case ef:f=12;break;case ld:f=14;break;default:if("number"===typeof d.tag)return b=d,b.pendingProps=a,b.expirationTime=c,b;l("130",null==d?d:typeof d,"")}else l("130",null==d?d:typeof d,"")}b=new sa(f,a,e,b);b.type=d;b.expirationTime=c;return b}function ob(a,b,c,d){a=new sa(10,a,d,b);a.expirationTime=c;return a}function fc(a,b,c){a=new sa(6,a,null,b);a.expirationTime=c;return a}function gc(a,b,c){b=new sa(4,null!==a.children?a.children:[],a.key,b);b.expirationTime= 47 | c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}function Nd(a){return function(b){try{return a(b)}catch(c){}}}function ff(a){if("undefined"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var b=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(b.isDisabled||!b.supportsFiber)return!0;try{var c=b.inject(a);hc=Nd(function(a){return b.onCommitFiberRoot(c,a)});ic=Nd(function(a){return b.onCommitFiberUnmount(c,a)})}catch(d){}return!0}function Od(a){"function"=== 48 | typeof hc&&hc(a)}function Pd(a){"function"===typeof ic&&ic(a)}function Qd(a){return{baseState:a,expirationTime:0,first:null,last:null,callbackList:null,hasForceUpdate:!1,isInitialized:!1,capturedValues:null}}function pb(a,b){null===a.last?a.first=a.last=b:(a.last.next=b,a.last=b);if(0===a.expirationTime||a.expirationTime>b.expirationTime)a.expirationTime=b.expirationTime}function jc(a){kc=lc=null;var b=a.alternate,c=a.updateQueue;null===c&&(c=a.updateQueue=Qd(null));null!==b?(a=b.updateQueue,null=== 49 | a&&(a=b.updateQueue=Qd(null))):a=null;kc=c;lc=a!==c?a:null}function Oa(a,b){jc(a);a=kc;var c=lc;null===c?pb(a,b):null===a.last||null===c.last?(pb(a,b),pb(c,b)):(pb(a,b),c.last=b)}function Rd(a,b,c,d){a=a.partialState;return"function"===typeof a?a.call(b,c,d):a}function qb(a,b,c,d,e,f){null!==a&&a.updateQueue===c&&(c=b.updateQueue={baseState:c.baseState,expirationTime:c.expirationTime,first:c.first,last:c.last,isInitialized:c.isInitialized,capturedValues:c.capturedValues,callbackList:null,hasForceUpdate:!1}); 50 | c.expirationTime=0;c.isInitialized?a=c.baseState:(a=c.baseState=b.memoizedState,c.isInitialized=!0);for(var g=!0,h=c.first,k=!1;null!==h;){var l=h.expirationTime;if(l>f){var m=c.expirationTime;if(0===m||m>l)c.expirationTime=l;k||(k=!0,c.baseState=a)}else{k||(c.first=h.next,null===c.first&&(c.last=null));if(h.isReplace)a=Rd(h,d,a,e),g=!0;else if(l=Rd(h,d,a,e))a=g?A({},a,l):A(a,l),g=!1;h.isForced&&(c.hasForceUpdate=!0);null!==h.callback&&(l=c.callbackList,null===l&&(l=c.callbackList=[]),l.push(h)); 51 | null!==h.capturedValue&&(l=c.capturedValues,null===l?c.capturedValues=[h.capturedValue]:l.push(h.capturedValue))}h=h.next}null!==c.callbackList?b.effectTag|=32:null!==c.first||c.hasForceUpdate||null!==c.capturedValues||(b.updateQueue=null);k||(c.baseState=a);return a}function Sd(a,b){var c=a.callbackList;if(null!==c)for(a.callbackList=null,a=0;ar?(q=t,t=null):q=t.sibling;var n=p(e,t,h[r],C);if(null===n){null===t&&(t=q);break}a&& 58 | t&&null===n.alternate&&b(e,t);m=f(n,m,r);null===g?x=n:g.sibling=n;g=n;t=q}if(r===h.length)return c(e,t),x;if(null===t){for(;rr?(q=t,t=null):q=t.sibling;var k=p(e,t,n.value,C);if(null===k){t||(t=q);break}a&&t&&null===k.alternate&&b(e,t);m=f(k,m,r);null===x?g=k:x.sibling=k;x=k;t=q}if(n.done)return c(e,t),g;if(null===t){for(;!n.done;r++,n=h.next())n=w(e,n.value,C),null!==n&&(m=f(n,m,r),null===x?g=n:x.sibling=n,x=n);return g}for(t=d(e,t);!n.done;r++,n=h.next())if(n=G(t,e,r,n.value,C),null!==n){if(a&&null!==n.alternate)t["delete"](null=== 60 | n.key?r:n.key);m=f(n,m,r);null===x?g=n:x.sibling=n;x=n}a&&t.forEach(function(a){return b(e,a)});return g}return function(a,d,f,m){"object"===typeof f&&null!==f&&f.type===Y&&null===f.key&&(f=f.props.children);var h="object"===typeof f&&null!==f;if(h)switch(f.$$typeof){case sb:a:{var x=f.key;for(h=d;null!==h;){if(h.key===x)if(10===h.tag?f.type===Y:h.type===f.type){c(a,h.sibling);d=e(h,f.type===Y?f.props.children:f.props,m);d.ref=Pa(a,h,f);d["return"]=a;a=d;break a}else{c(a,h);break}else b(a,h);h=h.sibling}f.type=== 61 | Y?(d=ob(f.props.children,a.mode,m,f.key),d["return"]=a,a=d):(m=ec(f,a.mode,m),m.ref=Pa(a,d,f),m["return"]=a,a=m)}return g(a);case ja:a:{for(h=f.key;null!==d;){if(d.key===h)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[],m);d["return"]=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=gc(f,a.mode,m);d["return"]=a;a=d}return g(a)}if("string"===typeof f||"number"===typeof f)return f=""+f,null!==d&&6=== 62 | d.tag?(c(a,d.sibling),d=e(d,f,m),d["return"]=a,a=d):(c(a,d),d=fc(f,a.mode,m),d["return"]=a,a=d),g(a);if(tb(f))return v(a,d,f,m);if(Da(f))return C(a,d,f,m);h&&rb(a,f);if("undefined"===typeof f)switch(a.tag){case 2:case 1:m=a.type,l("152",m.displayName||m.name||"Component")}return c(a,d)}}function Ud(a,b){var c=b.source;null===b.stack&&Qb(c);null!==c&&Ia(c);b=b.value;null!==a&&2===a.tag&&Ia(a);try{b&&b.suppressReactErrorLogging||console.error(b)}catch(d){d&&d.suppressReactErrorLogging||console.error(d)}} 63 | function hf(a,b,c){var d=3=b.length?void 0:l("93"),b=b[0]),c=""+b),null==c&&(c=""));a._wrapperState={initialValue:""+c}}function Xd(a,b){var c=b.value;null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&(a.defaultValue=c));null!=b.defaultValue&&(a.defaultValue=b.defaultValue)}function Yd(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML"; 66 | default:return"http://www.w3.org/1999/xhtml"}}function oc(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?Yd(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}function Zd(a,b,c){a=a.style;for(var d in b)if(b.hasOwnProperty(d)){c=0===d.indexOf("--");var e=d;var f=b[d];e=null==f||"boolean"===typeof f||""===f?"":c||"number"!==typeof f||0===f||Qa.hasOwnProperty(e)&&Qa[e]?(""+f).trim():f+"px";"float"===d&&(d="cssFloat");c?a.setProperty(d,e):a[d]=e}}function pc(a, 67 | b,c){b&&(kf[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML?l("137",a,c()):void 0),null!=b.dangerouslySetInnerHTML&&(null!=b.children?l("60"):void 0,"object"===typeof b.dangerouslySetInnerHTML&&"__html"in b.dangerouslySetInnerHTML?void 0:l("61")),null!=b.style&&"object"!==typeof b.style?l("62",c()):void 0)}function qc(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1; 68 | default:return!0}}function U(a,b){a=9===a.nodeType||11===a.nodeType?a:a.ownerDocument;var c=Fd(a);b=cb[b];for(var d=0;d=Ta),Wc=String.fromCharCode(32),ca={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd", 91 | "topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"topBlur topCompositionEnd topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"topBlur topCompositionStart topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate", 92 | captured:"onCompositionUpdateCapture"},dependencies:"topBlur topCompositionUpdate topKeyDown topKeyPress topKeyUp topMouseDown".split(" ")}},Vc=!1,ia=!1,vf={eventTypes:ca,extractEvents:function(a,b,c,d){var e=void 0;var f=void 0;if(Mb)b:{switch(a){case "topCompositionStart":e=ca.compositionStart;break b;case "topCompositionEnd":e=ca.compositionEnd;break b;case "topCompositionUpdate":e=ca.compositionUpdate;break b}e=void 0}else ia?Tc(a,c)&&(e=ca.compositionEnd):"topKeyDown"===a&&229===c.keyCode&&(e= 93 | ca.compositionStart);e?(Xc&&(ia||e!==ca.compositionStart?e===ca.compositionEnd&&ia&&(f=Qc()):(H._root=d,H._startText=Rc(),ia=!0)),e=sf.getPooled(e,b,c,d),f?e.data=f:(f=Uc(c),null!==f&&(e.data=f)),ya(e),f=e):f=null;(a=uf?Ie(a,c):Je(a,c))?(b=tf.getPooled(ca.beforeInput,b,c,d),b.data=a,ya(b)):b=null;return null===f?b:null===b?f:[f,b]}},eb=null,za=null,ra=null,oe={injectFiberControlledHostComponent:function(a){eb=a}},wf=Object.freeze({injection:oe,enqueueStateRestore:$c,needsStateRestore:ad,restoreStateIfNeeded:bd}), 94 | dd=function(a,b){return a(b)},Dd=function(a,b,c){return a(b,c)},ed=function(){},Nb=!1,Ke={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0},tc=pa.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,V="function"===typeof Symbol&&Symbol["for"],sb=V?Symbol["for"]("react.element"):60103,jd=V?Symbol["for"]("react.call"):60104,kd=V?Symbol["for"]("react.return"):60105,ja=V?Symbol["for"]("react.portal"): 95 | 60106,Y=V?Symbol["for"]("react.fragment"):60107,cf=V?Symbol["for"]("react.strict_mode"):60108,df=V?Symbol["for"]("react.provider"):60109,ef=V?Symbol["for"]("react.context"):60110,bf=V?Symbol["for"]("react.async_mode"):60111,ld=V?Symbol["for"]("react.forward_ref"):60112,id="function"===typeof Symbol&&Symbol.iterator,Ne=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/, 96 | nd={},md={},F={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){F[a]=new J(a,0,!1,a,null)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];F[b]=new J(b,1,!1,a[1],null)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){F[a]=new J(a,2,!1,a.toLowerCase(),null)});["autoReverse", 97 | "externalResourcesRequired","preserveAlpha"].forEach(function(a){F[a]=new J(a,2,!1,a,null)});"allowFullScreen async autoFocus autoPlay controls default defer disabled formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){F[a]=new J(a,3,!1,a.toLowerCase(),null)});["checked","multiple","muted","selected"].forEach(function(a){F[a]=new J(a,3,!0,a.toLowerCase(),null)});["capture","download"].forEach(function(a){F[a]= 98 | new J(a,4,!1,a.toLowerCase(),null)});["cols","rows","size","span"].forEach(function(a){F[a]=new J(a,6,!1,a.toLowerCase(),null)});["rowSpan","start"].forEach(function(a){F[a]=new J(a,5,!1,a.toLowerCase(),null)});var uc=/[\-:]([a-z])/g,vc=function(a){return a[1].toUpperCase()};"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b= 99 | a.replace(uc,vc);F[b]=new J(b,1,!1,a,null)});"xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(uc,vc);F[b]=new J(b,1,!1,a,"http://www.w3.org/1999/xlink")});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(uc,vc);F[b]=new J(b,1,!1,a,"http://www.w3.org/XML/1998/namespace")});F.tabIndex=new J("tabIndex",1,!1,"tabindex",null);var sd={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"}, 100 | dependencies:"topBlur topChange topClick topFocus topInput topKeyDown topKeyUp topSelectionChange".split(" ")}},Ja=null,Ka=null,wc=!1;R.canUseDOM&&(wc=Pb("input")&&(!document.documentMode||9=document.documentMode,Md={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"topBlur topContextMenu topFocus topKeyDown topKeyUp topMouseDown topMouseUp topSelectionChange".split(" ")}},ka=null,dc=null,Na=null,ac=!1,Mf={eventTypes:Md,extractEvents:function(a,b,c,d){var e=d.window===d?d.document:9===d.nodeType?d:d.ownerDocument,f;if(!(f= 117 | !e)){a:{e=Fd(e);f=cb.onSelect;for(var g=0;gd)f.expirationTime=d,null!==m&&(0===m.expirationTime||m.expirationTime>d)&&(m.expirationTime=d);else if(null!==m&&(0===m.expirationTime||m.expirationTime>d))m.expirationTime=d;else break;f=f["return"]}f= 131 | null}else f=e.child;break;case 13:f=e.type===a.type?null:e.child;break;default:f=e.child}if(null!==f)f["return"]=e;else for(f=e;null!==f;){if(f===a){f=null;break}e=f.sibling;if(null!==e){f=e;break}f=f["return"]}e=f}}function G(a,b,c){var d=b.type._context,e=b.pendingProps,f=b.memoizedProps;if(!Aa()&&f===e)return b.stateNode=0,z(b),v(a,b);var m=e.value;b.memoizedProps=e;if(null===f)m=1073741823;else if(f.value===e.value){if(f.children===e.children)return b.stateNode=0,z(b),v(a,b);m=0}else{var g=f.value; 132 | if(g===m&&(0!==g||1/g===1/m)||g!==g&&m!==m){if(f.children===e.children)return b.stateNode=0,z(b),v(a,b);m=0}else if(m="function"===typeof d._calculateChangedBits?d._calculateChangedBits(g,m):1073741823,m|=0,0===m){if(f.children===e.children)return b.stateNode=0,z(b),v(a,b)}else p(b,d,m,c)}b.stateNode=m;z(b);h(a,b,e.children);return b.child}function v(a,b){null!==a&&b.child!==a.child?l("153"):void 0;if(null!==b.child){a=b.child;var c=nb(a,a.pendingProps,a.expirationTime);b.child=c;for(c["return"]= 133 | b;null!==a.sibling;)a=a.sibling,c=c.sibling=nb(a,a.pendingProps,a.expirationTime),c["return"]=b;c.sibling=null}return b.child}var C=a.shouldSetTextContent,x=a.shouldDeprioritizeSubtree,t=b.pushHostContext,y=b.pushHostContainer,z=d.pushProvider,B=c.getMaskedContext,F=c.getUnmaskedContext,Aa=c.hasContextChanged,r=c.pushContextProvider,q=c.pushTopLevelContextObject,n=c.invalidateContextProvider,gf=e.enterHydrationState,E=e.resetHydrationState,qe=e.tryToClaimNextHydratableInstance;a=Nf(c,f,g,function(a, 134 | b){a.memoizedProps=b},function(a,b){a.memoizedState=b});var Of=a.adoptClassInstance,Pf=a.callGetDerivedStateFromProps,H=a.constructClassInstance,re=a.mountClassInstance,I=a.resumeMountClassInstance,J=a.updateClassInstance;return{beginWork:function(a,b,c){if(0===b.expirationTime||b.expirationTime>c){switch(b.tag){case 3:w(b);break;case 2:r(b);break;case 4:y(b,b.stateNode.containerInfo);break;case 13:z(b)}return null}switch(b.tag){case 0:null!==a?l("155"):void 0;var d=b.type,e=b.pendingProps,f=F(b); 135 | f=B(b,f);d=d(e,f);b.effectTag|=1;"object"===typeof d&&null!==d&&"function"===typeof d.render&&void 0===d.$$typeof?(f=b.type,b.tag=2,b.memoizedState=null!==d.state&&void 0!==d.state?d.state:null,"function"===typeof f.getDerivedStateFromProps&&(e=Pf(b,d,e,b.memoizedState),null!==e&&void 0!==e&&(b.memoizedState=A({},b.memoizedState,e))),e=r(b),Of(b,d),re(b,c),a=m(a,b,!0,e,!1,c)):(b.tag=1,h(a,b,d),b.memoizedProps=e,a=b.child);return a;case 1:return e=b.type,c=b.pendingProps,Aa()||b.memoizedProps!==c? 136 | (d=F(b),d=B(b,d),e=e(c,d),b.effectTag|=1,h(a,b,e),b.memoizedProps=c,a=b.child):a=v(a,b),a;case 2:e=r(b);null===a?null===b.stateNode?(H(b,b.pendingProps),re(b,c),d=!0):d=I(b,c):d=J(a,b,c);f=!1;var g=b.updateQueue;null!==g&&null!==g.capturedValues&&(f=d=!0);return m(a,b,d,e,f,c);case 3:a:if(w(b),d=b.updateQueue,null!==d){f=b.memoizedState;e=qb(a,b,d,null,null,c);b.memoizedState=e;d=b.updateQueue;if(null!==d&&null!==d.capturedValues)d=null;else if(f===e){E();a=v(a,b);break a}else d=e.element;f=b.stateNode; 137 | (null===a||null===a.child)&&f.hydrate&&gf(b)?(b.effectTag|=2,b.child=yc(b,null,d,c)):(E(),h(a,b,d));b.memoizedState=e;a=b.child}else E(),a=v(a,b);return a;case 5:a:{t(b);null===a&&qe(b);e=b.type;g=b.memoizedProps;d=b.pendingProps;f=null!==a?a.memoizedProps:null;if(!Aa()&&g===d){if(g=b.mode&1&&x(e,d))b.expirationTime=1073741823;if(!g||1073741823!==c){a=v(a,b);break a}}g=d.children;C(e,d)?g=null:f&&C(e,f)&&(b.effectTag|=16);D(a,b);1073741823!==c&&b.mode&1&&x(e,d)?(b.expirationTime=1073741823,b.memoizedProps= 138 | d,a=null):(h(a,b,g),b.memoizedProps=d,a=b.child)}return a;case 6:return null===a&&qe(b),b.memoizedProps=b.pendingProps,null;case 8:b.tag=7;case 7:return e=b.pendingProps,Aa()||b.memoizedProps!==e||(e=b.memoizedProps),d=e.children,b.stateNode=null===a?yc(b,b.stateNode,d,c):xb(b,a.stateNode,d,c),b.memoizedProps=e,b.stateNode;case 9:return null;case 4:return y(b,b.stateNode.containerInfo),e=b.pendingProps,Aa()||b.memoizedProps!==e?(null===a?b.child=xb(b,null,e,c):h(a,b,e),b.memoizedProps=e,a=b.child): 139 | a=v(a,b),a;case 14:return c=b.type.render,c=c(b.pendingProps,b.ref),h(a,b,c),b.memoizedProps=c,b.child;case 10:return c=b.pendingProps,Aa()||b.memoizedProps!==c?(h(a,b,c),b.memoizedProps=c,a=b.child):a=v(a,b),a;case 11:return c=b.pendingProps.children,Aa()||null!==c&&b.memoizedProps!==c?(h(a,b,c),b.memoizedProps=c,a=b.child):a=v(a,b),a;case 13:return G(a,b,c);case 12:a:{d=b.type;f=b.pendingProps;g=b.memoizedProps;e=d._currentValue;var n=d._changedBits;if(Aa()||0!==n||g!==f){b.memoizedProps=f;var q= 140 | f.unstable_observedBits;if(void 0===q||null===q)q=1073741823;b.stateNode=q;if(0!==(n&q))p(b,d,n,c);else if(g===f){a=v(a,b);break a}c=f.children;c=c(e);h(a,b,c);a=b.child}else a=v(a,b)}return a;default:l("156")}}}},Rf=function(a,b,c,d,e){function f(a){a.effectTag|=4}var g=a.createInstance,h=a.createTextInstance,k=a.appendInitialChild,D=a.finalizeInitialChildren,m=a.prepareUpdate,w=a.persistence,p=b.getRootHostContainer,G=b.popHostContext,v=b.getHostContext,C=b.popHostContainer,x=c.popContextProvider, 141 | t=c.popTopLevelContextObject,y=d.popProvider,z=e.prepareToHydrateHostInstance,B=e.prepareToHydrateHostTextInstance,A=e.popHydrationState,F=void 0,r=void 0,q=void 0;a.mutation?(F=function(a){},r=function(a,b,c,d,e,m,g,h){(b.updateQueue=c)&&f(b)},q=function(a,b,c,d){c!==d&&f(b)}):w?l("235"):l("236");return{completeWork:function(a,b,c){var d=b.pendingProps;switch(b.tag){case 1:return null;case 2:return x(b),a=b.stateNode,d=b.updateQueue,null!==d&&null!==d.capturedValues&&(b.effectTag&=-65,"function"=== 142 | typeof a.componentDidCatch?b.effectTag|=256:d.capturedValues=null),null;case 3:C(b);t(b);d=b.stateNode;d.pendingContext&&(d.context=d.pendingContext,d.pendingContext=null);if(null===a||null===a.child)A(b),b.effectTag&=-3;F(b);a=b.updateQueue;null!==a&&null!==a.capturedValues&&(b.effectTag|=256);return null;case 5:G(b);c=p();var e=b.type;if(null!==a&&null!=b.stateNode){var n=a.memoizedProps,w=b.stateNode,E=v();w=m(w,e,n,d,c,E);r(a,b,w,e,n,d,c,E);a.ref!==b.ref&&(b.effectTag|=128)}else{if(!d)return null=== 143 | b.stateNode?l("166"):void 0,null;a=v();if(A(b))z(b,c,a)&&f(b);else{n=g(e,d,c,a,b);a:for(E=b.child;null!==E;){if(5===E.tag||6===E.tag)k(n,E.stateNode);else if(4!==E.tag&&null!==E.child){E.child["return"]=E;E=E.child;continue}if(E===b)break;for(;null===E.sibling;){if(null===E["return"]||E["return"]===b)break a;E=E["return"]}E.sibling["return"]=E["return"];E=E.sibling}D(n,e,d,c,a)&&f(b);b.stateNode=n}null!==b.ref&&(b.effectTag|=128)}return null;case 6:if(a&&null!=b.stateNode)q(a,b,a.memoizedProps,d); 144 | else{if("string"!==typeof d)return null===b.stateNode?l("166"):void 0,null;a=p();c=v();A(b)?B(b)&&f(b):b.stateNode=h(d,a,c,b)}return null;case 7:(d=b.memoizedProps)?void 0:l("165");b.tag=8;e=[];a:for((n=b.stateNode)&&(n["return"]=b);null!==n;){if(5===n.tag||6===n.tag||4===n.tag)l("247");else if(9===n.tag)e.push(n.pendingProps.value);else if(null!==n.child){n.child["return"]=n;n=n.child;continue}for(;null===n.sibling;){if(null===n["return"]||n["return"]===b)break a;n=n["return"]}n.sibling["return"]= 145 | n["return"];n=n.sibling}n=d.handler;d=n(d.props,e);b.child=xb(b,null!==a?a.child:null,d,c);return b.child;case 8:return b.tag=7,null;case 9:return null;case 14:return null;case 10:return null;case 11:return null;case 4:return C(b),F(b),null;case 13:return y(b),null;case 12:return null;case 0:l("167");default:l("156")}}}},Sf=function(a,b,c,d,e){var f=a.popHostContainer,g=a.popHostContext,h=b.popContextProvider,k=b.popTopLevelContextObject,l=c.popProvider;return{throwException:function(a,b,c){b.effectTag|= 146 | 512;b.firstEffect=b.lastEffect=null;b={value:c,source:b,stack:Qb(b)};do{switch(a.tag){case 3:jc(a);a.updateQueue.capturedValues=[b];a.effectTag|=1024;return;case 2:if(c=a.stateNode,0===(a.effectTag&64)&&null!==c&&"function"===typeof c.componentDidCatch&&!e(c)){jc(a);c=a.updateQueue;var d=c.capturedValues;null===d?c.capturedValues=[b]:d.push(b);a.effectTag|=1024;return}}a=a["return"]}while(null!==a)},unwindWork:function(a){switch(a.tag){case 2:h(a);var b=a.effectTag;return b&1024?(a.effectTag=b&-1025| 147 | 64,a):null;case 3:return f(a),k(a),b=a.effectTag,b&1024?(a.effectTag=b&-1025|64,a):null;case 5:return g(a),null;case 4:return f(a),null;case 13:return l(a),null;default:return null}},unwindInterruptedWork:function(a){switch(a.tag){case 2:h(a);break;case 3:f(a);k(a);break;case 5:g(a);break;case 4:f(a);break;case 13:l(a)}}}},Tf=function(a,b,c,d,e,f){function g(a){var c=a.ref;if(null!==c)if("function"===typeof c)try{c(null)}catch(n){b(a,n)}else c.current=null}function h(a){"function"===typeof Pd&&Pd(a); 148 | switch(a.tag){case 2:g(a);var c=a.stateNode;if("function"===typeof c.componentWillUnmount)try{c.props=a.memoizedProps,c.state=a.memoizedState,c.componentWillUnmount()}catch(n){b(a,n)}break;case 5:g(a);break;case 7:k(a.stateNode);break;case 4:p&&m(a)}}function k(a){for(var b=a;;)if(h(b),null===b.child||p&&4===b.tag){if(b===a)break;for(;null===b.sibling;){if(null===b["return"]||b["return"]===a)return;b=b["return"]}b.sibling["return"]=b["return"];b=b.sibling}else b.child["return"]=b,b=b.child}function D(a){return 5=== 149 | a.tag||3===a.tag||4===a.tag}function m(a){for(var b=a,c=!1,d=void 0,e=void 0;;){if(!c){c=b["return"];a:for(;;){null===c?l("160"):void 0;switch(c.tag){case 5:d=c.stateNode;e=!1;break a;case 3:d=c.stateNode.containerInfo;e=!0;break a;case 4:d=c.stateNode.containerInfo;e=!0;break a}c=c["return"]}c=!0}if(5===b.tag||6===b.tag)k(b),e?F(d,b.stateNode):B(d,b.stateNode);else if(4===b.tag?d=b.stateNode.containerInfo:h(b),null!==b.child){b.child["return"]=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null=== 150 | b["return"]||b["return"]===a)return;b=b["return"];4===b.tag&&(c=!1)}b.sibling["return"]=b["return"];b=b.sibling}}var w=a.getPublicInstance,p=a.mutation;a=a.persistence;p||(a?l("235"):l("236"));var G=p.commitMount,v=p.commitUpdate,C=p.resetTextContent,x=p.commitTextUpdate,t=p.appendChild,y=p.appendChildToContainer,z=p.insertBefore,A=p.insertInContainerBefore,B=p.removeChild,F=p.removeChildFromContainer;return{commitBeforeMutationLifeCycles:function(a,b){switch(b.tag){case 2:if(b.effectTag&2048&&null!== 151 | a){var c=a.memoizedProps,d=a.memoizedState;a=b.stateNode;a.props=b.memoizedProps;a.state=b.memoizedState;b=a.getSnapshotBeforeUpdate(c,d);a.__reactInternalSnapshotBeforeUpdate=b}break;case 3:case 5:case 6:case 4:break;default:l("163")}},commitResetTextContent:function(a){C(a.stateNode)},commitPlacement:function(a){a:{for(var b=a["return"];null!==b;){if(D(b)){var c=b;break a}b=b["return"]}l("160");c=void 0}var d=b=void 0;switch(c.tag){case 5:b=c.stateNode;d=!1;break;case 3:b=c.stateNode.containerInfo; 152 | d=!0;break;case 4:b=c.stateNode.containerInfo;d=!0;break;default:l("161")}c.effectTag&16&&(C(b),c.effectTag&=-17);a:b:for(c=a;;){for(;null===c.sibling;){if(null===c["return"]||D(c["return"])){c=null;break a}c=c["return"]}c.sibling["return"]=c["return"];for(c=c.sibling;5!==c.tag&&6!==c.tag;){if(c.effectTag&2)continue b;if(null===c.child||4===c.tag)continue b;else c.child["return"]=c,c=c.child}if(!(c.effectTag&2)){c=c.stateNode;break a}}for(var e=a;;){if(5===e.tag||6===e.tag)c?d?A(b,e.stateNode,c): 153 | z(b,e.stateNode,c):d?y(b,e.stateNode):t(b,e.stateNode);else if(4!==e.tag&&null!==e.child){e.child["return"]=e;e=e.child;continue}if(e===a)break;for(;null===e.sibling;){if(null===e["return"]||e["return"]===a)return;e=e["return"]}e.sibling["return"]=e["return"];e=e.sibling}},commitDeletion:function(a){m(a);a["return"]=null;a.child=null;a.alternate&&(a.alternate.child=null,a.alternate["return"]=null)},commitWork:function(a,b){switch(b.tag){case 2:break;case 5:var c=b.stateNode;if(null!=c){var d=b.memoizedProps; 154 | a=null!==a?a.memoizedProps:d;var e=b.type,f=b.updateQueue;b.updateQueue=null;null!==f&&v(c,f,e,a,d,b)}break;case 6:null===b.stateNode?l("162"):void 0;c=b.memoizedProps;x(b.stateNode,null!==a?a.memoizedProps:c,c);break;case 3:break;default:l("163")}},commitLifeCycles:function(a,b,c,d,e){switch(c.tag){case 2:a=c.stateNode;c.effectTag&4&&(null===b?(a.props=c.memoizedProps,a.state=c.memoizedState,a.componentDidMount()):(d=b.memoizedProps,b=b.memoizedState,a.props=c.memoizedProps,a.state=c.memoizedState, 155 | a.componentDidUpdate(d,b,a.__reactInternalSnapshotBeforeUpdate)));c=c.updateQueue;null!==c&&Sd(c,a);break;case 3:b=c.updateQueue;if(null!==b){a=null;if(null!==c.child)switch(c.child.tag){case 5:a=w(c.child.stateNode);break;case 2:a=c.child.stateNode}Sd(b,a)}break;case 5:a=c.stateNode;null===b&&c.effectTag&4&&G(a,c.type,c.memoizedProps,c);break;case 6:break;case 4:break;default:l("163")}},commitErrorLogging:function(a,b){switch(a.tag){case 2:var c=a.type;b=a.stateNode;var d=a.updateQueue;null===d|| 156 | null===d.capturedValues?l("264"):void 0;var f=d.capturedValues;d.capturedValues=null;"function"!==typeof c.getDerivedStateFromCatch&&e(b);b.props=a.memoizedProps;b.state=a.memoizedState;for(c=0;cb||(c.current=a[b],a[b]=null,b--)},push:function(c,d,e){b++;a[b]=c.current;c.current=d},checkThatStackIsEmpty:function(){},resetStackAfterFatalErrorInDev:function(){}}},$f=function(a){function b(){if(null!==K)for(var a=K["return"];null!==a;)Q(a),a=a["return"];S=null;na=0;K=null;ka=!1}function c(a){return null!==O&&O.has(a)}function d(a){for(;;){var b=a.alternate,c=a["return"],d=a.sibling;if(0===(a.effectTag&512)){b=J(b,a,na);var e=a;if(1073741823=== 167 | na||1073741823!==e.expirationTime){b:switch(e.tag){case 3:case 2:var f=e.updateQueue;f=null===f?0:f.expirationTime;break b;default:f=0}for(var g=e.child;null!==g;)0!==g.expirationTime&&(0===f||f>g.expirationTime)&&(f=g.expirationTime),g=g.sibling;e.expirationTime=f}if(null!==b)return b;null!==c&&0===(c.effectTag&512)&&(null===c.firstEffect&&(c.firstEffect=a.firstEffect),null!==a.lastEffect&&(null!==c.lastEffect&&(c.lastEffect.nextEffect=a.firstEffect),c.lastEffect=a.lastEffect),1ua)&&(ua=a);return a}function D(a,c){a:{for(;null!==a;){if(0===a.expirationTime|| 171 | a.expirationTime>c)a.expirationTime=c;null!==a.alternate&&(0===a.alternate.expirationTime||a.alternate.expirationTime>c)&&(a.alternate.expirationTime=c);if(null===a["return"])if(3===a.tag){var d=a.stateNode;!ta&&0!==na&&cCa&&l("185")}else{c=void 0;break a}a=a["return"]}c=void 0}return c}function m(){ra=ba()-ia;return za=(ra/10|0)+2}function w(a,b,c,d,e){var f=Ba;Ba=1;try{return a(b,c,d,e)}finally{Ba=f}}function p(a){if(0!==Z){if(a>Z)return;wa(ma)}var b=ba()-ia;Z= 172 | a;ma=va(C,{timeout:10*(a-2)-b})}function y(a,b){if(null===a.nextScheduledRoot)a.remainingExpirationTime=b,null===N?(Ea=N=a,a.nextScheduledRoot=a):(N=N.nextScheduledRoot=a,N.nextScheduledRoot=Ea);else{var c=a.remainingExpirationTime;if(0===c||b=W)&&(!aa|| 174 | m()>=W);)A(oa,W,!aa),v();else for(;null!==oa&&0!==W&&(0===a||a>=W);)A(oa,W,!1),v();null!==X&&(Z=0,ma=-1);0!==W&&p(W);X=null;aa=!1;z()}function z(){ha=0;if(null!==Ga){var a=Ga;Ga=null;for(var b=0;bDa?!1:aa=!0}function H(a){null===oa?l("246"):void 0;oa.remainingExpirationTime=0;Ha||(Ha=!0,ea=a)}var r=Yf(),q=Uf(a,r),n=Wf(r);r=Xf(r);var I=Vf(a),E=Qf(a,q,n,r,I,D,k).beginWork,J=Rf(a,q,n,r,I).completeWork;q=Sf(q,n,r,D,c);var M=q.throwException,P=q.unwindWork,Q=q.unwindInterruptedWork;q=Tf(a,h,D,k,function(a){null===O?O=new Set([a]):O.add(a)},m);var R=q.commitBeforeMutationLifeCycles,V=q.commitResetTextContent,U=q.commitPlacement,ca=q.commitDeletion,Y=q.commitWork,la=q.commitLifeCycles, 179 | pa=q.commitErrorLogging,qa=q.commitAttachRef,sa=q.commitDetachRef,ba=a.now,va=a.scheduleDeferredCallback,wa=a.cancelDeferredCallback,xa=a.prepareForCommit,ya=a.resetAfterCommit,ia=ba(),za=2,ra=ia,ja=0,Ba=0,ta=!1,K=null,S=null,na=0,u=null,T=!1,ka=!1,O=null,Ea=null,N=null,Z=0,ma=-1,da=!1,oa=null,W=0,ua=0,aa=!1,Ha=!1,ea=null,X=null,L=!1,fa=!1,Fa=!1,Ga=null,Ca=1E3,ha=0,Da=1;return{recalculateCurrentTime:m,computeExpirationForFiber:k,scheduleWork:D,requestWork:y,flushRoot:function(a,b){da?l("253"):void 0; 180 | oa=a;W=b;A(a,b,!1);x();z()},batchedUpdates:function(a,b){var c=L;L=!0;try{return a(b)}finally{(L=c)||da||x()}},unbatchedUpdates:function(a,b){if(L&&!fa){fa=!0;try{return a(b)}finally{fa=!1}}return a(b)},flushSync:function(a,b){da?l("187"):void 0;var c=L;L=!0;try{return w(a,b)}finally{L=c,x()}},flushControlled:function(a){var b=L;L=!0;try{w(a)}finally{(L=b)||da||t(1,!1,null)}},deferredUpdates:function(a){var b=Ba;Ba=25*(((m()+500)/25|0)+1);try{return a()}finally{Ba=b}},syncUpdates:w,interactiveUpdates:function(a, 181 | b,c){if(Fa)return a(b,c);L||da||0===ua||(t(ua,!1,null),ua=0);var d=Fa,e=L;L=Fa=!0;try{return a(b,c)}finally{Fa=d,(L=e)||da||x()}},flushInteractiveUpdates:function(){da||0===ua||(t(ua,!1,null),ua=0)},computeUniqueAsyncExpiration:function(){var a=25*(((m()+500)/25|0)+1);a<=ja&&(a=ja+1);return ja=a},legacyContext:n}},se=function(a){function b(a,b,c,d,e,g){d=b.current;if(c){c=c._reactInternalFiber;var m=h(c);c=k(c)?y(c,m):m}else c=la;null===b.context?b.context=c:b.pendingContext=c;b=g;Oa(d,{expirationTime:e, 182 | partialState:{element:a},callback:void 0===b?null:b,isReplace:!1,isForced:!1,capturedValue:null,next:null});f(d,e);return e}var c=a.getPublicInstance;a=$f(a);var d=a.recalculateCurrentTime,e=a.computeExpirationForFiber,f=a.scheduleWork,g=a.legacyContext,h=g.findCurrentUnmaskedContext,k=g.isContextProvider,y=g.processChildContext;return{createContainer:function(a,b,c){b=new sa(3,null,null,b?3:0);a={current:b,containerInfo:a,pendingChildren:null,pendingCommitExpirationTime:0,finishedWork:null,context:null, 183 | pendingContext:null,hydrate:c,remainingExpirationTime:0,firstBatch:null,nextScheduledRoot:null};return b.stateNode=a},updateContainer:function(a,c,f,g){var h=c.current,k=d();h=e(h);return b(a,c,f,k,h,g)},updateContainerAtExpirationTime:function(a,c,e,f,g){var h=d();return b(a,c,e,h,f,g)},flushRoot:a.flushRoot,requestWork:a.requestWork,computeUniqueAsyncExpiration:a.computeUniqueAsyncExpiration,batchedUpdates:a.batchedUpdates,unbatchedUpdates:a.unbatchedUpdates,deferredUpdates:a.deferredUpdates,syncUpdates:a.syncUpdates, 184 | interactiveUpdates:a.interactiveUpdates,flushInteractiveUpdates:a.flushInteractiveUpdates,flushControlled:a.flushControlled,flushSync:a.flushSync,getPublicRootInstance:function(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return c(a.child.stateNode);default:return a.child.stateNode}},findHostInstance:function(a){var b=a._reactInternalFiber;void 0===b&&("function"===typeof a.render?l("188"):l("268",Object.keys(a)));a=yd(b);return null===a?null:a.stateNode},findHostInstanceWithNoPortals:function(a){a= 185 | Ze(a);return null===a?null:a.stateNode},injectIntoDevTools:function(a){var b=a.findFiberByHostInstance;return ff(A({},a,{findHostInstanceByFiber:function(a){a=yd(a);return null===a?null:a.stateNode},findFiberByHostInstance:function(a){return b?b(a):null}}))}}},te=Object.freeze({default:se}),Ac=te&&se||te,ag=Ac["default"]?Ac["default"]:Ac,ue="object"===typeof performance&&"function"===typeof performance.now,yb=void 0;yb=ue?function(){return performance.now()}:function(){return Date.now()};var zb=void 0, 186 | Ab=void 0;if(R.canUseDOM)if("function"!==typeof requestIdleCallback||"function"!==typeof cancelIdleCallback){var Bb=null,Cb=!1,Ya=-1,Za=!1,$a=0,Db=33,ab=33,Eb=void 0;Eb=ue?{didTimeout:!1,timeRemaining:function(){var a=$a-performance.now();return 0=$a- 187 | a)if(-1!==Ya&&Ya<=a)Eb.didTimeout=!0;else{Za||(Za=!0,requestAnimationFrame(we));return}else Eb.didTimeout=!1;Ya=-1;a=Bb;Bb=null;null!==a&&a(Eb)}},!1);var we=function(a){Za=!1;var b=a-$a+ab;bb&&(b=8),ab=bd&&(e=d,d=a,a=e);e=Kd(c,a);var f=Kd(c,d);if(e&&f&&(1!==b.rangeCount||b.anchorNode!==e.node||b.anchorOffset!==e.offset||b.focusNode!==f.node||b.focusOffset!==f.offset)){var g=document.createRange();g.setStart(e.node,e.offset);b.removeAllRanges();a>d?(b.addRange(g),b.extend(f.node,f.offset)):(g.setEnd(f.node,f.offset),b.addRange(g))}}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop}); 201 | c.focus();for(c=0;c