Repository: ckinmind/mobx-share Branch: master Commit: 400a89c8c070 Files: 59 Total size: 252.6 KB Directory structure: gitextract_u3zs106u/ ├── .babelrc ├── .editorconfig ├── .eslintrc ├── .gitignore ├── README.md ├── _template/ │ ├── page-config.js │ └── page-dir/ │ ├── <%component-name%>-store.js │ ├── <%component-name%>.js │ ├── <%component-name%>.styl │ ├── index.js │ └── io.js ├── index.html ├── package.json ├── page-base/ │ ├── base.html │ └── base.js ├── page-config/ │ ├── demo.js │ └── mobx.js ├── postcss.config.js ├── src/ │ ├── common/ │ │ ├── app.styl │ │ └── common.js │ ├── head/ │ │ ├── head.js │ │ └── index.js │ ├── markdown/ │ │ ├── index.js │ │ └── markdown.js │ ├── page-demo/ │ │ ├── demo-store.js │ │ ├── demo.js │ │ ├── demo.styl │ │ ├── index.js │ │ └── io.js │ └── page-mobx/ │ ├── D/ │ │ ├── d1.js │ │ └── d2.js │ ├── Q/ │ │ ├── q1.js │ │ ├── q2.js │ │ ├── q3.js │ │ └── q4.js │ ├── aside.js │ ├── css/ │ │ ├── p7.scss │ │ └── p8.scss │ ├── d3.js │ ├── index.js │ ├── p0.js │ ├── p1.js │ ├── p10.js │ ├── p2.js │ ├── p3.js │ ├── p4.js │ ├── p5.js │ ├── p6.js │ ├── p7.js │ ├── p8.js │ ├── p9.js │ ├── routes.js │ ├── store6.js │ └── style/ │ ├── app.styl │ ├── p0.styl │ ├── p1.styl │ └── p4.styl ├── tool.js └── webpack.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": [ "es2015", "stage-2", "react" ], "plugins": ["transform-decorators-legacy"], "ignore": [ "./src/page-mobx/d3.js" ], "env": { "development": { "presets": [ "react-hmre" ], "plugins": [ "transform-runtime", [ "react-transform", { "transforms": [ { "transform": "react-transform-hmr", "imports": [ "react" ], "locals": [ "module" ] }, { "transform": "react-transform-catch-errors", "imports": [ "react", "redbox-react" ] } ] } ] ] } } } ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false ================================================ FILE: .eslintrc ================================================ { "extends": "airbnb", "parser": "babel-eslint", "env": { "node": true }, "plugins": [ "react" ], "parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }, "rules": { "arrow-parens": [1, "as-needed", { "requireForBlockBody": true }], "indent": ["error", 4], "max-len": [1, 90, 2, {"ignoreComments": true}], "no-unused-vars": [1], "import/no-unresolved": 0, "import/prefer-default-export": [1], "import/extensions": 0, "no-param-reassign": 0, "react/jsx-indent": [1, 4], "react/jsx-indent-props": [1, 4], "react/prefer-stateless-function": [0, {"ignorePureComponents": true}], "react/prop-types": [1], "react/jsx-space-before-closing": ["warn", "always"], "react/jsx-tag-spacing" : [ "warn", { "closingSlash" : "never", "beforeSelfClosing" : "always", "afterOpening" : "never" }], "jsx-a11y/no-static-element-interactions": [1], "react/jsx-closing-bracket-location": [0], "react/forbid-prop-types": [1, {"forbid": ["any"]}], "react/require-default-props": [1], "react/no-array-index-key": [1] }, "globals": { "document": true, "window": true }, "class-methods-use-this": ["warn", { "exceptMethods": [ "render", "componentWillMount", "componentDidMount", "componentWillReceiveProps", "shouldComponentUpdate", "componentWillUpdate", "componentDidUpdate", "componentWillUnmount" ] }], "import/no-extraneous-dependencies": ["error", { "devDependencies": false, "optionalDependencies": false, "peerDependencies": false } ] } ================================================ FILE: .gitignore ================================================ # IntelliJ project files .idea *.iml dist npm-debug.log node_modules .DS_Store jsconfig.json ================================================ FILE: README.md ================================================ # mobx-share ![mobx-share](https://raw.githubusercontent.com/ckinmind/mobx-share/master/src/image/demo.gif) 一个关于mobx的研究和分享演示, 在线访问 [https://ckinmind.github.io/mobx-share](https://ckinmind.github.io/mobx-share) ## 技术栈 - React - Mobx - d3.js - antd ## 项目说明 - 本项目是关于mobx的研究, 以ppt的形式展示mobx的各个api以及会遇到的问题 - 项目中的markdown使用的是 `prismjs` 和 `react-markdown` ## 版本更新 - **[v1.0]**: 初始版本,详细更新查看 [issue 2](https://github.com/ckinmind/mobx-share/issues/2) ## 如何开始 ```js > git clone https://github.com/ckinmind/mobx-share.git > cd mobx-share > npm install > npm start ``` ## 内容说明 ``` - API - mobx - @observable - @action - autorun / when / reaction - @computed - intercept & observe - 工具API: extendObservable, toJS, isObservable - mobx-react - @observer - Observer - Provider / inject - componentWillReact - PropTypes - Observable类型 - object - extendObservable - array - clear/replace/remove方法 - slice/ toJS方法 - arrays更新触发 - maps - 两种定义的差别 - 和ES6map的区别 - 问题 - 1. 关于清理autorun - 2. 关于触发视图更新的一种方案 - 3. 关于store的传递 / 单例模式 - 4. 关于细粒度拆分 - 5. 关于跨组件触发更新的问题 - 6. 在async/await中使用runInAction ``` ================================================ FILE: _template/page-config.js ================================================ module.exports = function (envData, projectData, global) { return { pageTitle: '<%component-name%>', privateCSS: [ `${projectData.__PROJECT_PREFIX__}<%component-name%>.css`, ].map(function(url) { return `` }).join(''), privateJS: [ `${projectData.__PROJECT_PREFIX__}<%component-name%>.js`, ].map(function(url) { return `\n ` }).join(''), } } ================================================ FILE: _template/page-dir/<%component-name%>-store.js ================================================ import {observable, action} from 'mobx' export default class <%ComponentName%>Store { // 被观察的属性 @observable content = '' // 异步action示例 @action getContent = () => { setTimeout(action('test action', () => { this.content = '从前有座山,山里有个庙,庙里有个缸,缸里有个盆,盆里有个碗,碗里有个豆,我吃了,你馋了,我的故事讲完了。' }), 1000) } // 同步action示例 @action clearContent() { this.content = '' } } ================================================ FILE: _template/page-dir/<%component-name%>.js ================================================ import {Component} from 'react' import {Button, Modal} from 'antd' import {observable, action} from 'mobx' import {observer} from 'mobx-react' import <%ComponentName%>Store from './<%component-name%>-store' const store = new <%ComponentName%>Store() @observer export default class <%ComponentName%> extends Component { @observable modalVisible = false constructor(props) { super(props) } render() { return
{/* 通用头部 */} {/* ... */} {/* 页面主体区域 */}
Store示例:
{ store.content ?
{store.content}
: }
UI状态示例:
this.closeModal()} onCancel={() => this.closeModal()}>

some contents...

some contents...

some contents...

环境变量
__DEV__: {'' + __DEV__}
__PRODUCTION__: {'' + __PRODUCTION__}
{/* 通用底部 */} {/* ... */}
} @action openModal() { this.modalVisible = true } @action closeModal() { this.modalVisible = false } } ================================================ FILE: _template/page-dir/<%component-name%>.styl ================================================ .<%component-name%> .main background-color: papayawhip ================================================ FILE: _template/page-dir/index.js ================================================ import './<%component-name%>.styl' import <%ComponentName%> from './<%component-name%>' import ReactDOM from 'react-dom' import DevTools from 'mobx-react-devtools' ReactDOM.render(
{__DEV__ && } <<%ComponentName%>/>
, document.getElementById('root') ) ================================================ FILE: _template/page-dir/io.js ================================================ import ioContext from '../common/io-context' ioContext.create('<%componentName%>',{ xxx:{ url: 'xxx' } }) export default ioContext.api.<%componentName%> ================================================ FILE: index.html ================================================ 所有页面
demo
mobx
================================================ FILE: package.json ================================================ { "name": "project-name", "version": "1.0.0", "description": "react webpack", "main": "index.js", "scripts": { "start": "cross-env NODE_ENV=development webpack-dev-server && node tool.js -i", "build": "cross-env NODE_ENV=production webpack --hide-modules true" }, "repository": {}, "author": "js", "license": "MIT", "dependencies": { "autobind-decorator": "^1.3.4", "classnames": "^2.2.5", "mobx": "^3.1.0", "mobx-react": "^4.1.0", "natty-fetch": "^2.2.3", "react": "^15.4.2", "react-dom": "^15.4.2", "react-router": "^3.0.2", "react-router-dom": "^4.1.1", "whatwg-fetch": "^2.0.2", "prismjs": "^1.6.0", "react-markdown": "^2.4.6" }, "devDependencies": { "autoprefixer": "^6.7.3", "autoprefixer-loader": "^3.2.0", "babel-core": "^6.22.1", "babel-eslint": "^7.1.1", "babel-loader": "^6.2.10", "babel-plugin-react-transform": "^2.0.2", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-runtime": "^6.22.0", "babel-preset-es2015": "^6.22.0", "babel-preset-react": "^6.22.0", "babel-preset-react-hmre": "^1.1.1", "babel-preset-stage-2": "^6.22.0", "babel-runtime": "^6.22.0", "cross-env": "^3.1.4", "css-loader": "^0.26.1", "eslint": "^3.15.0", "eslint-config-airbnb": "^14.1.0", "eslint-loader": "^1.6.1", "eslint-plugin-babel": "^4.0.1", "eslint-plugin-import": "^2.2.0", "eslint-plugin-jsx-a11y": "^4.0.0", "eslint-plugin-react": "^6.9.0", "extract-text-webpack-plugin": "^2.0.0", "file-loader": "^0.10.0", "fs-extra": "^2.0.0", "html-webpack-plugin": "^2.28.0", "json-loader": "^0.5.4", "lodash": "^4.17.4", "metalsmith": "^2.3.0", "metalsmith-collections": "^0.9.0", "minimatch": "^3.0.3", "mobx-react-devtools": "^4.2.11", "postcss-loader": "^1.2.2", "react-transform-catch-errors": "^1.0.2", "react-transform-hmr": "^1.0.4", "redbox-react": "^1.3.3", "source-map-loader": "^0.1.6", "style-loader": "^0.13.1", "stylus": "^0.54.5", "stylus-loader": "^2.5.0", "url-loader": "^0.5.7", "webpack": "^2.2.1", "webpack-dev-server": "^2.3.0", "yargs": "^6.6.0" } } ================================================ FILE: page-base/base.html ================================================ <%= htmlWebpackPlugin.options.pageTitle %> <%= htmlWebpackPlugin.options.publicCSS %> <%= htmlWebpackPlugin.options.privateCSS %>
<%= htmlWebpackPlugin.options.publicJS %> <%= htmlWebpackPlugin.options.privateJS %> ================================================ FILE: page-base/base.js ================================================ // 这个文件不要用ES6语法!!! module.exports = function (envData, projectData) { var isDev = envData.__DEV__; var jsExt = `${isDev ? '.' : '.min.'}js`; var publicPrefix = projectData.__PUBLIC_PREFIX__; var projectPrefix = projectData.__PROJECT_PREFIX__; return { // 全局通用`css`库 publicCSS: [ 'antd/2.7.2/dist/antd.min.css', '//at.alicdn.com/t/font_tcp3x4qhuth85mi.css' ].map(function(url){ if(url.indexOf('//') > -1) { return `` } else { return `` } }).join(''), // 页面私有`css` privateCSS: '', // 全局通用`js`库, 位于页面私有`js`之前 publicJS: [ `${publicPrefix}js/react/15/react${jsExt}`, `${publicPrefix}js/react/15/react-dom${jsExt}`, `${publicPrefix}mobx/3.1.0/lib/mobx.umd${jsExt}`, `${publicPrefix}mobx-react/4.1.0/index${jsExt}`, // antd太大了,开发环境也用min吧 `${publicPrefix}antd/2.7.2/dist/antd.min.js`, `${publicPrefix}lodash/4.17.4/lodash${jsExt}`, // 通用chunk,不用加入`.min` `${projectPrefix}common.js`, //d3-v4版本 'https://d3js.org/d3.v4.min.js' ].map(function(url) { return `\n ` }).join(''), // 页面私有`js` privateJS: '' } } ================================================ FILE: page-config/demo.js ================================================ // 这个文件不要用ES6语法!!! module.exports = function (envData, projectData, global) { return { pageTitle: 'demo page-dir', privateCSS: [ `${projectData.__PROJECT_PREFIX__}demo.css`, ].map(function(url) { return `` }).join(''), privateJS: [ `${projectData.__PROJECT_PREFIX__}demo.js`, ].map(function(url) { return `\n ` }).join(''), } } ================================================ FILE: page-config/mobx.js ================================================ module.exports = function (envData, projectData, global) { return { pageTitle: 'mobx', privateCSS: [ `${projectData.__PROJECT_PREFIX__}mobx.css`, ].map(function(url) { return `` }).join(''), privateJS: [ `${projectData.__PROJECT_PREFIX__}mobx.js`, ].map(function(url) { return `\n ` }).join(''), } } ================================================ FILE: postcss.config.js ================================================ module.exports = { plugins: [ require('autoprefixer') ] }; ================================================ FILE: src/common/app.styl ================================================ body { margin: 0; padding: 0; font-family: "微软雅黑","Hiragino Sans GB","Microsoft Yahei",SimSun,Arial,"Helvetica Neue",Helvetica; color: #333; word-wrap: break-word; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; line-height: 100% !important; } body { font-size: 14px !important; width: 100%; min-width: 1200px; color: #333; /*background-color: #f7f7f7;*/ padding: 0; margin: 0; width: 100%; } .w1200{ width: 1200px; margin: 0 auto; } .ant-modal-footer{ text-align: center; } .ant-popover-buttons{ text-align: center; button{ &:last-child{ margin-left: -95px; }; } } .ant-table { font-size: 14px !important; } label { font-size: 14px !important; } ================================================ FILE: src/common/common.js ================================================ import mobx from 'mobx' mobx.useStrict(true) ================================================ FILE: src/head/head.js ================================================ import {Component} from 'react' export default class Head extends Component { render() { return
Head
} } ================================================ FILE: src/head/index.js ================================================ import Head from './head' export default Head ================================================ FILE: src/markdown/index.js ================================================ import Markdown from './markdown' export default Markdown; ================================================ FILE: src/markdown/markdown.js ================================================ import React from 'react' import ReactMarkdown from 'react-markdown' import Prism from 'prismjs' import 'prismjs/themes/prism-coy.css' function CodeBlock(props) { let html = Prism.highlight(props.literal, Prism.languages[props.language]); let cls = 'language-' + props.language; return (
          
      
) } const Markdown = ({source, show = true}) =>(
); export default Markdown; ================================================ FILE: src/page-demo/demo-store.js ================================================ import {observable, action} from 'mobx' import NattyFetch from 'natty-fetch' export default class DemoStore { // 被观察的属性 @observable content = '' // 异步action示例 @action getContent = () => { setTimeout(action(() => { this.content = '考研成绩出来,很多群里炸开了锅,都在谈这事。结果有三种:毫无悬念地进复试、等待被调剂、没考上' }), 1000) } // 同步action示例 @action clearContent() { this.content = '' } } ================================================ FILE: src/page-demo/demo.js ================================================ import {Component} from 'react' import {Button, Modal} from 'antd' import {observable, action} from 'mobx' import {observer} from 'mobx-react' import Head from '../head' import DemoStore from './demo-store' const store1 = new DemoStore() const store2 = new DemoStore() @observer export default class Home extends Component { @observable modalVisible = false @observable aaa = false constructor(props) { super(props) } render() { return
Store示例:
{ store1.content ?
{store1.content}
: }
{ store2.content ?
{store2.content}
: }
UI状态示例:
{ this.modalVisible ? 1111 : null } this.closeModal()} onCancel={() => this.closeModal()}>

some contents...

some contents...

some contents...

环境变量
__DEV__: {'' + __DEV__}
__PRODUCTION__: {'' + __PRODUCTION__}
} @action openModal() { this.modalVisible = true } @action closeModal() { this.modalVisible = false } } ================================================ FILE: src/page-demo/demo.styl ================================================ body background-color: yellow .demo-main .box background-color: orangered border-radius: 10px width: 100px height: 100px display: flex ================================================ FILE: src/page-demo/index.js ================================================ import './demo.styl' import Demo from './demo' import ReactDOM from 'react-dom' import mobx from 'mobx' import DevTools from 'mobx-react-devtools' mobx.useStrict(true) ReactDOM.render(
{__DEV__ && }
, document.getElementById('root') ) ================================================ FILE: src/page-demo/io.js ================================================ ================================================ FILE: src/page-mobx/D/d1.js ================================================ import React from 'react' //import d3 from '../d3' import '../style/p1.styl' let info = ` \`\`\`js 123 \`\`\` `; class P1 extends React.Component { drawChart(){ let width = 1000; let height = 800; this.data = { 'name':'Mobx知识结构', isV: true, 'children': [ { 'name':"API" , '_children': [ { 'name': 'mobx', _children: [ {'name':"@observable", isV: true}, {'name':"@action", isV: true}, {'name':"autorun / when / reaction" }, {'name':"@computed" }, {'name':"intercept & observe" }, {'name':"工具API: extendObservable, toJS, isObservable" }, ] }, { 'name': 'mobx-react', _children: [ {'name':"@observer", isV: true}, {'name':"Observer" }, {'name':"Provider / inject" }, {'name':"componentWillReact" }, {'name':"PropTypes" } ] }, ] }, { 'name':'Observable类型', "_children": [ { "name":"object", "_children": [ {"name":"新增属性更新触发问题"} ] }, { 'name':'arrays', "_children": [ {"name":"clear/replace/remove方法"}, {"name":"slice/ toJS方法"}, {"name":"arrays更新触发"} ] }, { 'name':'maps', "_children": [ {"name":"两种定义的差别"}, {"name":"和ES6map的区别"} ] } ] }, { "name":"问题", "_children": [ {"name":"1. 关于清理autorun"}, {"name":"2. 关于触发视图更新的一种方案"}, {"name":"3. 关于store的传递 / 单例模式"}, {"name":"4. 关于细粒度拆分"} ] }, ] }; //边界空白 let padding = {left: 150, right:50, top: 20, bottom: 50 }; this.svg = d3.select('#p1') .append('svg') .attr('width', width + padding.left + padding.right) .attr('height', height + padding.top + padding.bottom) .append('g') .attr("transform",`translate(${padding.left}, ${padding.top})`); //树状图布局 this.tree = d3.layout.tree().size([height, width]); //对角线生成器 this.diagonal = d3.svg.diagonal().projection(d => [d.y, d.x]); //给第一个节点添加初始坐标x0和x1 let root = this.data; root.x0 = height / 2; root.y0 = 0; //以第一个节点为起始节点,重绘 this.redraw(root); } //重绘函数 redraw = (source) => { let that = this; /** 1. 计算节点和连线的位置 */ //应用布局,计算节点和连线 let nodes = this.tree.nodes(this.data); let links = this.tree.links(nodes); //重新计算节点的y坐标 nodes.forEach(d => d.y = d.depth * 180); /** 2. 节点的处理*/ //获取节点的update部分 let nodeUpdate = this.svg.selectAll(".node") .data(nodes, d => d.name); //获取节点的enter部分 let nodeEnter = nodeUpdate.enter(); //获取节点的exit部分 let nodeExit = nodeUpdate.exit(); //1. 节点的 Enter 部分的处理办法 let enterNodes = nodeEnter.append("g") .attr("class", "node") .attr("transform", d => `translate(${source.y0}, ${source.x0})`) .on("click", function(d){ that.toggle(d); that.redraw(d); }); enterNodes.append("circle") .attr("r", 0) .style("fill", d => d._children ? "lightsteelblue" : "#fff"); enterNodes.append("text") .attr("x", d => d.children || d._children ? -14 : 14) .attr("dy", ".35em") .attr("text-anchor", d => d.children || d._children ? "end" : "start") .text(d => d.name) .style("fill-opacity", 0); //2. 节点的 Update 部分的处理办法 let updateNodes = nodeUpdate.transition() .duration(500) .attr("transform", d => `translate(${d.y}, ${d.x})`); updateNodes.select("circle") .attr("r", 8) .style("fill", d => d._children ? "lightsteelblue" : "#fff"); updateNodes.select("text") .style("fill-opacity", 1) .style('font-weight', d => d.isV ? 'bold' : 'normal') .style('fill', d => d.isV ? 'red' : 'black'); //3. 节点的 Exit 部分的处理办法 let exitNodes = nodeExit.transition() .duration(500) .attr("transform", d => `translate(${source.y}, ${source.x})`) .remove(); exitNodes.select("circle").attr("r", 0); exitNodes.select("text").style("fill-opacity", 0); /** 3. 连线的处理 */ //获取连线的update部分 let linkUpdate = this.svg.selectAll(".link") .data(links, function (d) { return d.target.name; }); //获取连线的enter部分 let linkEnter = linkUpdate.enter(); //获取连线的exit部分 let linkExit = linkUpdate.exit(); //1. 连线的 Enter 部分的处理办法 linkEnter.insert("path", ".node") .attr("class", "link") .attr("d", function (d) { var o = {x: source.x0, y: source.y0}; return that.diagonal({source: o, target: o}); }) .transition() .duration(500) .attr("d", that.diagonal); //2. 连线的 Update 部分的处理办法 linkUpdate.transition() .duration(500) .attr("d", that.diagonal); //3. 连线的 Exit 部分的处理办法 linkExit.transition() .duration(500) .attr("d", function (d) { var o = {x: source.x, y: source.y}; return that.diagonal({source: o, target: o}); }) .remove(); /** 4. 将当前的节点坐标保存在变量x0、y0里,以备更新时使用*/ nodes.forEach(function (d) { d.x0 = d.x; d.y0 = d.y; }); }; //切换开关,d 为被点击的节点 toggle = (d) => { if (d.children) { //如果有子节点 d._children = d.children; //将该子节点保存到 _children d.children = null; //将子节点设置为null } else { //如果没有子节点 d.children = d._children; //从 _children 取回原来的子节点 d._children = null; //将 _children 设置为 null } }; componentDidMount(){ this.drawChart(); } render() { return (

Mobx知识结构

{/**/}
); } } export default P1; ================================================ FILE: src/page-mobx/D/d2.js ================================================ import React from 'react' import d3 from '../../v3.lesson/d3' import '../style/p1.styl' let info = ` \`\`\`js 123 \`\`\` `; class P1 extends React.Component { drawChart(){ let width = 1000; let height = 800; this.data = { 'name':'Mobx知识结构', isV: true, 'children': [ { 'name':"API" , '_children': [ { 'name': 'mobx', _children: [ {'name':"@observable", isV: true}, {'name':"@action", isV: true}, {'name':"autorun / when / reaction" }, {'name':"@computed" }, {'name':"intercept & observe" }, {'name':"工具API: extendObservable, toJS, isObservable" }, ] }, { 'name': 'mobx-react', _children: [ {'name':"@observer", isV: true}, {'name':"Observer" }, {'name':"Provider / inject" }, {'name':"componentWillReact" }, {'name':"PropTypes" } ] }, ] }, { 'name':'Observable类型', "_children": [ { "name":"object", "_children": [ {"name":"新增属性更新触发问题"} ] }, { 'name':'arrays', "_children": [ {"name":"clear/replace/remove方法"}, {"name":"slice/ toJS方法"}, {"name":"arrays更新触发"} ] }, { 'name':'maps', "_children": [ {"name":"两种定义的差别"}, {"name":"和ES6map的区别"} ] } ] }, { "name":"问题", "_children": [ {"name":"1. 关于清理autorun"}, {"name":"2. 关于触发视图更新的一种方案"}, {"name":"3. 关于store的传递 / 单例模式"}, {"name":"4. 关于细粒度拆分"} ] }, ] }; //边界空白 let padding = {left: 150, right:50, top: 20, bottom: 50 }; this.svg = d3.select('#p1') .append('svg') .attr('width', width + padding.left + padding.right) .attr('height', height + padding.top + padding.bottom) .append('g') .attr("transform",`translate(${padding.left}, ${padding.top})`); //树状图布局 this.tree = d3.layout.tree().size([height, width]); //对角线生成器 this.diagonal = d3.svg.diagonal().projection(d => [d.y, d.x]); //给第一个节点添加初始坐标x0和x1 let root = this.data; root.x0 = height / 2; root.y0 = 0; //以第一个节点为起始节点,重绘 this.redraw(root); } //重绘函数 redraw = (source) => { let that = this; /** 1. 计算节点和连线的位置 */ //应用布局,计算节点和连线 let nodes = this.tree.nodes(this.data); let links = this.tree.links(nodes); //重新计算节点的y坐标 nodes.forEach(d => d.y = d.depth * 180); /** 2. 节点的处理*/ //获取节点的update部分 let nodeUpdate = this.svg.selectAll(".node") .data(nodes, d => d.name); //获取节点的enter部分 let nodeEnter = nodeUpdate.enter(); //获取节点的exit部分 let nodeExit = nodeUpdate.exit(); //1. 节点的 Enter 部分的处理办法 let enterNodes = nodeEnter.append("g") .attr("class", "node") .attr("transform", d => `translate(${source.y0}, ${source.x0})`) .on("click", function(d){ that.toggle(d); that.redraw(d); }); enterNodes.append("circle") .attr("r", 0) .style("fill", d => d._children ? "lightsteelblue" : "#fff"); enterNodes.append("text") .attr("x", d => d.children || d._children ? -14 : 14) .attr("dy", ".35em") .attr("text-anchor", d => d.children || d._children ? "end" : "start") .text(d => d.name) .style("fill-opacity", 0); //2. 节点的 Update 部分的处理办法 let updateNodes = nodeUpdate.transition() .duration(500) .attr("transform", d => `translate(${d.y}, ${d.x})`); updateNodes.select("circle") .attr("r", 8) .style("fill", d => d._children ? "lightsteelblue" : "#fff"); updateNodes.select("text") .style("fill-opacity", 1) .style('font-weight', d => d.isV ? 'bold' : 'normal') .style('fill', d => d.isV ? 'red' : 'black'); //3. 节点的 Exit 部分的处理办法 let exitNodes = nodeExit.transition() .duration(500) .attr("transform", d => `translate(${source.y}, ${source.x})`) .remove(); exitNodes.select("circle").attr("r", 0); exitNodes.select("text").style("fill-opacity", 0); /** 3. 连线的处理 */ //获取连线的update部分 let linkUpdate = this.svg.selectAll(".link") .data(links, function (d) { return d.target.name; }); //获取连线的enter部分 let linkEnter = linkUpdate.enter(); //获取连线的exit部分 let linkExit = linkUpdate.exit(); //1. 连线的 Enter 部分的处理办法 linkEnter.insert("path", ".node") .attr("class", "link") .attr("d", function (d) { var o = {x: source.x0, y: source.y0}; return that.diagonal({source: o, target: o}); }) .transition() .duration(500) .attr("d", that.diagonal); //2. 连线的 Update 部分的处理办法 linkUpdate.transition() .duration(500) .attr("d", that.diagonal); //3. 连线的 Exit 部分的处理办法 linkExit.transition() .duration(500) .attr("d", function (d) { var o = {x: source.x, y: source.y}; return that.diagonal({source: o, target: o}); }) .remove(); /** 4. 将当前的节点坐标保存在变量x0、y0里,以备更新时使用*/ nodes.forEach(function (d) { d.x0 = d.x; d.y0 = d.y; }); }; //切换开关,d 为被点击的节点 toggle = (d) => { if (d.children) { //如果有子节点 d._children = d.children; //将该子节点保存到 _children d.children = null; //将子节点设置为null } else { //如果没有子节点 d.children = d._children; //从 _children 取回原来的子节点 d._children = null; //将 _children 设置为 null } }; componentDidMount(){ this.drawChart(); } render() { return (

Mobx知识结构

{/**/}
); } } export default P1; ================================================ FILE: src/page-mobx/Q/q1.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer, Observer} from 'mobx-react' import Markdown from '../../markdown' import { Table, Button} from 'antd'; let info = ` 参考资料: - [Is autorun equivalent to componentWillReact?](https://github.com/mobxjs/mobx-react/issues/62) - [autorun](http://cn.mobx.js.org/refguide/autorun.html) \`\`\`js componentDidMount(){ this.disposer = autorun(() => { if (this.isError) { notification.error({message: '有错误', description: '这是错误提示'}); } }); this.disposer2 = when( () => !this.isError, () => { notification.success({message: '没有错误', description: '没有错误'}); } ); } componentWillUnmount(){ this.disposer(); this.disposer2(); } \`\`\` `; class Q1 extends React.Component { render() { return (

Q1: 关于清理autorun观察

); } } export default Q1; ================================================ FILE: src/page-mobx/Q/q2.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer, Observer} from 'mobx-react' import Markdown from '../../markdown' import { Table, Button} from 'antd'; let info = ` 参考资料: - [关于在mobx中如何observe观察深层的数据变动](https://github.com/ckinmind/ReactCollect/issues/97) \`\`\`js @observer class Test extends Component { data = []; // data内存储的是嵌套很深的数据 @observable updateKey = ''; //定义一个用于触发更新的变量 /** 视图触发器,里面什么也不用做 */ @action renderTrigger = () => { }; @action changeData = () => { // 异步或者别的什么操作,改变了data this.updateKey = Math.random(); // 随机改变updateKey的值,只要和之前不一样就行 // 因为这里改变了,所以触发了renderTrigger的依赖变动(即使里面什么也不做), // 从而触发了视图更新, 从而将改变都反应到视图中 }; render(){ this.renderTrigger(this.updateKey); // 这里必须传入updateKey,效果类似autorun return ( ....... ) } } 1. 任何需要改变data然后视图更新的地方,都可以通过改变updateaKey来触发视图更新 2. 极端情况是,只定义一个updateKey是observable,其他所有的变量都可以不用是observable, 任何数据改变后需要触发更新,只要直接this.updateKey = Math.random();就行 3. 还有一个额外的好处是,可以让data的数据结构变得清晰,否则使用observable之后结构看起来就不太一样, 加上可能还需要转换状态比如toJS,slice之类的,使用了我这种方式就可以直接使用原数据 \`\`\` `; class Q2 extends React.Component { render() { return (

Q2: 关于更新触发的一种方案

); } } export default Q2; ================================================ FILE: src/page-mobx/Q/q3.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer, Observer} from 'mobx-react' import Markdown from '../../markdown' import { Table, Button} from 'antd'; let info = ` \`\`\`js 1. 定义store, 直接export这个store,然后在定义组件中实例化,通过props传递到子组件 ----------------------------------------- class store { ... } export default store; ----------------------------------------- import store from './store' let store-Instance = new store(); class App extends Component { // 使用store-Instance的属性和方法 render(){ return ( ); }; } ----------------------------------------- 2. store定义完之后直接export这个store的实例(单例模式),然后所有组件共享这一个store实例 那个组件需要就import这个实例 ----------------------------------------- class store { ... } export default new store(); ----------------------------------------- import store-Instance from './store' class App extends Component { // 使用store-Instance的属性和方法 } ----------------------------------------- import store-Instance from './store' class OtherComponent extends Component { // 使用store-Instance的属性和方法 } ----------------------------------------- \`\`\` `; @observer class Q3 extends React.Component { render() { return (

Q3: 关于store的传递 / 单例模式

); } } export default Q3; ================================================ FILE: src/page-mobx/Q/q4.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer, Observer} from 'mobx-react' import Markdown from '../../markdown' import { Table, Button} from 'antd'; let info = ` \`\`\`js 1. 当一个observable只被一个组件使用时,将这个变量放在组件中,不要放在store中 2. 当有多个组件使用一个observable的变量时,有以下几种方式,去传递使用这个变量 a. 将这个变量放到store中, 引入该store然后使用 b. 通过props传递到子组件(注意@observer的问题 / 传递原始值和传递对象的问题 / 使用Observer组件的问题) c. 跨组件传递可以通过Provider / inject 注入 \`\`\` `; @observer class Q4 extends React.Component { render() { return (

Q4: 关于细粒度拆分 ?

); } } export default Q4; ================================================ FILE: src/page-mobx/aside.js ================================================ import React from 'react'; import { NavLink } from 'react-router-dom'; class Aside extends React.Component { render() { return ( ) } } export default Aside; ================================================ FILE: src/page-mobx/css/p7.scss ================================================ .info-block{ display: flex; div { text-align: center; background: rgba(0,0,0,0.05); border-radius: 4px; padding: 30px 50px; margin: 20px 10px; width: 100%; font-size: 20px; } } ================================================ FILE: src/page-mobx/css/p8.scss ================================================ .head-example { width: 42px; height: 42px; border-radius: 6px; background: #eee; display: inline-block; } .message-item { padding: 8px; } ================================================ FILE: src/page-mobx/d3.js ================================================ !function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); ================================================ FILE: src/page-mobx/index.js ================================================ import ReactDOM from 'react-dom' import DevTools from 'mobx-react-devtools' import Route from './routes' import './style/app.styl' ReactDOM.render(
{__DEV__ && } {/**/}
, document.getElementById('root') ); ================================================ FILE: src/page-mobx/p0.js ================================================ import React from 'react' import './style/p0.styl' class P0 extends React.Component { render() { return (

MobX分享

); } } export default P0; ================================================ FILE: src/page-mobx/p1.js ================================================ import React from 'react' import d3 from './d3' import './style/p1.styl' class P1 extends React.Component { drawChart(){ let width = 900; let height = 700; this.data = { 'name':'Mobx知识结构', '_children': [ { 'name':"API" , '_children': [ { 'name': 'mobx', _children: [ {'name':"@observable", isV: true}, {'name':"@action", isV: true}, {'name':"autorun / when / reaction" }, {'name':"@computed" }, {'name':"intercept & observe" }, {'name':"工具API: extendObservable, toJS, isObservable" }, ] }, { 'name': 'mobx-react', _children: [ {'name':"@observer", isV: true}, {'name':"Observer" }, {'name':"Provider / inject" }, {'name':"componentWillReact" }, {'name':"PropTypes" } ] }, ] }, { 'name':'Observable类型', "_children": [ { "name":"object", "_children": [ {"name":"extendObservable"} ] }, { 'name':'arrays', "_children": [ {"name":"clear/replace/remove方法"}, {"name":"slice/ toJS方法"}, {"name":"arrays更新触发"} ] }, { 'name':'maps', "_children": [ {"name":"两种定义的差别"}, {"name":"和ES6map的区别"} ] } ] }, { "name":"问题", "_children": [ {"name":"1. 关于清理autorun"}, {"name":"2. 关于触发视图更新的一种方案"}, {"name":"3. 关于store的传递 / 单例模式"}, {"name":"4. 关于细粒度拆分"}, {"name":"5. 关于跨组件触发更新的问题"}, {"name":"6. 在async/await中使用runInAction"}, ] }, ] }; //边界空白 let padding = {left: 150, right:50, top: 20, bottom: 50 }; this.svg = d3.select('#p1') .append('svg') .attr('width', width + padding.left + padding.right) .attr('height', height + padding.top + padding.bottom) .append('g') .attr("transform",`translate(${padding.left}, ${padding.top})`); //树状图布局 this.tree = d3.layout.tree().size([height, width]); //对角线生成器 this.diagonal = d3.svg.diagonal().projection(d => [d.y, d.x]); //给第一个节点添加初始坐标x0和x1 let root = this.data; root.x0 = height / 2; root.y0 = 0; //以第一个节点为起始节点,重绘 this.redraw(root); } //重绘函数 redraw = (source) => { let that = this; /** 1. 计算节点和连线的位置 */ //应用布局,计算节点和连线 let nodes = this.tree.nodes(this.data); let links = this.tree.links(nodes); //重新计算节点的y坐标 nodes.forEach(d => d.y = d.depth * 180); /** 2. 节点的处理*/ //获取节点的update部分 let nodeUpdate = this.svg.selectAll(".node") .data(nodes, d => d.name); //获取节点的enter部分 let nodeEnter = nodeUpdate.enter(); //获取节点的exit部分 let nodeExit = nodeUpdate.exit(); //1. 节点的 Enter 部分的处理办法 let enterNodes = nodeEnter.append("g") .attr("class", "node") .attr("transform", d => `translate(${source.y0}, ${source.x0})`) .on("click", function(d){ that.toggle(d); that.redraw(d); }); enterNodes.append("circle") .attr("r", 0) .style("fill", d => d._children ? "lightsteelblue" : "#fff"); enterNodes.append("text") .attr("x", d => d.children || d._children ? -14 : 14) .attr("dy", ".35em") .attr("text-anchor", d => d.children || d._children ? "end" : "start") .text(d => d.name) .style("fill-opacity", 0); //2. 节点的 Update 部分的处理办法 let updateNodes = nodeUpdate.transition() .duration(500) .attr("transform", d => `translate(${d.y}, ${d.x})`); updateNodes.select("circle") .attr("r", 8) .style("fill", d => d._children ? "lightsteelblue" : "#fff"); updateNodes.select("text") .style("fill-opacity", 1) .style('font-weight', d => d.isV ? 'bold' : 'normal') .style('fill', d => d.isV ? 'red' : 'black'); //3. 节点的 Exit 部分的处理办法 let exitNodes = nodeExit.transition() .duration(500) .attr("transform", d => `translate(${source.y}, ${source.x})`) .remove(); exitNodes.select("circle").attr("r", 0); exitNodes.select("text").style("fill-opacity", 0); /** 3. 连线的处理 */ //获取连线的update部分 let linkUpdate = this.svg.selectAll(".link") .data(links, function (d) { return d.target.name; }); //获取连线的enter部分 let linkEnter = linkUpdate.enter(); //获取连线的exit部分 let linkExit = linkUpdate.exit(); //1. 连线的 Enter 部分的处理办法 linkEnter.insert("path", ".node") .attr("class", "link") .attr("d", function (d) { var o = {x: source.x0, y: source.y0}; return that.diagonal({source: o, target: o}); }) .transition() .duration(500) .attr("d", that.diagonal); //2. 连线的 Update 部分的处理办法 linkUpdate.transition() .duration(500) .attr("d", that.diagonal); //3. 连线的 Exit 部分的处理办法 linkExit.transition() .duration(500) .attr("d", function (d) { var o = {x: source.x, y: source.y}; return that.diagonal({source: o, target: o}); }) .remove(); /** 4. 将当前的节点坐标保存在变量x0、y0里,以备更新时使用*/ nodes.forEach(function (d) { d.x0 = d.x; d.y0 = d.y; }); }; //切换开关,d 为被点击的节点 toggle = (d) => { if (d.children) { //如果有子节点 d._children = d.children; //将该子节点保存到 _children d.children = null; //将子节点设置为null } else { //如果没有子节点 d.children = d._children; //从 _children 取回原来的子节点 d._children = null; //将 _children 设置为 null } }; componentDidMount(){ this.drawChart(); } render() { return (

Mobx知识结构

); } } export default P1; ================================================ FILE: src/page-mobx/p10.js ================================================ import React from 'react' import {observable, action,computed} from 'mobx' import {observer} from 'mobx-react' import Markdown from '../markdown' let info = ` 注意: 如果是异步请求,在请求的回调中需要改变observable的变量,必须在回调的外层包一层action函数,才能触发更新 \`\`\`js import {action } from 'mobx' fetch('xxxx') .then(action(res => { // 成功操作,可能会改变observable的值,从而触发更新,必须外边包一层action函数 })).catch(action(err => { // 错误回调, 如果有改变observable值的操作,也需要外边包一层action函数 })); \`\`\` 如果使用 async / await, 需要使用runInAction \`\`\`js import {runInAction } from 'mobx' @observable data = '' async initData() { let content = await fetch('xxxx') runInAction(() => { this.data = content.data }) } \`\`\` `; @observer class P10 extends React.Component { render() { return (

action / runInAction

); } } export default P10; ================================================ FILE: src/page-mobx/p2.js ================================================ import React from 'react' import {observable, action, autorun, when} from 'mobx' import {observer, whyRun} from 'mobx-react' import Markdown from '../markdown' import './style/p1.styl' import { Button, notification, Switch } from 'antd' let info = ` \`\`\`js \import {observable, action, autorun, when} from 'mobx' @observable isError = false; @action handleClick = () => { this.isError = !this.isError; }; componentDidMount(){ autorun(()=> { if (this.isError) { notification.error({ message: '有错误', description: '这是错误提示' }); } }); when( () => !this.isError, () => { notification.success({message: '没有错误', description: '没有错误'}); } ); } render() { return (
); } \`\`\` `; let result = ` \`\`\`js 1. when 满足条件后只执行一次,autorun 满足条件可以可以一直执行 2. reaction 函数是 autorun 的变种,粗略地讲,reaction 是 computed(expression).observe(action(sideEffect)) 或 autorun(() => action(sideEffect)(expression) 的语法糖 3. 注意 autorun 的清理查看Q1 \`\`\` `; @observer class P2 extends React.Component { @observable showResult = false; @observable isError = false; @action handleClick = () => { this.isError = !this.isError; }; componentDidMount(){ autorun(() => { if (this.isError) { notification.error({message: '有错误', description: '这是错误提示'}); } }); when( () => !this.isError, () => { notification.success({message: '没有错误', description: '没有错误'}); } ); } componentWillUnmount(){ console.log('this is componentWillUnmount'); } render() { return (
this.showResult = !this.showResult}/>

autorun / when / reaction

); } } export default P2; ================================================ FILE: src/page-mobx/p3.js ================================================ import React from 'react' import {observable, action,computed} from 'mobx' import {observer} from 'mobx-react' import Markdown from '../markdown' import './style/p1.styl' import { Button, notification } from 'antd'; let info = ` \`\`\`js import {observable, action,computed} from 'mobx' class store { @observable num = 8; @computed get price(){ return this.num * 100; } } @observer class App extends React.Component { @action handleClick = () => { store.num = Math.random(); }; render() { return (

衬衫的价格是: {store.price}

); } } \`\`\` `; @observer class P3 extends React.Component { @observable num = 8; @computed get price(){ return this.num * 100; } @action handleClick = () => { this.num = Math.random(); }; render() { return (

@computed

衬衫的价格是: {this.price}

); } } export default P3; ================================================ FILE: src/page-mobx/p4.js ================================================ import React from 'react' import {observable, action, computed, extendObservable} from 'mobx' import {observer} from 'mobx-react' import Markdown from '../markdown' import './style/p4.styl' import { Button, Spin, Switch} from 'antd'; let info = ` 参考资料:[extendObservable](https://github.com/mobxjs/mobx/issues/194) \`\`\`js import {observable, action, computed, extendObservable} from 'mobx' import {observer} from 'mobx-react' @observable isSpinning = { S1: false }; @action handleClick1 = () => { this.isSpinning.S1 = !this.isSpinning.S1; }; @action handleClick2 = () => { if(Object.keys(this.isSpinning).includes('S2')){ this.isSpinning.S2 = !this.isSpinning.S2; }else{ this.isSpinning.S2 = true; } }; @action handleClick3 = () => { if(Object.keys(this.isSpinning).includes('S3')){ this.isSpinning.S3 = !this.isSpinning.S3; }else{ extendObservable(this.isSpinning, {S3:true}); } }; render() { return (
S1
S2
S3
); } \`\`\` `; let result = ` \`\`\`js let arr = []; _.forOwn(this.isSpinning, (value, key, obj) => { arr.push(
{key}
); }); \`\`\` `; @observer class P4 extends React.Component { @observable showResult = false; @observable isSpinning = { S1: false }; @action handleClick1 = () => { this.isSpinning.S1 = !this.isSpinning.S1; }; @action handleClick2 = () => { if(Object.keys(this.isSpinning).includes('S2')){ this.isSpinning.S2 = !this.isSpinning.S2; }else{ this.isSpinning.S2 = true; } }; @action handleClick3 = () => { if(Object.keys(this.isSpinning).includes('S3')){ this.isSpinning.S3 = !this.isSpinning.S3; }else{ extendObservable(this.isSpinning, {S3:true}); } }; render() { return (
this.showResult = !this.showResult}/>

object

S1
S2
S3
); } } export default P4; ================================================ FILE: src/page-mobx/p5.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer} from 'mobx-react' import Markdown from '../markdown' import { Table, Button, notification} from 'antd'; const columns = [{ title: 'Name', dataIndex: 'name', key: 'name', width: '40%', }, { title: 'Age', dataIndex: 'age', key: 'age', width: '30%', }, { title: 'Address', dataIndex: 'address', key: 'address', }]; let info = ` \`\`\`js @observable isLoading = false; @observable isLoading = false; @observable data = [ { key: 1, name: 'John Brown sr.', age: 60, address: 'New York No. 1 Lake Park', children: [ { key: 11, name: 'John Brown', age: 42, address: 'New York No. 2 Lake Park', }, { key: 12, name: 'John Brown jr.', age: 30, address: 'New York No. 3 Lake Park' } ] }, { key: 2, name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park'}, { key: 3, name: 'Jack Rose', age: 55, address: 'test', children: null}, { key: 4, name: ' CKTest', age: 55, address: 'test'} ]; handleClick1 = () => { setTimeout(()=>{ let key = Math.random(); this.data.push({ key: key, name: 'CK-' + key, age: 26, address: 'Hang Zhou' }); if(isObservable(this.data[this.data.length-1])){ notification.success({message: '消息提示', description: '新增的数据是observable的'}); } },200); }; handleClick2 = () => { setTimeout(() => { let key = Math.random(); // push 操作 }, 200); }; handleClick3 = () => { setTimeout(()=>{ if(!Object.keys(this.data[1]).includes('children')){ this.data[1].children = []; }else{ let key = Math.random(); // push操作 } },200); }; handleClick4 = () => { setTimeout(()=>{ if (!Array.isArray(toJS(this.data[2].children))) { this.data[2].children = []; }else{ let key = Math.random(); // push操作 } },200); }; handleClick5 = () => { this.isLoading = true; setTimeout(()=>{ if(!Object.keys(this.data[3]).includes('children')){ this.data[3].children = []; this.isLoading = false; }else{ let key = Math.random(); // push操作 this.isLoading = false; } },200); }; render() { return (
); } \`\`\` `; @observer class P5 extends React.Component { @observable isLoading = false; @observable data = [{ key: 1, name: 'John Brown sr.', age: 60, address: 'New York No. 1 Lake Park', children: [ { key: 11, name: 'John Brown', age: 42, address: 'New York No. 2 Lake Park', }, { key: 12, name: 'John Brown jr.', age: 30, address: 'New York No. 3 Lake Park' } ] }, { key: 2, name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park' },{ key: 3, name: 'Jack Rose', age: 55, address: 'test', children: null }, { key: 4, name: ' CKTest', age: 55, address: 'test' }]; handleClick1 = () => { setTimeout(()=>{ let key = Math.random(); this.data.push({ key: key, name: 'CK-' + key, age: 26, address: 'Hang Zhou' }); if(isObservable(this.data[this.data.length-1])){ notification.success({message: '消息提示', description: '新增的数据是observable的'}); } },200); }; handleClick2 = () => { setTimeout(() => { let key = Math.random(); this.data[0].children.push({ key: key, name: 'John Brown jr.' + key, age: 60, address: 'New York No. 3 Lake Park' }); if (isObservable(this.data[0].children[this.data[0].children.length-1])) { notification.success({message: '消息提示', description: '新增的数据是observable的'}); } }, 200); }; handleClick3 = () => { setTimeout(()=>{ if(!Object.keys(this.data[1]).includes('children')){ this.data[1].children = []; if (isObservable(this.data[1].children)) { notification.success({message: '消息提示', description: '新增的children属性是observable的'}); }else{ notification.error({message: '消息提示', description: '新增的children属性不是observable的'}); } }else{ let key = Math.random(); this.data[1].children.push({ key: key, name: 'Joe Black-' + key, age: 30, address: 'New York No. 3 Lake Park' }); if (isObservable(this.data[1].children[this.data[1].children.length-1])) { notification.success({message: '消息提示', description: '新增的数据是observable的'}); }else{ notification.error({message: '消息提示', description: '新增的数据不是observable的'}); } } },200); }; handleClick4 = () => { setTimeout(()=>{ if (!Array.isArray(toJS(this.data[2].children))) { this.data[2].children = []; if (isObservable(this.data[2].children)) { notification.success({message: '消息提示', description: '新增的children属性是observable的'}); }else{ notification.error({message: '消息提示', description: '新增的children属性不是observable的'}); } }else{ let key = Math.random(); this.data[2].children.push({ key: key, name: 'Jack Rose-' + key, age: 55, address: 'test' }); if (isObservable(this.data[2].children[this.data[2].children.length-1])) { notification.success({message: '消息提示', description: '新增的数据是observable的'}); }else{ notification.error({message: '消息提示', description: '新增的数据不是observable的'}); } } },200); }; handleClick5 = () => { this.isLoading = true; setTimeout(()=>{ if(!Object.keys(this.data[3]).includes('children')){ this.data[3].children = []; if (isObservable(this.data[3].children)) { notification.success({message: '消息提示', description: '新增的children属性是observable的'}); }else{ notification.error({message: '消息提示', description: '新增的children属性不是observable的'}); } this.isLoading = false; }else{ let key = Math.random(); this.data[3].children.push({ key: key, name: 'Joe Black-' + key, age: 30, address: 'New York No. 3 Lake Park' }); if (isObservable(this.data[3].children[this.data[3].children.length-1])) { notification.success({message: '消息提示', description: '新增的数据是observable的'}); }else{ notification.error({message: '消息提示', description: '新增的数据不是observable的'}); } this.isLoading = false; } },200); }; render() { return (

arrays

); } } export default P5; ================================================ FILE: src/page-mobx/p6.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, isObservable,isObservableMap} from 'mobx' import {observer} from 'mobx-react' import Markdown from '../markdown' import './style/p4.styl' import { Button, Spin, Switch} from 'antd'; let info = ` \`\`\`js import {observable, action, computed, extendObservable, isObservable,isObservableMap} from 'mobx' @observable map1 = observable.map(); @observable map2 = new Map(); @observable map3 = observable.map([ ['map3',[{value: true, key:'map3-0'}]] ]); @observable map4 = new Map([ ['map4',[{value: true, key:'map4-0'}]] ]); @action handleClick1 = () => { let key = 'map1-' + this.map1.size; this.map1.set(key, true); console.log('------ this is map1------'); console.log(this.map1.keys()); console.log(isObservable(this.map1.get('map1-1'))); console.log(isObservable(this.map1)); console.log(isObservableMap(this.map1)); }; @action handleClick2 = () => { let status = !this.map1.get('map1-1'); this.map1.set('map1-1',status); }; @action handleClick3 = () => { let key = 'map2-' + this.map2.size ; this.map2.set(key, true); console.log('------ this is map2------'); console.log(this.map2.keys()); console.log(isObservable(this.map2.get('map2-1'))); console.log(isObservable(this.map2)); console.log(isObservableMap(this.map2)); }; @action handleClick4 = () => { let status = !this.map2.get('map2-1'); this.map2.set('map2-1', status); }; @action handleClick5 = () => { let arr = this.map3.get('map3'); let key = 'map3-' + arr.length; arr.push({value: true, key:key}); console.log('------ this is map3------'); console.log(this.map3.keys()); console.log(isObservable(this.map3.get('map3'))); console.log(isObservable(this.map3.get('map3')[1])); console.log(isObservable(this.map3)); console.log(isObservableMap(this.map3)); }; @action handleClick6 = () => { let arr = this.map3.get('map3'); arr[1].value = ! arr[1].value; }; @action handleClick7 = () => { let arr = this.map4.get('map4'); let key = 'map4-' + arr.length; arr.push({value: true, key:key}); console.log('------ this is map4------'); console.log(this.map4.keys()); console.log(isObservable(this.map4.get('map4'))); console.log(isObservable(this.map4.get('map4')[1])); console.log(isObservable(this.map4)); console.log(isObservableMap(this.map4)); }; @action handleClick8 = () => { let arr = this.map4.get('map4'); arr[1].value = ! arr[1].value; }; render() { let arr = []; this.map1.forEach((value,key,map) => { if(value){ arr.push(
map1: {key}
); } }); let arr2 = []; this.map2.forEach((value,key,map) => { if(value) { arr2.push(
map3: {key}
); } }); let arr3 = []; this.map3.get('map3').forEach(item => { if(item.value) { arr3.push(
map3: {item.key}
); } }); let arr4 = []; this.map4.get('map4').forEach(item => { if(item.value) { arr4.push(
map4: {item.key}
); } }); return (
{arr}
{arr2}
{arr3}
{arr4}
\`\`\` `; let result = ` \`\`\`js class Store { @observable map1 = observable.map([ ['key1', 'value1'], ['key2', 'value2'], ]); @observable map2 = new Map([ ['key1', 'value1'], ['key2', 'value2'], ]); map3 = new Map([ ['key1', 'value1'], ['key2', 'value2'], ]); } const store = new Store(); console.log(Array.isArray(store.map1.values())) // true console.log(Array.isArray(store.map2.values())) // true console.log(Array.isArray(store.map3.values())) // false console.log(store.map1.keys(); // ['key1', 'key2'] console.log(store.map2.keys()); // ['key1', 'key2'] console.log(store.map3.keys()); // MapIterator {"key1", "key2"} values()方法类似keys()方法 测试结果表明,使用mobx的方式定义的map类型,通过values/keys方法返回的是一个数组, 而原生定义的map类型返回的是遍历器 \`\`\` `; @observer class P6 extends React.Component { @observable showResult = false; @observable map1 = observable.map(); @observable map2 = new Map(); @observable map3 = observable.map([ ['map3',[{value: true, key:'map3-0'}]] ]); @observable map4 = new Map([ ['map4',[{value: true, key:'map4-0'}]] ]); map5 = new Map([ ['key1', 'value1'], ['key2', 'value2'], ]); @action handleClick1 = () => { let key = 'map1-' + this.map1.size; this.map1.set(key, true); console.log('------ this is map1------'); console.log(this.map1.keys()); console.log(isObservable(this.map1.get('map1-1'))); console.log(isObservable(this.map1)); console.log(isObservableMap(this.map1)); console.log(this.map5); }; @action handleClick2 = () => { let status = !this.map1.get('map1-1'); this.map1.set('map1-1',status); }; @action handleClick3 = () => { let key = 'map2-' + this.map2.size ; this.map2.set(key, true); console.log('------ this is map2------'); console.log(this.map2.keys()); console.log(isObservable(this.map2.get('map2-1'))); console.log(isObservable(this.map2)); console.log(isObservableMap(this.map2)); }; @action handleClick4 = () => { let status = !this.map2.get('map2-1'); this.map2.set('map2-1', status); }; @action handleClick5 = () => { let arr = this.map3.get('map3'); let key = 'map3-' + arr.length; arr.push({value: true, key:key}); console.log('------ this is map3------'); console.log(this.map3.keys()); console.log(isObservable(this.map3.get('map3'))); console.log(isObservable(this.map3.get('map3')[1])); console.log(isObservable(this.map3)); console.log(isObservableMap(this.map3)); }; @action handleClick6 = () => { let arr = this.map3.get('map3'); arr[1].value = ! arr[1].value; }; @action handleClick7 = () => { let arr = this.map4.get('map4'); let key = 'map4-' + arr.length; arr.push({value: true, key:key}); console.log('------ this is map4------'); console.log(this.map4.keys()); console.log(isObservable(this.map4.get('map4'))); console.log(isObservable(this.map4.get('map4')[1])); console.log(isObservable(this.map4)); console.log(isObservableMap(this.map4)); }; @action handleClick8 = () => { let arr = this.map4.get('map4'); arr[1].value = ! arr[1].value; }; render() { let arr = []; this.map1.forEach((value,key,map) => { if(value){ arr.push(
map1: {key}
); } }); let arr2 = []; this.map2.forEach((value,key,map) => { if(value) { arr2.push(
map3: {key}
); } }); let arr3 = []; this.map3.get('map3').forEach(item => { if(item.value) { arr3.push(
map3: {item.key}
); } }); let arr4 = []; this.map4.get('map4').forEach(item => { if(item.value) { arr4.push(
map4: {item.key}
); } }); return (
this.showResult = !this.showResult}/>

maps

{arr}
{arr2}
{arr3}
{arr4}
); } } export default P6; ================================================ FILE: src/page-mobx/p7.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer, Observer, componentWillReact} from 'mobx-react' import Markdown from '../markdown' import { Table, Button, notification, Switch} from 'antd'; // import './css/p7.scss' let info = ` \`\`\`js import {observable, action} from 'mobx' import {observer, Observer, componentWillReact} from 'mobx-react' //@observer class Test extends React.Component \{ componentWillReact() { notification.info({message: '消息提示', description: 'This is componentWillReact'}); } componentWillReceiveProps(){ notification.error({message: '消息提示', description: 'This is componentWillReceiveProps'}); } componentDidUpdate(){ notification.warn({message: '消息提示', description: 'This is Test componentDidUpdate'}); } render() { return (
num1: {this.props.num1}
{() =>
num2: {this.props.num2}
}
num3: {this.props.num3.value}
{() =>
num4: {this.props.num4.value}
}
); } } //@observer class App extends React.Component { @observable num1 = 1; @observable num2 = 1; @observable num3 = { value: 1 }; @observable num4 = { value: 1 }; handleClick = () => { this.num1 = Math.random(); this.num2 = Math.random(); this.num3.value = Math.random(); this.num4.value = Math.random(); }; componentDidUpdate(){ notification.info({message: '消息提示', description: 'This is App componentDidUpdate'}); } render() { return (
); } } \`\`\` `; let result = ` \`\`\`js 1. App / Test 都不加 @observer - 只有num4的值变化了 2. 只有Test组件加了 @observer - num3 和 num4 的值发生了变化 - Test组件触发了componentWillReact / componentDidUpdate - 测试表明 num3导致了Test触发componentWillReact / componentDidUpdate 3. 只有App组件加了 @observer - num1 / num2 / num3 /num4 的值都改变了 - App组件触发了 componentDidUpdate - Test组件触发了 componentWillReceiveProps / componentDidUpdate 4. App / Test都加了@observer - num1 / num2 / num3 /num4 的值都改变了 - App组件触发了 componentDidUpdate - Test组件触发了 componentWillReact componentWillReceiveProps / componentDidUpdate ------------------------------------------------------- App re-render => Test componentWillReceiveProps componentWillReact的生效依赖于 @observer ------------------------------------------------------- 贴士与技巧: 在所有渲染 @observable 的组件上使用 @observer @observer 只会增强你正在装饰的组件,而不是内部使用了的组件。 所以通常你的所有组件都应该是装饰了的。但别担心,这样不会降低效率,相反 observer 组件越多,渲染效率越高 ------------------------------------------------------- MobX 可以做许多事,但是它无法将原始类型值转变成 observable 所以说值不是 observable,而对象的属性才是 永远只传递拥有 observable 属性的对象 \`\`\` `; //@observer class Test extends React.Component { componentWillReact() { notification.info({message: '消息提示', description: 'This is Test componentWillReact'}); } componentWillReceiveProps(){ notification.error({message: '消息提示', description: 'This is Test componentWillReceiveProps'}); } componentDidUpdate(){ notification.warn({message: '消息提示', description: 'This is Test componentDidUpdate'}); } render() { return (
num1: {this.props.num1}
{() =>
num2: {this.props.num2}
}
num3: {this.props.num3.value}
{() =>
num4: {this.props.num4.value}
}
); } } @observer class P7 extends React.Component { @observable showResult = false; @observable num1 = 1; @observable num2 = 1; @observable num3 = { value: 1 }; @observable num4 = { value: 1 }; handleClick = () => { this.num1 = Math.random(); this.num2 = Math.random(); this.num3.value = Math.random(); this.num4 = {value:12323} }; componentDidUpdate(){ notification.info({message: '消息提示', description: 'This is App componentDidUpdate'}); } render() { return (
this.showResult = !this.showResult}/>

Observer (mobx-react)

); } } export default P7; ================================================ FILE: src/page-mobx/p8.js ================================================ import React from 'react' import {observable, action, computed, extendObservable, toJS, isObservable} from 'mobx' import {observer, Observer, componentWillReact, inject, Provider} from 'mobx-react' import Markdown from '../markdown' import { Table, Badge, Button, notification, Switch} from 'antd'; //import './css/p8.scss' let info = ` \`\`\`js import {observable, action } from 'mobx' import {observer, inject, Provider} from 'mobx-react' @inject('color','count') class BadgeContainer extends React.Component { render() { return ( ); } } class Message extends React.Component { render() { return (
{this.props.text}
); } } @observer class App extends React.Component { messages = [ {text: '这是第一条消息'}, {text: '这是第二条消息'}, {text: '这是第三条消息'}, {text: '这是第四条消息'} ]; @observable color = '#87d068'; @observable count = 19; handleClick = () => { this.color = '#'+Math.floor(Math.random()*16777215).toString(16); this.count = Math.floor(Math.random()*100); }; render() { const children = this.messages.map((message,index) => ); return (
{children}
) } } \`\`\` `; let result = ` \`\`\`js 1. Provider is a component that can pass stores (or other stuff) using React's context mechanism to child components 2. inject can be used to pick up those stores 3. if your stores will change over time, like an observable value of another store, MobX will warn you. To suppress that warning explicitly, you can use suppressChangedStoreWarning={true} as a prop at your own risk. \`\`\` `; @inject('color','count') //@observer class BadgeContainer extends React.Component { componentWillReact() { notification.info({message: '消息提示', description: 'This is componentWillReact'}); } render() { return ( ); } } //@observer class Message extends React.Component { render() { return (
{this.props.text}
); } } @observer class P8 extends React.Component { @observable showResult = false; messages = [ {text: '这是第一条消息'}, {text: '这是第二条消息'}, {text: '这是第三条消息'}, {text: '这是第四条消息'} ]; @observable color = '#87d068'; @observable count = 19; handleClick = () => { this.color = '#'+Math.floor(Math.random()*16777215).toString(16); this.count = Math.floor(Math.random()*100); }; render() { const children = this.messages.map((message,index) => ); return (
this.showResult = !this.showResult}/>

Provider and inject

{children}
) } } export default P8; ================================================ FILE: src/page-mobx/p9.js ================================================ import React from 'react' import {observable, action, intercept, observe} from 'mobx' import {observer, componentWillReact} from 'mobx-react' import Markdown from '../markdown' import { Table, Input, notification, Switch} from 'antd'; let info = ` 参考资料:[Intercept & Observe](http://cn.mobx.js.org/refguide/observe.html) \`\`\`js import {observable, action, intercept, observe} from 'mobx' @observable style = { color:'' }; @action handleEnter = (e) => { this.style.color = e.target.value }; componentDidMount(){ this.disposer = intercept(this.style, 'color', change => { if (!change.newValue) { // 忽略取消设置背景颜色 notification.error({message: '错误提示', description: '颜色值不能为空'}); return null; } if (change.newValue.length === 6) { // 补全缺少的 '#' 前缀 change.newValue = '#' + change.newValue; notification.warn({message: '警告提示', description: '缺少#前缀'}); return change; } if (change.newValue.length === 7) { return change; } if (change.newValue.length > 10) this.disposer(); // 不再拦截今后的任何变化 notification.error({message: '错误提示', description: change.newValue + ' 不是一个合法的颜色值'}); }); this.disposer2 = observe(this.style, 'color', (change) => { notification.success({message: '颜色设置成功', description: \`更新类型:\${change.type}, 输入的值:\${change.newValue}, 旧的值:\${change.oldValue} \`}); }); } \`\`\` `; let result = ` \`\`\`js 1. intercept 可以在变化作用于 observable 之前监测和修改变化。 2. observe 允许你在 observable 变化之后拦截改变 3. intercept/observe 返回一个 disposer 函数,当调用时可以取消拦截器 4. autorun 通常是一个更强大的和更具声明性的 observe 替代品 5. 当 observe 被创建出来后就会对变化作出反应,而像 autorun 或 reaction 这样的反应, 当它们变得可用时,它们会对新值做出反应。在大多数情况下,后者就足够了 6. intercept 和 observe 的回调函数接收一个事件对象 \`\`\` `; @observer class P9 extends React.Component { @observable showResult = false; @observable style = { color:'' }; @action handleEnter = (e) => { this.style.color = e.target.value }; componentDidMount(){ this.disposer = intercept(this.style, 'color', change => { if (!change.newValue) { // 忽略取消设置背景颜色 notification.error({message: '错误提示', description: '颜色值不能为空'}); return null; } if (change.newValue.length === 6) { // 补全缺少的 '#' 前缀 change.newValue = '#' + change.newValue; notification.warn({message: '警告提示', description: '缺少#前缀'}); return change; } if (change.newValue.length === 7) { return change; } if (change.newValue.length > 10) this.disposer(); // 不再拦截今后的任何变化 notification.error({message: '错误提示', description: change.newValue + ' 不是一个合法的颜色值'}); }); this.disposer2 = observe(this.style, 'color', (change) => { notification.success({message: '颜色设置成功', description: `更新类型:${change.type}, 输入的值:${change.newValue}, 旧的值:${change.oldValue} `}); }); } render() { return (
this.showResult = !this.showResult}/>

intercept & observe(注意和 observer/ Observer的区别)

); } } export default P9; ================================================ FILE: src/page-mobx/routes.js ================================================ import React from 'react'; import {HashRouter as Router, Route, Switch} from 'react-router-dom' import Aside from './aside'; import P0 from './p0'; import P1 from './p1'; import P2 from './p2'; import P3 from './p3'; import P4 from './p4'; import P5 from './p5'; import P6 from './p6'; import P7 from './p7'; import P8 from './p8'; import P9 from './p9'; import P10 from './p10'; import Q1 from './Q/q1'; import Q2 from './Q/q2'; import Q3 from './Q/q3'; import Q4 from './Q/q4'; export default () => (
); ================================================ FILE: src/page-mobx/store6.js ================================================ import {observable, action,computed} from 'mobx' class store6 { @observable map3 = observable.map(); @observable map4 = new Map(); } export default new store6(); ================================================ FILE: src/page-mobx/style/app.styl ================================================ body { height: 100%; } h1 { text-align: center; } .app-wrap { height: 100vh; display: flex; flex-direction: column; } .app-content, .app-sidebar { overflow-y: scroll; padding: 2em; } .app-content { flex: 5; position: relative; } .app-sidebar { background: #ff6347; flex: 1; border-bottom: 1px solid #eee; text-align: center; padding-bottom: 0.5em; nav { font-family: 'Unica One', sans-serif; //text-transform: uppercase; letter-spacing: 1px; margin-bottom: 2rem; > a { display: block; color: #fff; text-decoration: none; padding: 1em; border: 1px solid #ff4726; border-top: 0; &:first-child { border-top: 1px solid #ff4726; } &:hover { background: #ff5537; } } .active { background: #ff5537; } } } @media (min-width: 800px) { .app-wrap { flex-direction: row; } .app-content { order: 2; } .app-sidebar { order: 1; } } ================================================ FILE: src/page-mobx/style/p0.styl ================================================ .p0 height: 100% display: flex justify-content: center flex-direction: column ================================================ FILE: src/page-mobx/style/p1.styl ================================================ #p1 { .node circle { cursor: pointer; fill: #fff; stroke: steelblue; stroke-width: 2px; } .node text { font-size: 16px; } .link { fill: none; stroke: #ccc; stroke-width: 1.5px; } } ================================================ FILE: src/page-mobx/style/p4.styl ================================================ .example { text-align: center; background: rgba(0,0,0,0.05); border-radius: 4px; margin-bottom: 20px; padding: 30px 50px; margin: 20px 0; span { } } ================================================ FILE: tool.js ================================================ #!/usr/bin/env node const fs = require('fs-extra') const yargs = require('yargs') const _ = require('lodash') const Metalsmith = require('metalsmith') const collections = require('metalsmith-collections') const minimatch = require('minimatch') const path = require('path') yargs .usage('$0 [args]') .option('page', { alias: 'p', desc: 'Page name', demand: false, type: 'string' }) // .option('force', { // alias: 'f', // desc: 'Force to overwrite existed page dir', // demand: false, // type: 'boolean' // }) .option('remove', { alias: 'r', desc: 'Remove page files', demand: false, type: 'boolean' }) .option('index', { alias: 'i', desc: 'Update index.html', demand: false, type: 'boolean' }) .help() const argv = yargs.argv // console.log(JSON.stringify(argv, null, 4)) if (argv.index) { updateIndexHtml() process.exit(0) } // 验证page参数 if (!argv.page) { console.log('Invalid value: ') process.exit(0) } const componentName = argv.page const metadata = { ComponentName: _.upperFirst(_.camelCase(componentName)), componentName: _.camelCase(componentName), 'component-name': _.kebabCase(componentName) } // 执行:删除页面文件 if (argv.remove) { removePage() // 执行:更新首页链接列表 updateIndexHtml() } // 执行:创建页面文件 else { createPage() // 执行:更新首页链接列表 updateIndexHtml() } // ========================== 以下的函数集合 ========================== // 删除页面文件 function removePage () { // 删除配置文件 fs.removeSync(`./page-config/${metadata['component-name']}.js`) // 删除页面文件 fs.removeSync(`./src/page-${metadata['component-name']}`) } // 创建页面级初始化文件 function createPage () { // 替换变量 function insertVariables(content) { content = content.replace(/<%ComponentName%>/g, metadata.ComponentName) content = content.replace(/<%componentName%>/g, metadata.componentName) content = content.replace(/<%component-name%>/g, metadata['component-name']) return content } // 创建对应的`page-config`文件 const content = fs.readFileSync('./_template/page-config.js', 'utf8') fs.writeFileSync(`./page-config/${metadata['component-name']}.js`, insertVariables(content), 'utf8') Metalsmith(__dirname) .metadata(metadata) .source(`./_template/page-dir`) .destination(`./src/page-${metadata['component-name']}`) .clean(true) // 是否先清除目录,不写这一行时默认为true .use(collections({ files: '*/*' })) .use(renameFileAndInsertVariables({ filesToRename: { pattern: '*.*', rename: function (name) { return createFileName(name, metadata) } } }, metadata)) .build(function (error) { if (error) { console.log('error: ' + error) } else { console.log(`success: page-${metadata['component-name']} was created.`) } }) } // 创建文件名 function createFileName(name, metadata) { return name.replace(/<%component-name%>/g, metadata['component-name']) } // 文件重命名 + 文件内容替换 function renameFileAndInsertVariables(options, metadata) { return function(files, metalsmith, done) { Object.keys(options).forEach(function(opt) { var matcher = minimatch.Minimatch(options[opt].pattern); Object.keys(files).forEach(function(file) { if (!matcher.match(file)) { return; } var rename = options[opt].rename; var renamedEntry = path.dirname(file) + '/'; if (typeof rename === 'function') { renamedEntry += rename(path.basename(file)); } else { renamedEntry += rename; } // 加入新的文件 files[renamedEntry] 是 node 的 file 对象 files[renamedEntry] = files[file]; var fileContent = fs.readFileSync(`./_template/page-dir/${file}`, 'utf8'); fileContent = fileContent.replace(/<%ComponentName%>/g, metadata.ComponentName); fileContent = fileContent.replace(/<%componentName%>/g, metadata.componentName); fileContent = fileContent.replace(/<%component-name%>/g, metadata['component-name']); files[renamedEntry].contents = fileContent; delete files[file]; }); }); done(); }; } function updateIndexHtml() { let content = fs.readFileSync('./index.html', 'utf8') const listStart = '' const listEnd = '' const pageConfigPath = path.join(__dirname, 'page-config') // 已经创建的页面名称 let pageNames = fs.readdirSync(pageConfigPath).map(function (item) { if (!fs.statSync(pageConfigPath + '/' + item).isFile()) { console.error(`Page config must be a file: "${pageConfigPath + '/' + item}" is not a file!`) process.exit(0) } return item.split('.')[0] }) // 过滤掉空的文件名 // 出现原因:系统自动生成.开头的隐藏文件 pageNames = _.filter(pageNames, function(pageName) { return !!pageName }) let newContent = pageNames.map(function(pageName) { return `` }) newContent.unshift(listStart) newContent.push(listEnd) content = content.replace(/<\!\-\-list\sstart\-\->[\s\S]*<\!\-\-list\send\-\->/, newContent.join('\n')) fs.writeFileSync('./index.html', content, 'utf8') } ================================================ FILE: webpack.config.js ================================================ const fs = require('fs'); const path = require("path"); const webpack = require("webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const ExtractTextPlugin = require("extract-text-webpack-plugin"); const pkg = require('./package.json') const _ = require('lodash') const HOST = "0.0.0.0"; const PORT = 3000; let commonPlugins = []; const isDev = process.env.NODE_ENV !== "production"; const pageBasePath = path.join(__dirname, 'page-base') const pageConfigPath = path.join(__dirname, 'page-config') // 要创建的页面名称 let pageNames = fs.readdirSync(pageConfigPath).map(function (item) { if (!fs.statSync(pageConfigPath + '/' + item).isFile()) { console.error(`Page config must be a file: "${pageConfigPath + '/' + item}" is not a file!`) process.exit(0) } return item.split('.')[0] }) // 过滤掉空的文件名 // 出现原因:系统自动生成.开头的隐藏文件 pageNames = _.filter(pageNames, function(pageName) { return !!pageName }) let entry = {}; pageNames.map(function (name) { entry[name] = [ path.join(__dirname, 'src', `page-${name}`, 'index.js') ] }); // 环境数据 const envData = { __DEV__: isDev, __PRODUCTION__: !isDev, }; const projectData = { __PUBLIC_PREFIX__: '//cdn.dtwave.com/public/', __PROJECT_PREFIX__: isDev ? '/' : '//cdn.dtwave.com/' + pkg.name + '/' + pkg.version + '/', __PROJECT_NAME__: pkg.name, __VERSION__: pkg.version } // 页面基础数据 let pageBaseData = require(path.join(pageBasePath, 'base')); pageBaseData = typeof pageBaseData === 'function' ? pageBaseData(envData, projectData) : pageBaseData; // process.exit(0) module.exports = { // https://webpack.js.org/configuration/dev-server/ devServer: { compress: true, inline: true, hot: true, port: PORT, host: HOST, open: true, headers: {'Access-Control-Allow-Origin': '*'}, noInfo: true }, entry: entry, output: { // path配置只在build时才有用到 path: path.join(__dirname, 'dist'), filename: "[name].js", chunkFilename: "[name].[chunkhash:6].chunk.js", // publicPath只是dev时用到 publicPath: '/', }, resolveLoader: { moduleExtensions: ["-loader"] }, module: { rules: [ { test: /\.css$/, use:['style','css'] }, { test: /\.js$/, use: ["babel?cacheDirectory"], // use: ["babel", "eslint"], include: path.join(__dirname, 'src') }, { test: /\.styl$/, use: ExtractTextPlugin.extract({ fallback: "style", use: ["css", "postcss", "stylus"], }), exclude: /node_modules/, }, { test: /\.json$/, use: ['json'] } // { // test: /\.(jpg|jpeg|png|gif|svg)$/, // use: ['file'], // query: { // name: '[name].[hash:8].[ext]' // } // } ] }, plugins: [ // 从多个模块中提取共用的模块到common.js // https://webpack.js.org/plugins/commons-chunk-plugin/#commons-chunk-for-entries new webpack.optimize.CommonsChunkPlugin({ name: "common", filename: "common.js" }), new webpack.DefinePlugin(envData), new ExtractTextPlugin('[name].css') ].concat((function () { return pageNames.map(function (pageName) { // console.log('privatePageData', path.join(pageConfigPath, pageName)) // 页面私有数据 let privatePageData = require(path.join(pageConfigPath, pageName)); privatePageData = typeof privatePageData === 'function' ? privatePageData(envData, projectData, pageBaseData) : privatePageData; // https://github.com/jantimon/html-webpack-plugin#configuration return new HtmlWebpackPlugin(Object.assign( { // NOTE 不允许配置成绝对路径 `filename`是相对于`webpack`的`output.path`(build时)和`output.publicPath`(dev时)值的 filename: isDev ? pageName+'.html' : 'html/' + pageName + '.html', // NOTE 不允许配置成绝对路径 `template`是相对于`webpack`的`resolve.root`值的 template: 'page-base/base.html', // 页面自己决定如何插入 inject: false, pageName: pageName }, envData, projectData, pageBaseData, privatePageData )) }); })()), externals: { 'react': 'var React', 'react-dom': 'var ReactDOM', 'mobx': 'var mobx', 'mobx-react': 'var mobxReact', '_': 'var _', 'antd': 'var antd', } }; if (!isDev) { commonPlugins = [ // new HtmlWebpackPlugin({ // filename: "index.html", // template: "wwwindex.html", // inject: true, // hash: true, // minify: { // removeComments: true, // // collapseWhitespace: true, // removeAttributeQuotes: true, // // minifyJS: true, // minifyCSS: true, // minifyURLs: true, // } // }), // 是否压缩JS 如果不压缩 需要全部注释掉 new webpack.optimize.UglifyJsPlugin({ sourceMap: true, output: false, compress: { unused: true, dead_code: true, pure_getters: true, warnings: false, screw_ie8: true, conditionals: true, comparisons: true, sequences: true, evaluate: true, join_vars: true, if_return: true, }, }), new webpack.LoaderOptionsPlugin({ minimize: true, debug: false, quiet: true, }), ]; } else { commonPlugins = [ new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), // new webpack.LoaderOptionsPlugin({ // debug: true, // options: { // eslint: { // configFile: './.eslintrc', // }, // } // }), ]; module.exports.devtool = "source-map"; } module.exports.plugins = module.exports.plugins.concat(commonPlugins);