Removed react dependencies
This commit is contained in:
		
							parent
							
								
									aa67cb955b
								
							
						
					
					
						commit
						1d268d474c
					
				| 
						 | 
				
			
			@ -1,18 +1,12 @@
 | 
			
		|||
{
 | 
			
		||||
  "name": "probExample",
 | 
			
		||||
  "reason": {
 | 
			
		||||
    "react-jsx": 3
 | 
			
		||||
  },
 | 
			
		||||
  "sources": [
 | 
			
		||||
    {
 | 
			
		||||
      "dir": "src",
 | 
			
		||||
      "subdirs": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "dir": "showcase",
 | 
			
		||||
      "type": "dev",
 | 
			
		||||
      "subdirs": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "dir": "__tests__",
 | 
			
		||||
      "type": "dev",
 | 
			
		||||
| 
						 | 
				
			
			@ -35,19 +29,13 @@
 | 
			
		|||
  "bs-dependencies": [
 | 
			
		||||
    "@glennsl/bs-jest",
 | 
			
		||||
    "@glennsl/bs-json",
 | 
			
		||||
    "@rescriptbr/reform",
 | 
			
		||||
    "@rescript/react",
 | 
			
		||||
    "bs-css",
 | 
			
		||||
    "bs-css-dom",
 | 
			
		||||
    "rationale",
 | 
			
		||||
    "bs-moment",
 | 
			
		||||
    "reschema"
 | 
			
		||||
    "bs-moment"
 | 
			
		||||
  ],
 | 
			
		||||
  "refmt": 3,
 | 
			
		||||
  "warnings": {
 | 
			
		||||
    "number": "+A-42-48-9-30-4-102"
 | 
			
		||||
  },
 | 
			
		||||
  "ppx-flags": [
 | 
			
		||||
    "lenses-ppx/ppx"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
# Squiggle
 | 
			
		||||
 | 
			
		||||
Squiggle is a DSL for making probabilistic estimations. It is meant
 | 
			
		||||
to be a programming analogue of the [Guesstimate](https://www.getguesstimate.com/)
 | 
			
		||||
application.
 | 
			
		||||
 | 
			
		||||
There are several use cases for a language that represent uncertainty. Some include
 | 
			
		||||
writing cost effectiveness analysis, as well as doing accurate forecasting.
 | 
			
		||||
 | 
			
		||||
Squiggle is written in [Rescript](https://rescript-lang.org/) and is presented
 | 
			
		||||
as a website.
 | 
			
		||||
 | 
			
		||||
If you wish to try squiggle out, you can visit our [main page](https://squiggle-language.com/).
 | 
			
		||||
 | 
			
		||||
## Syntax
 | 
			
		||||
We use the [Math.js expression language](https://mathjs.org/index.html) for Squiggle.
 | 
			
		||||
So any expression that's available on Math.js is supported on Squiggle.
 | 
			
		||||
 | 
			
		||||
To represent uncertainty, we use a custom DSL called [DistML](https://docs.google.com/document/d/1xlEC8KjchP4PL-KdSxfBJr0UZ9nVMSAlz-rjAQEinyA/edit#).
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
To contribute to this project, we recommend visiting our [Contributing Guide](contributing.md).
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="UTF-8">
 | 
			
		||||
  <title>Squiggle Documentation</title>
 | 
			
		||||
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
 | 
			
		||||
  <meta name="description" content="Description">
 | 
			
		||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
 | 
			
		||||
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <div id="app"></div>
 | 
			
		||||
  <script>
 | 
			
		||||
    window.$docsify = {
 | 
			
		||||
      name: 'Squiggle',
 | 
			
		||||
      repo: 'foretold-app/squiggle',
 | 
			
		||||
      loadSidebar: true
 | 
			
		||||
    }
 | 
			
		||||
  </script>
 | 
			
		||||
  <!-- Docsify v4 -->
 | 
			
		||||
  <script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
 | 
			
		||||
  <!-- CDN files for docsify-katex -->
 | 
			
		||||
  <script src="//cdn.jsdelivr.net/npm/docsify-katex@latest/dist/docsify-katex.js"></script>
 | 
			
		||||
  <!-- or <script src="//cdn.jsdelivr.net/gh/upupming/docsify-katex@latest/dist/docsify-katex.js"></script> -->
 | 
			
		||||
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css"/>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
{
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "docsify-cli": "^4.4.3"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1323
									
								
								docs/yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										1323
									
								
								docs/yarn.lock
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
[[redirects]]
 | 
			
		||||
  from = "/*"
 | 
			
		||||
  to = "/index.html"
 | 
			
		||||
  status = 200
 | 
			
		||||
							
								
								
									
										25
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								package.json
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -27,44 +27,21 @@
 | 
			
		|||
  "license": "MIT",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@glennsl/bs-json": "^5.0.2",
 | 
			
		||||
    "@rescript/react": "^0.10.3",
 | 
			
		||||
    "@rescriptbr/reform": "^11.0.1",
 | 
			
		||||
    "ace-builds": "^1.4.12",
 | 
			
		||||
    "antd": "^4.18.5",
 | 
			
		||||
    "autoprefixer": "9.8.8",
 | 
			
		||||
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
 | 
			
		||||
    "binary-search-tree": "0.2.6",
 | 
			
		||||
    "bs-ant-design-alt": "2.0.0-alpha.33",
 | 
			
		||||
    "bs-css": "^15.1.0",
 | 
			
		||||
    "bs-css-dom": "^3.1.0",
 | 
			
		||||
    "bs-moment": "0.6.0",
 | 
			
		||||
    "bs-reform": "^10.0.3",
 | 
			
		||||
    "bsb-js": "1.1.7",
 | 
			
		||||
    "d3": "7.3.0",
 | 
			
		||||
    "gh-pages": "2.2.0",
 | 
			
		||||
    "jest": "^25.5.1",
 | 
			
		||||
    "jstat": "1.9.2",
 | 
			
		||||
    "lenses-ppx": "5.1.0",
 | 
			
		||||
    "less": "3.10.3",
 | 
			
		||||
    "lodash": "4.17.15",
 | 
			
		||||
    "mathjs": "5.10.3",
 | 
			
		||||
    "moduleserve": "0.9.1",
 | 
			
		||||
    "moment": "2.24.0",
 | 
			
		||||
    "pdfast": "^0.2.0",
 | 
			
		||||
    "postcss-cli": "7.1.0",
 | 
			
		||||
    "rationale": "0.2.0",
 | 
			
		||||
    "react": "^16.10.0",
 | 
			
		||||
    "react-ace": "^9.2.0",
 | 
			
		||||
    "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0",
 | 
			
		||||
    "react-use": "^17.3.2",
 | 
			
		||||
    "react-vega": "^7.4.4",
 | 
			
		||||
    "reason-react": ">=0.7.0",
 | 
			
		||||
    "reschema": "^2.2.0",
 | 
			
		||||
    "rescript": "^9.1.4",
 | 
			
		||||
    "tailwindcss": "1.2.0",
 | 
			
		||||
    "vega": "*",
 | 
			
		||||
    "vega-embed": "6.6.0",
 | 
			
		||||
    "vega-lite": "*"
 | 
			
		||||
    "rescript": "^9.1.4"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@glennsl/bs-jest": "^0.5.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
let entries = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -1,30 +0,0 @@
 | 
			
		|||
type compEntry = {
 | 
			
		||||
  mutable id: string,
 | 
			
		||||
  title: string,
 | 
			
		||||
  render: unit => React.element,
 | 
			
		||||
  container: containerType,
 | 
			
		||||
}
 | 
			
		||||
and folderEntry = {
 | 
			
		||||
  mutable id: string,
 | 
			
		||||
  title: string,
 | 
			
		||||
  children: list(navEntry),
 | 
			
		||||
}
 | 
			
		||||
and navEntry =
 | 
			
		||||
  | CompEntry(compEntry)
 | 
			
		||||
  | FolderEntry(folderEntry)
 | 
			
		||||
and containerType =
 | 
			
		||||
  | FullWidth
 | 
			
		||||
  | Sidebar;
 | 
			
		||||
 | 
			
		||||
let entry = (~title, ~render): navEntry => {
 | 
			
		||||
  CompEntry({id: "", title, render, container: FullWidth});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Maybe different api, this avoids breaking changes
 | 
			
		||||
let sidebar = (~title, ~render): navEntry => {
 | 
			
		||||
  CompEntry({id: "", title, render, container: Sidebar});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let folder = (~title, ~children): navEntry => {
 | 
			
		||||
  FolderEntry({id: "", title, children});
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										163
									
								
								showcase/Lib.res
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								showcase/Lib.res
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,163 +0,0 @@
 | 
			
		|||
open EntryTypes
 | 
			
		||||
 | 
			
		||||
module HS = Belt.HashMap.String
 | 
			
		||||
 | 
			
		||||
let entriesByPath: HS.t<navEntry> = HS.make(~hintSize=100)
 | 
			
		||||
 | 
			
		||||
/* Creates unique id's per scope based on title */
 | 
			
		||||
let buildIds = entries => {
 | 
			
		||||
  let genId = (title, path) => {
 | 
			
		||||
    let noSpaces = Js.String.replaceByRe(%re("/\\s+/g"), "-", title)
 | 
			
		||||
    if !HS.has(entriesByPath, path ++ ("/" ++ noSpaces)) {
 | 
			
		||||
      noSpaces
 | 
			
		||||
    } else {
 | 
			
		||||
      let rec loop = num => {
 | 
			
		||||
        let testId = noSpaces ++ ("-" ++ string_of_int(num))
 | 
			
		||||
        if !HS.has(entriesByPath, path ++ ("/" ++ testId)) {
 | 
			
		||||
          testId
 | 
			
		||||
        } else {
 | 
			
		||||
          loop(num + 1)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      loop(2)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  let rec processFolder = (f: folderEntry, curPath) => {
 | 
			
		||||
    f.id = curPath ++ ("/" ++ genId(f.title, curPath))
 | 
			
		||||
    HS.set(entriesByPath, f.id, FolderEntry(f))
 | 
			
		||||
    f.children |> E.L.iter(x =>
 | 
			
		||||
      switch x {
 | 
			
		||||
      | CompEntry(c) => processEntry(c, f.id)
 | 
			
		||||
      | FolderEntry(f) => processFolder(f, f.id)
 | 
			
		||||
      }
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
  and processEntry = (c: compEntry, curPath) => {
 | 
			
		||||
    c.id = curPath ++ ("/" ++ genId(c.title, curPath))
 | 
			
		||||
    HS.set(entriesByPath, c.id, CompEntry(c))
 | 
			
		||||
  }
 | 
			
		||||
  entries |> E.L.iter(x =>
 | 
			
		||||
    switch x {
 | 
			
		||||
    | CompEntry(c) => processEntry(c, "")
 | 
			
		||||
    | FolderEntry(f) => processFolder(f, "")
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let entries = Entries.entries
 | 
			
		||||
buildIds(entries)
 | 
			
		||||
 | 
			
		||||
module Styles = {
 | 
			
		||||
  open CssJs
 | 
			
		||||
  let pageContainer = style(. [ display(#flex), height(#vh(100.)) ])
 | 
			
		||||
  let leftNav = style(. [ padding(#em(2.)),
 | 
			
		||||
  flexBasis(#px(200)),
 | 
			
		||||
  flexShrink(0.),
 | 
			
		||||
  backgroundColor(#hex("eaeff3")),
 | 
			
		||||
  boxShadows([ Shadow.box(~x=px(-1), ~blur=px(1), ~inset=true, rgba(0, 0, 0, #percent(0.1))) ]),
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
let folderNav = style(. [ selector(.
 | 
			
		||||
  ">h4",
 | 
			
		||||
  [ cursor(#pointer), margin2(~v=#em(0.3), ~h=#zero), hover([ color(#hex("7089ad")) ]) ],
 | 
			
		||||
),
 | 
			
		||||
 ])
 | 
			
		||||
  let folderChildren = style(. [ paddingLeft(#px(7)) ])
 | 
			
		||||
  let compNav = style(. [ cursor(#pointer),
 | 
			
		||||
  paddingBottom(#px(3)),
 | 
			
		||||
  hover([ color(#hex("7089ad")) ]),
 | 
			
		||||
])
 | 
			
		||||
  let compContainer = style(. [ padding(#em(2.)), flexGrow(1.) ])
 | 
			
		||||
  // Approximate sidebar container for entry
 | 
			
		||||
  let sidebarContainer = style(. [ maxWidth(#px(430)) ])
 | 
			
		||||
  let folderChildContainer = style(. [ marginBottom(#em(2.)) ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let baseUrl = "/showcase/index.html"
 | 
			
		||||
 | 
			
		||||
module Index = {
 | 
			
		||||
  type state = {route: RescriptReactRouter.url}
 | 
			
		||||
 | 
			
		||||
  type action =
 | 
			
		||||
    | ItemClick(string)
 | 
			
		||||
    | ChangeRoute(RescriptReactRouter.url)
 | 
			
		||||
 | 
			
		||||
  let changeId = (id: string) => {
 | 
			
		||||
    let _ = RescriptReactRouter.push(baseUrl ++ ("#" ++ id))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let buildNav = _ => {
 | 
			
		||||
    let rec buildFolder = (f: folderEntry) =>
 | 
			
		||||
      <div key=f.id style=Styles.folderNav>
 | 
			
		||||
        <h4 onClick={_e => changeId(f.id)}> {f.title->React.string} </h4>
 | 
			
		||||
        <div style=Styles.folderChildren>
 | 
			
		||||
          {(f.children
 | 
			
		||||
          |> E.L.fmap(e =>
 | 
			
		||||
            switch e {
 | 
			
		||||
            | FolderEntry(folder) => buildFolder(folder)
 | 
			
		||||
            | CompEntry(entry) => buildEntry(entry)
 | 
			
		||||
            }
 | 
			
		||||
          )
 | 
			
		||||
          |> E.L.toArray)->React.array}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    and buildEntry = (e: compEntry) =>
 | 
			
		||||
      <div key=e.id style=Styles.compNav onClick={_e => changeId(e.id)}>
 | 
			
		||||
        {e.title->React.string}
 | 
			
		||||
      </div>
 | 
			
		||||
    (entries
 | 
			
		||||
    |> E.L.fmap(e =>
 | 
			
		||||
      switch e {
 | 
			
		||||
      | FolderEntry(folder) => buildFolder(folder)
 | 
			
		||||
      | CompEntry(entry) => buildEntry(entry)
 | 
			
		||||
      }
 | 
			
		||||
    )
 | 
			
		||||
    |> E.L.toArray)->React.array
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let renderEntry = e =>
 | 
			
		||||
    switch e.container {
 | 
			
		||||
    | FullWidth => e.render()
 | 
			
		||||
    | Sidebar => <div style=Styles.sidebarContainer> {e.render()} </div>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = () => {
 | 
			
		||||
    let (route, setRoute) = React.useState(() => {
 | 
			
		||||
      let url: RescriptReactRouter.url = {path: list{}, hash: "", search: ""}
 | 
			
		||||
      url
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    React.useState(() => {
 | 
			
		||||
      let _ = RescriptReactRouter.watchUrl(url => setRoute(_ => url))
 | 
			
		||||
    }) |> ignore
 | 
			
		||||
 | 
			
		||||
    <div style=Styles.pageContainer>
 | 
			
		||||
      <div style=Styles.leftNav> {buildNav(setRoute)} </div>
 | 
			
		||||
      <div style=Styles.compContainer>
 | 
			
		||||
        {if route.hash == "" {
 | 
			
		||||
          React.null
 | 
			
		||||
        } else {
 | 
			
		||||
          switch HS.get(entriesByPath, route.hash) {
 | 
			
		||||
          | Some(navEntry) =>
 | 
			
		||||
            switch navEntry {
 | 
			
		||||
            | CompEntry(c) => renderEntry(c)
 | 
			
		||||
            | FolderEntry(f) =>
 | 
			
		||||
              /* Rendering immediate children */
 | 
			
		||||
              (f.children
 | 
			
		||||
              |> E.L.fmap(child =>
 | 
			
		||||
                switch child {
 | 
			
		||||
                | CompEntry(c) =>
 | 
			
		||||
                  <div style=Styles.folderChildContainer key=c.id> {renderEntry(c)} </div>
 | 
			
		||||
                | _ => React.null
 | 
			
		||||
                }
 | 
			
		||||
              )
 | 
			
		||||
              |> E.L.toArray)->React.array
 | 
			
		||||
            }
 | 
			
		||||
          | None => <div> {"Component not found"->React.string} </div>
 | 
			
		||||
          }
 | 
			
		||||
        }}
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
switch(ReactDOM.querySelector("main")){
 | 
			
		||||
| Some(root) => ReactDOM.render(<div> <Lib.Index /> </div>, root)
 | 
			
		||||
| None => () // do nothing
 | 
			
		||||
}
 | 
			
		||||
RescriptReactRouter.push("")
 | 
			
		||||
| 
						 | 
				
			
			@ -1,24 +0,0 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,900" rel="stylesheet">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,900" rel="stylesheet">
 | 
			
		||||
    <link href="../src/styles/index.css" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
    <title>Showcase</title>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="main"></div>
 | 
			
		||||
    <script src=" ./ShowcaseIndex.bs.js "></script>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
module Input = Antd_Input
 | 
			
		||||
module Grid = Antd_Grid
 | 
			
		||||
module Form = Antd_Form
 | 
			
		||||
module Card = Antd_Card
 | 
			
		||||
module Button = Antd_Button
 | 
			
		||||
module IconName = Antd_IconName
 | 
			
		||||
| 
						 | 
				
			
			@ -1,38 +0,0 @@
 | 
			
		|||
 | 
			
		||||
@deriving(abstract)
 | 
			
		||||
type props
 | 
			
		||||
type makeType = props => React.element
 | 
			
		||||
 | 
			
		||||
@obj external makeProps:
 | 
			
		||||
    (
 | 
			
		||||
  ~disabled: bool=?,
 | 
			
		||||
  ~ghost: bool=?,
 | 
			
		||||
  ~href: string=?,
 | 
			
		||||
  ~htmlType: @string [#button | #submit | #submit]=?,
 | 
			
		||||
  ~icon: 'a=?,
 | 
			
		||||
  ~shape: @string [#circle | #round]=?,
 | 
			
		||||
  ~size: @string [#small | #large]=?,
 | 
			
		||||
  ~target: string=?,
 | 
			
		||||
  ~loading: bool=?,
 | 
			
		||||
  ~_type: @string
 | 
			
		||||
  [
 | 
			
		||||
    | #primary
 | 
			
		||||
    | #default
 | 
			
		||||
    | #dashed
 | 
			
		||||
    | #danger
 | 
			
		||||
    | #link
 | 
			
		||||
    | #ghost
 | 
			
		||||
  ]=?,
 | 
			
		||||
  ~onClick: ReactEvent.Mouse.t => unit=?,
 | 
			
		||||
  ~block: bool=?,
 | 
			
		||||
  ~children: React.element=?,
 | 
			
		||||
  ~className: string=?,
 | 
			
		||||
  ~id: string=?,
 | 
			
		||||
  ~testId: string=?,
 | 
			
		||||
  unit
 | 
			
		||||
    ) =>
 | 
			
		||||
    props =
 | 
			
		||||
    ""
 | 
			
		||||
 | 
			
		||||
@module("antd")
 | 
			
		||||
external make : makeType = "Button"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,32 +0,0 @@
 | 
			
		|||
 | 
			
		||||
@deriving(abstract)
 | 
			
		||||
type props
 | 
			
		||||
type makeType = props => React.element
 | 
			
		||||
 | 
			
		||||
@obj external makeProps: (
 | 
			
		||||
    ~actions: array<React.element>=?,
 | 
			
		||||
    ~activeTabKey: string=?,
 | 
			
		||||
    ~headStyle: ReactDOMStyle.t=?,
 | 
			
		||||
    ~bodyStyle: ReactDOMStyle.t=?,
 | 
			
		||||
    ~style: ReactDOMStyle.t=?,
 | 
			
		||||
    ~bordered: bool=?,
 | 
			
		||||
    ~cover: React.element=?,
 | 
			
		||||
    ~defaultActiveTabKey: string=?,
 | 
			
		||||
    ~extra: React.element=?,
 | 
			
		||||
    ~hoverable: bool=?,
 | 
			
		||||
    ~loading: bool=?,
 | 
			
		||||
    ~tabList: array<{
 | 
			
		||||
                "key": string,
 | 
			
		||||
                "tab": React.element,
 | 
			
		||||
              }>
 | 
			
		||||
                =?,
 | 
			
		||||
    ~size: @string [ #default | #small]=?,
 | 
			
		||||
    ~title: 'a=?,
 | 
			
		||||
    ~_type: string=?,
 | 
			
		||||
    ~onTabChange: string => unit=?,
 | 
			
		||||
    ~children: React.element=?,
 | 
			
		||||
    unit // This unit is a quirk of the type system. Apparently it must exist to have optional arguments in a type
 | 
			
		||||
  ) => props = "" 
 | 
			
		||||
 | 
			
		||||
@module("antd")
 | 
			
		||||
external make : makeType = "Card"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
 | 
			
		||||
@deriving(abstract)
 | 
			
		||||
type props
 | 
			
		||||
type makeType = props => React.element
 | 
			
		||||
 | 
			
		||||
@obj 
 | 
			
		||||
external makeProps:
 | 
			
		||||
  (
 | 
			
		||||
    ~onSubmit: ReactEvent.Form.t => unit=?,
 | 
			
		||||
    ~hideRequiredMark: bool=?,
 | 
			
		||||
    ~id: string=?,
 | 
			
		||||
    ~className: string=?,
 | 
			
		||||
    ~style: ReactDOMStyle.t=?,
 | 
			
		||||
    ~colon: bool=?,
 | 
			
		||||
    ~validateStatus: string=?,
 | 
			
		||||
    ~extra: string=?,
 | 
			
		||||
    ~required: bool=?,
 | 
			
		||||
    ~label: string=?,
 | 
			
		||||
    ~help: string=?,
 | 
			
		||||
    ~hasFeedback: bool=?,
 | 
			
		||||
    ~children:React.element=?,
 | 
			
		||||
    unit
 | 
			
		||||
  ) =>
 | 
			
		||||
  props =
 | 
			
		||||
  ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@module("antd")
 | 
			
		||||
external make : makeType = "Form"
 | 
			
		||||
 | 
			
		||||
module Item = {
 | 
			
		||||
  type props
 | 
			
		||||
  type makeType = props => React.element
 | 
			
		||||
  @obj 
 | 
			
		||||
  external makeProps:
 | 
			
		||||
      (
 | 
			
		||||
        ~colon:string=?,
 | 
			
		||||
        ~validateStatus:string=?,
 | 
			
		||||
        ~extra:string=?,
 | 
			
		||||
        ~className:string=?,
 | 
			
		||||
        ~required:bool=?,
 | 
			
		||||
        ~style:ReactDOMStyle.t=?,
 | 
			
		||||
        ~label:string=?,
 | 
			
		||||
        ~id:string=?,
 | 
			
		||||
        ~help:string=?,
 | 
			
		||||
        ~hasFeedback:bool=?,
 | 
			
		||||
        ~children:React.element=?,
 | 
			
		||||
        unit
 | 
			
		||||
      ) => props = ""
 | 
			
		||||
  @module("antd")
 | 
			
		||||
  external make : makeType = "Form.Item"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,58 +0,0 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
module Row = {
 | 
			
		||||
  type props
 | 
			
		||||
 | 
			
		||||
  @obj
 | 
			
		||||
  external makeProps:
 | 
			
		||||
    (
 | 
			
		||||
      ~className: string=?,
 | 
			
		||||
      ~_type: string=?,
 | 
			
		||||
      ~align: string=?,
 | 
			
		||||
      ~justify: string=?,
 | 
			
		||||
      ~gutter: 'a=?,
 | 
			
		||||
      ~style: ReactDOMStyle.t=?,
 | 
			
		||||
      ~prefixCls: string=?,
 | 
			
		||||
      ~children: React.element=?,
 | 
			
		||||
      unit
 | 
			
		||||
    ) =>
 | 
			
		||||
    props =
 | 
			
		||||
    "";
 | 
			
		||||
 | 
			
		||||
  type makeType = props => React.element
 | 
			
		||||
 | 
			
		||||
  @module("antd")
 | 
			
		||||
  external make : makeType = "Row"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module Col = {
 | 
			
		||||
  type props
 | 
			
		||||
 | 
			
		||||
  @obj
 | 
			
		||||
  external makeProps:
 | 
			
		||||
    (
 | 
			
		||||
      ~className: string=?,
 | 
			
		||||
      ~span: int=?,
 | 
			
		||||
      ~order: int=?,
 | 
			
		||||
      ~offset: int=?,
 | 
			
		||||
      ~push: int=?,
 | 
			
		||||
      ~pull: int=?,
 | 
			
		||||
      ~xs: 'a=?,
 | 
			
		||||
      ~sm: 'b=?,
 | 
			
		||||
      ~md: 'c=?,
 | 
			
		||||
      ~lg: 'd=?,
 | 
			
		||||
      ~xl: 'e=?,
 | 
			
		||||
      ~xxl: 'f=?,
 | 
			
		||||
      ~prefixCls: string=?,
 | 
			
		||||
      ~style: ReactDOMStyle.t=?,
 | 
			
		||||
      ~children: React.element=?,
 | 
			
		||||
      unit
 | 
			
		||||
    ) =>
 | 
			
		||||
    props =
 | 
			
		||||
    "";
 | 
			
		||||
 | 
			
		||||
  type makeType = props => React.element
 | 
			
		||||
 | 
			
		||||
  @module("antd")
 | 
			
		||||
  external make : makeType = "Col"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,581 +0,0 @@
 | 
			
		|||
type t = string
 | 
			
		||||
 | 
			
		||||
let toString = t => t
 | 
			
		||||
 | 
			
		||||
let fromString = t => t
 | 
			
		||||
 | 
			
		||||
let compare = (t1, t2) => t1 == t2
 | 
			
		||||
 | 
			
		||||
let stepBackward = "step-backward"
 | 
			
		||||
 | 
			
		||||
let stepForward = "step-forward"
 | 
			
		||||
 | 
			
		||||
let fastBackward = "fast-backward"
 | 
			
		||||
 | 
			
		||||
let fastForward = "fast-forward"
 | 
			
		||||
 | 
			
		||||
let shrink = "shrink"
 | 
			
		||||
 | 
			
		||||
let arrowsAlt = "arrows-alt"
 | 
			
		||||
 | 
			
		||||
let down = "down"
 | 
			
		||||
 | 
			
		||||
let up = "up"
 | 
			
		||||
 | 
			
		||||
let left = "left"
 | 
			
		||||
 | 
			
		||||
let right = "right"
 | 
			
		||||
 | 
			
		||||
let caretUp = "caret-up"
 | 
			
		||||
 | 
			
		||||
let caretDown = "caret-down"
 | 
			
		||||
 | 
			
		||||
let caretLeft = "caret-left"
 | 
			
		||||
 | 
			
		||||
let caretRight = "caret-right"
 | 
			
		||||
 | 
			
		||||
let upCircle = "up-circle"
 | 
			
		||||
 | 
			
		||||
let downCircle = "down-circle"
 | 
			
		||||
 | 
			
		||||
let leftCircle = "left-circle"
 | 
			
		||||
 | 
			
		||||
let rightCircle = "right-circle"
 | 
			
		||||
 | 
			
		||||
let upCircleO = "up-circle-o"
 | 
			
		||||
 | 
			
		||||
let downCircleO = "down-circle-o"
 | 
			
		||||
 | 
			
		||||
let rightCircleO = "right-circle-o"
 | 
			
		||||
 | 
			
		||||
let leftCircleO = "left-circle-o"
 | 
			
		||||
 | 
			
		||||
let doubleRight = "double-right"
 | 
			
		||||
 | 
			
		||||
let doubleLeft = "double-left"
 | 
			
		||||
 | 
			
		||||
let verticleLeft = "verticle-left"
 | 
			
		||||
 | 
			
		||||
let verticleRight = "verticle-right"
 | 
			
		||||
 | 
			
		||||
let forward = "forward"
 | 
			
		||||
 | 
			
		||||
let backward = "backward"
 | 
			
		||||
 | 
			
		||||
let rollback = "rollback"
 | 
			
		||||
 | 
			
		||||
let enter = "enter"
 | 
			
		||||
 | 
			
		||||
let retweet = "retweet"
 | 
			
		||||
 | 
			
		||||
let swap = "swap"
 | 
			
		||||
 | 
			
		||||
let swapLeft = "swap-left"
 | 
			
		||||
 | 
			
		||||
let swapRight = "swap-right"
 | 
			
		||||
 | 
			
		||||
let arrowUp = "arrow-up"
 | 
			
		||||
 | 
			
		||||
let arrowDown = "arrow-down"
 | 
			
		||||
 | 
			
		||||
let arrowLeft = "arrow-left"
 | 
			
		||||
 | 
			
		||||
let arrowRight = "arrow-right"
 | 
			
		||||
 | 
			
		||||
let playCircle = "play-circle"
 | 
			
		||||
 | 
			
		||||
let playCircleO = "play-circle-o"
 | 
			
		||||
 | 
			
		||||
let upSquare = "up-square"
 | 
			
		||||
 | 
			
		||||
let downSquare = "down-square"
 | 
			
		||||
 | 
			
		||||
let leftSquare = "left-square"
 | 
			
		||||
 | 
			
		||||
let rightSquare = "right-square"
 | 
			
		||||
 | 
			
		||||
let upSquareO = "up-square-o"
 | 
			
		||||
 | 
			
		||||
let downSquareO = "down-square-o"
 | 
			
		||||
 | 
			
		||||
let leftSquareO = "left-square-o"
 | 
			
		||||
 | 
			
		||||
let rightSquareO = "right-square-o"
 | 
			
		||||
 | 
			
		||||
let login = "login"
 | 
			
		||||
 | 
			
		||||
let logout = "logout"
 | 
			
		||||
 | 
			
		||||
let menuFold = "menu-fold"
 | 
			
		||||
 | 
			
		||||
let menuUnfold = "menu-unfold"
 | 
			
		||||
 | 
			
		||||
let question = "question"
 | 
			
		||||
 | 
			
		||||
let questionCircleO = "question-circle-o"
 | 
			
		||||
 | 
			
		||||
let questionCircle = "question-circle"
 | 
			
		||||
 | 
			
		||||
let plus = "plus"
 | 
			
		||||
 | 
			
		||||
let plusCircleO = "plus-circle-o"
 | 
			
		||||
 | 
			
		||||
let plusCircle = "plus-circle"
 | 
			
		||||
 | 
			
		||||
let pause = "pause"
 | 
			
		||||
 | 
			
		||||
let pauseCircleO = "pause-circle-o"
 | 
			
		||||
 | 
			
		||||
let pauseCircle = "pause-circle"
 | 
			
		||||
 | 
			
		||||
let minus = "minus"
 | 
			
		||||
 | 
			
		||||
let minusCircleO = "minus-circle-o"
 | 
			
		||||
 | 
			
		||||
let minusCircle = "minus-circle"
 | 
			
		||||
 | 
			
		||||
let plusSquare = "plus-square"
 | 
			
		||||
 | 
			
		||||
let plusSquareO = "plus-square-o"
 | 
			
		||||
 | 
			
		||||
let minusSquare = "minus-square"
 | 
			
		||||
 | 
			
		||||
let minusSquareO = "minus-square-o"
 | 
			
		||||
 | 
			
		||||
let info = "info"
 | 
			
		||||
 | 
			
		||||
let infoCircleO = "info-circle-o"
 | 
			
		||||
 | 
			
		||||
let infoCircle = "info-circle"
 | 
			
		||||
 | 
			
		||||
let exclamation = "exclamation"
 | 
			
		||||
 | 
			
		||||
let exclamationCircleO = "exclamation-circle-o"
 | 
			
		||||
 | 
			
		||||
let exclamationCircle = "exclamation-circle"
 | 
			
		||||
 | 
			
		||||
let close = "close"
 | 
			
		||||
 | 
			
		||||
let closeCircle = "close-circle"
 | 
			
		||||
 | 
			
		||||
let closeCircleO = "close-circle-o"
 | 
			
		||||
 | 
			
		||||
let closeSquare = "close-square"
 | 
			
		||||
 | 
			
		||||
let closeSquareO = "close-square-o"
 | 
			
		||||
 | 
			
		||||
let check = "check"
 | 
			
		||||
 | 
			
		||||
let checkCircle = "check-circle"
 | 
			
		||||
 | 
			
		||||
let checkCircleO = "check-circle-o"
 | 
			
		||||
 | 
			
		||||
let checkSquare = "check-square"
 | 
			
		||||
 | 
			
		||||
let checkSquareO = "check-square-o"
 | 
			
		||||
 | 
			
		||||
let clockCircleO = "clock-circle-o"
 | 
			
		||||
 | 
			
		||||
let clockCircle = "clock-circle"
 | 
			
		||||
 | 
			
		||||
let warning = "warning"
 | 
			
		||||
 | 
			
		||||
let lock = "lock"
 | 
			
		||||
 | 
			
		||||
let unlock = "unlock"
 | 
			
		||||
 | 
			
		||||
let areaChart = "area-chart"
 | 
			
		||||
 | 
			
		||||
let pieChart = "pie-chart"
 | 
			
		||||
 | 
			
		||||
let barChart = "bar-chart"
 | 
			
		||||
 | 
			
		||||
let dotChart = "dot-chart"
 | 
			
		||||
 | 
			
		||||
let bars = "bars"
 | 
			
		||||
 | 
			
		||||
let book = "book"
 | 
			
		||||
 | 
			
		||||
let calendar = "calendar"
 | 
			
		||||
 | 
			
		||||
let cloud = "cloud"
 | 
			
		||||
 | 
			
		||||
let cloudDownload = "cloud-download"
 | 
			
		||||
 | 
			
		||||
let code = "code"
 | 
			
		||||
 | 
			
		||||
let codeO = "code-o"
 | 
			
		||||
 | 
			
		||||
let copy = "copy"
 | 
			
		||||
 | 
			
		||||
let creditCard = "credit-card"
 | 
			
		||||
 | 
			
		||||
let delete = "delete"
 | 
			
		||||
 | 
			
		||||
let desktop = "desktop"
 | 
			
		||||
 | 
			
		||||
let download = "download"
 | 
			
		||||
 | 
			
		||||
let edit = "edit"
 | 
			
		||||
 | 
			
		||||
let ellipsis = "ellipsis"
 | 
			
		||||
 | 
			
		||||
let file = "file"
 | 
			
		||||
 | 
			
		||||
let fileText = "file-text"
 | 
			
		||||
 | 
			
		||||
let fileUnknown = "file-unknown"
 | 
			
		||||
 | 
			
		||||
let filePdf = "file-pdf"
 | 
			
		||||
 | 
			
		||||
let fileWord = "file-word"
 | 
			
		||||
 | 
			
		||||
let fileExcel = "file-excel"
 | 
			
		||||
 | 
			
		||||
let fileJpg = "file-jpg"
 | 
			
		||||
 | 
			
		||||
let filePpt = "file-ppt"
 | 
			
		||||
 | 
			
		||||
let fileMarkdown = "file-markdown"
 | 
			
		||||
 | 
			
		||||
let fileAdd = "file-add"
 | 
			
		||||
 | 
			
		||||
let folder = "folder"
 | 
			
		||||
 | 
			
		||||
let folderOpen = "folder-open"
 | 
			
		||||
 | 
			
		||||
let folderAdd = "folder-add"
 | 
			
		||||
 | 
			
		||||
let hdd = "hdd"
 | 
			
		||||
 | 
			
		||||
let frown = "frown"
 | 
			
		||||
 | 
			
		||||
let frownO = "frown-o"
 | 
			
		||||
 | 
			
		||||
let meh = "meh"
 | 
			
		||||
 | 
			
		||||
let mehO = "meh-o"
 | 
			
		||||
 | 
			
		||||
let smile = "smile"
 | 
			
		||||
 | 
			
		||||
let smileO = "smile-o"
 | 
			
		||||
 | 
			
		||||
let inbox = "inbox"
 | 
			
		||||
 | 
			
		||||
let laptop = "laptop"
 | 
			
		||||
 | 
			
		||||
let appstoreO = "appstore-o"
 | 
			
		||||
 | 
			
		||||
let appstore = "appstore"
 | 
			
		||||
 | 
			
		||||
let lineChart = "line-chart"
 | 
			
		||||
 | 
			
		||||
let link = "link"
 | 
			
		||||
 | 
			
		||||
let mail = "mail"
 | 
			
		||||
 | 
			
		||||
let mobile = "mobile"
 | 
			
		||||
 | 
			
		||||
let notification = "notification"
 | 
			
		||||
 | 
			
		||||
let paperClip = "paper-clip"
 | 
			
		||||
 | 
			
		||||
let picture = "picture"
 | 
			
		||||
 | 
			
		||||
let poweroff = "poweroff"
 | 
			
		||||
 | 
			
		||||
let reload = "reload"
 | 
			
		||||
 | 
			
		||||
let search = "search"
 | 
			
		||||
 | 
			
		||||
let setting = "setting"
 | 
			
		||||
 | 
			
		||||
let shareAlt = "share-alt"
 | 
			
		||||
 | 
			
		||||
let shoppingCart = "shopping-cart"
 | 
			
		||||
 | 
			
		||||
let tablet = "tablet"
 | 
			
		||||
 | 
			
		||||
let tag = "tag"
 | 
			
		||||
 | 
			
		||||
let tagO = "tag-o"
 | 
			
		||||
 | 
			
		||||
let tags = "tags"
 | 
			
		||||
 | 
			
		||||
let tagsO = "tags-o"
 | 
			
		||||
 | 
			
		||||
let toTop = "to-top"
 | 
			
		||||
 | 
			
		||||
let upload = "upload"
 | 
			
		||||
 | 
			
		||||
let user = "user"
 | 
			
		||||
 | 
			
		||||
let videoCamera = "video-camera"
 | 
			
		||||
 | 
			
		||||
let home = "home"
 | 
			
		||||
 | 
			
		||||
let loading = "loading"
 | 
			
		||||
 | 
			
		||||
let loading3Quarters = "loading-3-quarters"
 | 
			
		||||
 | 
			
		||||
let cloudUploadO = "cloud-upload-o"
 | 
			
		||||
 | 
			
		||||
let cloudDownloadO = "cloud-download-o"
 | 
			
		||||
 | 
			
		||||
let cloudUpload = "cloud-upload"
 | 
			
		||||
 | 
			
		||||
let cloudO = "cloud-o"
 | 
			
		||||
 | 
			
		||||
let starO = "star-o"
 | 
			
		||||
 | 
			
		||||
let star = "star"
 | 
			
		||||
 | 
			
		||||
let heartO = "heart-o"
 | 
			
		||||
 | 
			
		||||
let heart = "heart"
 | 
			
		||||
 | 
			
		||||
let environment = "environment"
 | 
			
		||||
 | 
			
		||||
let environmentO = "environment-o"
 | 
			
		||||
 | 
			
		||||
let eye = "eye"
 | 
			
		||||
 | 
			
		||||
let eyeO = "eye-o"
 | 
			
		||||
 | 
			
		||||
let camera = "camera"
 | 
			
		||||
 | 
			
		||||
let cameraO = "camera-o"
 | 
			
		||||
 | 
			
		||||
let save = "save"
 | 
			
		||||
 | 
			
		||||
let team = "team"
 | 
			
		||||
 | 
			
		||||
let solution = "solution"
 | 
			
		||||
 | 
			
		||||
let phone = "phone"
 | 
			
		||||
 | 
			
		||||
let filter = "filter"
 | 
			
		||||
 | 
			
		||||
let exception_ = "exception"
 | 
			
		||||
 | 
			
		||||
let \"export" = "export"
 | 
			
		||||
 | 
			
		||||
let customerService = "customer-service"
 | 
			
		||||
 | 
			
		||||
let qrcode = "qrcode"
 | 
			
		||||
 | 
			
		||||
let scan = "scan"
 | 
			
		||||
 | 
			
		||||
let like = "like"
 | 
			
		||||
 | 
			
		||||
let likeO = "like-o"
 | 
			
		||||
 | 
			
		||||
let dislike = "dislike"
 | 
			
		||||
 | 
			
		||||
let dislikeO = "dislike-o"
 | 
			
		||||
 | 
			
		||||
let message = "message"
 | 
			
		||||
 | 
			
		||||
let payCircle = "pay-circle"
 | 
			
		||||
 | 
			
		||||
let payCircleO = "pay-circle-o"
 | 
			
		||||
 | 
			
		||||
let calculator = "calculator"
 | 
			
		||||
 | 
			
		||||
let pushpin = "pushpin"
 | 
			
		||||
 | 
			
		||||
let pushpinO = "pushpin-o"
 | 
			
		||||
 | 
			
		||||
let bulb = "bulb"
 | 
			
		||||
 | 
			
		||||
let select = "select"
 | 
			
		||||
 | 
			
		||||
let switcher = "switcher"
 | 
			
		||||
 | 
			
		||||
let rocket = "rocket"
 | 
			
		||||
 | 
			
		||||
let bell = "bell"
 | 
			
		||||
 | 
			
		||||
let disconnect = "disconnect"
 | 
			
		||||
 | 
			
		||||
let database = "database"
 | 
			
		||||
 | 
			
		||||
let compass = "compass"
 | 
			
		||||
 | 
			
		||||
let barcode = "barcode"
 | 
			
		||||
 | 
			
		||||
let hourglass = "hourglass"
 | 
			
		||||
 | 
			
		||||
let key = "key"
 | 
			
		||||
 | 
			
		||||
let flag = "flag"
 | 
			
		||||
 | 
			
		||||
let layout = "layout"
 | 
			
		||||
 | 
			
		||||
let printer = "printer"
 | 
			
		||||
 | 
			
		||||
let sound = "sound"
 | 
			
		||||
 | 
			
		||||
let usb = "usb"
 | 
			
		||||
 | 
			
		||||
let skin = "skin"
 | 
			
		||||
 | 
			
		||||
let tool = "tool"
 | 
			
		||||
 | 
			
		||||
let sync = "sync"
 | 
			
		||||
 | 
			
		||||
let wifi = "wifi"
 | 
			
		||||
 | 
			
		||||
let car = "car"
 | 
			
		||||
 | 
			
		||||
let schedule = "schedule"
 | 
			
		||||
 | 
			
		||||
let userAdd = "user-add"
 | 
			
		||||
 | 
			
		||||
let userDelete = "user-delete"
 | 
			
		||||
 | 
			
		||||
let usergroupAdd = "usergroup-add"
 | 
			
		||||
 | 
			
		||||
let usergroupDelete = "usergroup-delete"
 | 
			
		||||
 | 
			
		||||
let man = "man"
 | 
			
		||||
 | 
			
		||||
let woman = "woman"
 | 
			
		||||
 | 
			
		||||
let shop = "shop"
 | 
			
		||||
 | 
			
		||||
let gift = "gift"
 | 
			
		||||
 | 
			
		||||
let idcard = "idcard"
 | 
			
		||||
 | 
			
		||||
let medicineBox = "medicine-box"
 | 
			
		||||
 | 
			
		||||
let redEnvelope = "red-envelope"
 | 
			
		||||
 | 
			
		||||
let coffee = "coffee"
 | 
			
		||||
 | 
			
		||||
let copyright = "copyright"
 | 
			
		||||
 | 
			
		||||
let trademark = "trademark"
 | 
			
		||||
 | 
			
		||||
let safety = "safety"
 | 
			
		||||
 | 
			
		||||
let wallet = "wallet"
 | 
			
		||||
 | 
			
		||||
let bank = "bank"
 | 
			
		||||
 | 
			
		||||
let trophy = "trophy"
 | 
			
		||||
 | 
			
		||||
let contacts = "contacts"
 | 
			
		||||
 | 
			
		||||
let global = "global"
 | 
			
		||||
 | 
			
		||||
let shake = "shake"
 | 
			
		||||
 | 
			
		||||
let api = "api"
 | 
			
		||||
 | 
			
		||||
let fork = "fork"
 | 
			
		||||
 | 
			
		||||
let dashboard = "dashboard"
 | 
			
		||||
 | 
			
		||||
let form = "form"
 | 
			
		||||
 | 
			
		||||
let table = "table"
 | 
			
		||||
 | 
			
		||||
let profile = "profile"
 | 
			
		||||
 | 
			
		||||
let android = "android"
 | 
			
		||||
 | 
			
		||||
let androidO = "android-o"
 | 
			
		||||
 | 
			
		||||
let apple = "apple"
 | 
			
		||||
 | 
			
		||||
let appleO = "apple-o"
 | 
			
		||||
 | 
			
		||||
let windows = "windows"
 | 
			
		||||
 | 
			
		||||
let windowsO = "windows-o"
 | 
			
		||||
 | 
			
		||||
let ie = "ie"
 | 
			
		||||
 | 
			
		||||
let chrome = "chrome"
 | 
			
		||||
 | 
			
		||||
let github = "github"
 | 
			
		||||
 | 
			
		||||
let aliwangwang = "aliwangwang"
 | 
			
		||||
 | 
			
		||||
let aliwangwangO = "aliwangwang-o"
 | 
			
		||||
 | 
			
		||||
let dingding = "dingding"
 | 
			
		||||
 | 
			
		||||
let dingdingO = "dingding-o"
 | 
			
		||||
 | 
			
		||||
let weiboSquare = "weibo-square"
 | 
			
		||||
 | 
			
		||||
let weiboCircle = "weibo-circle"
 | 
			
		||||
 | 
			
		||||
let taobaoCircle = "taobao-circle"
 | 
			
		||||
 | 
			
		||||
let html5 = "html5"
 | 
			
		||||
 | 
			
		||||
let weibo = "weibo"
 | 
			
		||||
 | 
			
		||||
let twitter = "twitter"
 | 
			
		||||
 | 
			
		||||
let wechat = "wechat"
 | 
			
		||||
 | 
			
		||||
let youtube = "youtube"
 | 
			
		||||
 | 
			
		||||
let alipayCircle = "alipay-circle"
 | 
			
		||||
 | 
			
		||||
let taobao = "taobao"
 | 
			
		||||
 | 
			
		||||
let skype = "skype"
 | 
			
		||||
 | 
			
		||||
let qq = "qq"
 | 
			
		||||
 | 
			
		||||
let mediumWorkmark = "medium-workmark"
 | 
			
		||||
 | 
			
		||||
let gitlab = "gitlab"
 | 
			
		||||
 | 
			
		||||
let medium = "medium"
 | 
			
		||||
 | 
			
		||||
let linkedin = "linkedin"
 | 
			
		||||
 | 
			
		||||
let googlePlus = "google-plus"
 | 
			
		||||
 | 
			
		||||
let dropbox = "dropbox"
 | 
			
		||||
 | 
			
		||||
let facebook = "facebook"
 | 
			
		||||
 | 
			
		||||
let codepen = "codepen"
 | 
			
		||||
 | 
			
		||||
let amazon = "amazon"
 | 
			
		||||
 | 
			
		||||
let google = "google"
 | 
			
		||||
 | 
			
		||||
let codepenCircle = "codepen-circle"
 | 
			
		||||
 | 
			
		||||
let alipay = "alipay"
 | 
			
		||||
 | 
			
		||||
let antDesign = "ant-design"
 | 
			
		||||
 | 
			
		||||
let aliyun = "aliyun"
 | 
			
		||||
 | 
			
		||||
let zhihu = "zhihu"
 | 
			
		||||
 | 
			
		||||
let slack = "slack"
 | 
			
		||||
 | 
			
		||||
let slackSquare = "slack-square"
 | 
			
		||||
 | 
			
		||||
let behance = "behance"
 | 
			
		||||
 | 
			
		||||
let behanceSquare = "behance-square"
 | 
			
		||||
 | 
			
		||||
let dribbble = "dribbble"
 | 
			
		||||
 | 
			
		||||
let dribbbleSquare = "dribbble-square"
 | 
			
		||||
 | 
			
		||||
let instagram = "instagram"
 | 
			
		||||
 | 
			
		||||
let yuque = "yuque"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,21 +0,0 @@
 | 
			
		|||
@deriving(abstract)
 | 
			
		||||
type props
 | 
			
		||||
type makeType = props => React.element
 | 
			
		||||
 | 
			
		||||
@obj external makeProps: (
 | 
			
		||||
  @as("type") 
 | 
			
		||||
  ~htmlType: string=?,
 | 
			
		||||
  ~name: string=?,
 | 
			
		||||
  ~value: string=?,
 | 
			
		||||
  ~defaultValue: string=?,
 | 
			
		||||
  ~onChange: ReactEvent.Form.t => unit=?,
 | 
			
		||||
  ~onPressEnter: ReactEvent.Keyboard.t => unit=?,
 | 
			
		||||
  ~onBlur: ReactEvent.Focus.t => unit=?,
 | 
			
		||||
  ~className: string=?,
 | 
			
		||||
  ~style: ReactDOMStyle.t=?,
 | 
			
		||||
  ~placeholder: string=?,
 | 
			
		||||
  unit // This unit is a quirk of the type system. Apparently it must exist to have optional arguments in a type
 | 
			
		||||
  ) => props = "" 
 | 
			
		||||
 | 
			
		||||
@module("antd")
 | 
			
		||||
external make : makeType = "Input"
 | 
			
		||||
							
								
								
									
										78
									
								
								src/App.res
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/App.res
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,78 +0,0 @@
 | 
			
		|||
type route =
 | 
			
		||||
  | DistBuilder
 | 
			
		||||
  | Home
 | 
			
		||||
  | NotFound
 | 
			
		||||
 | 
			
		||||
let routeToPath = route =>
 | 
			
		||||
  switch route {
 | 
			
		||||
  | DistBuilder => "/dist-builder"
 | 
			
		||||
  | Home => "/"
 | 
			
		||||
  | _ => "/"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
module Menu = {
 | 
			
		||||
  module Styles = {
 | 
			
		||||
    open CssJs
 | 
			
		||||
    let menu = style(. [ position(#relative),
 | 
			
		||||
    marginTop(em(0.25)),
 | 
			
		||||
    marginBottom(em(0.25)),
 | 
			
		||||
    selector(.
 | 
			
		||||
      "a",
 | 
			
		||||
      [ borderRadius(em(0.25)),
 | 
			
		||||
      display(#inlineBlock),
 | 
			
		||||
      backgroundColor(#hex("eee")),
 | 
			
		||||
      padding(em(1.)),
 | 
			
		||||
      cursor(#pointer),
 | 
			
		||||
    ],
 | 
			
		||||
    ),
 | 
			
		||||
    selector(. "a:hover", [ backgroundColor(#hex("bfcad4")) ]),
 | 
			
		||||
    selector(. "a:hover", [ backgroundColor(#hex("bfcad4")) ]),
 | 
			
		||||
    selector(.
 | 
			
		||||
      "a:not(:firstChild):not(:lastChild)",
 | 
			
		||||
      [ marginRight(em(0.25)), marginLeft(em(0.25)) ],
 | 
			
		||||
    ),
 | 
			
		||||
  ])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  module Item = {
 | 
			
		||||
    @react.component
 | 
			
		||||
    let make = (~href, ~children) =>
 | 
			
		||||
      <a
 | 
			
		||||
        href
 | 
			
		||||
        onClick={e => {
 | 
			
		||||
          e->ReactEvent.Synthetic.preventDefault
 | 
			
		||||
          RescriptReactRouter.push(href)
 | 
			
		||||
        }}>
 | 
			
		||||
        children
 | 
			
		||||
      </a>
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = () =>
 | 
			
		||||
    <div style=Styles.menu>
 | 
			
		||||
      <Item href={routeToPath(Home)} key="home"> {"Home" |> R.ste} </Item>
 | 
			
		||||
      <Item href={routeToPath(DistBuilder)} key="dist-builder"> {"Dist Builder" |> R.ste} </Item>
 | 
			
		||||
    </div>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let fixedLength = r => <div className="w-full max-w-screen-xl mx-auto px-6"> r </div>
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
let make = () => {
 | 
			
		||||
  let url = RescriptReactRouter.useUrl()
 | 
			
		||||
 | 
			
		||||
  let routing = switch url.path {
 | 
			
		||||
  | list{"dist-builder"} => DistBuilder
 | 
			
		||||
  | list{} => Home
 | 
			
		||||
  | _ => NotFound
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  <>
 | 
			
		||||
    <Menu />
 | 
			
		||||
    {switch routing {
 | 
			
		||||
    | DistBuilder => <DistBuilder />
 | 
			
		||||
    | Home => <Home />
 | 
			
		||||
    | _ => fixedLength("Page is not found" |> R.ste)
 | 
			
		||||
    }}
 | 
			
		||||
  </>
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,44 +0,0 @@
 | 
			
		|||
let reasonReactBlue = "#48a9dc";
 | 
			
		||||
 | 
			
		||||
// The {j|...|j} feature is just string interpolation, from
 | 
			
		||||
// bucklescript.github.io/docs/en/interop-cheatsheet#string-unicode-interpolation
 | 
			
		||||
// This allows us to conveniently write CSS, together with variables, by
 | 
			
		||||
// constructing a string
 | 
			
		||||
let style = {j|
 | 
			
		||||
  body {
 | 
			
		||||
    background-color: rgb(224, 226, 229);
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
  }
 | 
			
		||||
  button {
 | 
			
		||||
    background-color: white;
 | 
			
		||||
    color: $reasonReactBlue;
 | 
			
		||||
    box-shadow: 0 0 0 1px $reasonReactBlue;
 | 
			
		||||
    border: none;
 | 
			
		||||
    padding: 8px;
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
  }
 | 
			
		||||
  button:active {
 | 
			
		||||
    background-color: $reasonReactBlue;
 | 
			
		||||
    color: white;
 | 
			
		||||
  }
 | 
			
		||||
  .container {
 | 
			
		||||
    margin: 12px 0px;
 | 
			
		||||
    box-shadow: 0px 4px 16px rgb(200, 200, 200);
 | 
			
		||||
    width: 720px;
 | 
			
		||||
    border-radius: 12px;
 | 
			
		||||
    font-family: sans-serif;
 | 
			
		||||
  }
 | 
			
		||||
  .containerTitle {
 | 
			
		||||
    background-color: rgb(242, 243, 245);
 | 
			
		||||
    border-radius: 12px 12px 0px 0px;
 | 
			
		||||
    padding: 12px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
  }
 | 
			
		||||
  .containerContent {
 | 
			
		||||
    background-color: white;
 | 
			
		||||
    padding: 16px;
 | 
			
		||||
    border-radius: 0px 0px 12px 12px;
 | 
			
		||||
  }
 | 
			
		||||
|j};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
%raw(`import('./styles/index.css')`)
 | 
			
		||||
switch ReactDOM.querySelector("#app") {
 | 
			
		||||
| Some(root) => ReactDOM.render(<App />, root)
 | 
			
		||||
| None => ()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +0,0 @@
 | 
			
		|||
let ste = React.string
 | 
			
		||||
let showIf = (cond, comp) => cond ? comp : React.null
 | 
			
		||||
 | 
			
		||||
module O = {
 | 
			
		||||
  let defaultNull = E.O.default(React.null)
 | 
			
		||||
  let fmapOrNull = (fn, el) => el |> E.O.fmap(fn) |> E.O.default(React.null)
 | 
			
		||||
  let flatten = E.O.default(React.null)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
import React from "react";
 | 
			
		||||
import AceEditor from "react-ace";
 | 
			
		||||
 | 
			
		||||
import "ace-builds/src-noconflict/mode-golang";
 | 
			
		||||
import "ace-builds/src-noconflict/theme-github";
 | 
			
		||||
import "ace-builds/src-noconflict/ext-language_tools";
 | 
			
		||||
import "ace-builds/src-noconflict/keybinding-vim";
 | 
			
		||||
 | 
			
		||||
function onChange(newValue) {
 | 
			
		||||
  console.log("change", newValue);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function CodeEditor(props) {
 | 
			
		||||
  return (
 | 
			
		||||
    <AceEditor
 | 
			
		||||
      value={props.value}
 | 
			
		||||
      mode="golang"
 | 
			
		||||
      height="400px"
 | 
			
		||||
      width="100%"
 | 
			
		||||
      theme="github"
 | 
			
		||||
      showGutter={false}
 | 
			
		||||
      highlightActiveLine={false}
 | 
			
		||||
      showPrintMargin={false}
 | 
			
		||||
      onChange={props.onChange}
 | 
			
		||||
      name="UNIQUE_ID_OF_DIV"
 | 
			
		||||
      editorProps={{
 | 
			
		||||
        $blockScrolling: true,
 | 
			
		||||
      }}
 | 
			
		||||
      setOptions={{
 | 
			
		||||
        enableBasicAutocompletion: false,
 | 
			
		||||
        enableLiveAutocompletion: true,
 | 
			
		||||
        enableSnippets: true,
 | 
			
		||||
      }}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
type props
 | 
			
		||||
@obj external makeProps : (~value:string=?, ~onChange: string => unit, ~children: React.element=?, unit) => props = ""
 | 
			
		||||
 | 
			
		||||
@module("./CodeEditor.js")
 | 
			
		||||
external make: props => React.element = "CodeEditor"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,271 +0,0 @@
 | 
			
		|||
open ReForm
 | 
			
		||||
open Antd.Grid
 | 
			
		||||
 | 
			
		||||
module FormConfig = %lenses(
 | 
			
		||||
  type state = {
 | 
			
		||||
    squiggleString: string,
 | 
			
		||||
    sampleCount: string,
 | 
			
		||||
    outputXYPoints: string,
 | 
			
		||||
    downsampleTo: string,
 | 
			
		||||
    kernelWidth: string,
 | 
			
		||||
    diagramStart: string,
 | 
			
		||||
    diagramStop: string,
 | 
			
		||||
    diagramCount: string,
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type options = {
 | 
			
		||||
  sampleCount: int,
 | 
			
		||||
  outputXYPoints: int,
 | 
			
		||||
  downsampleTo: option<int>,
 | 
			
		||||
  kernelWidth: option<float>,
 | 
			
		||||
  diagramStart: float,
 | 
			
		||||
  diagramStop: float,
 | 
			
		||||
  diagramCount: int,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module Form = ReForm.Make(FormConfig)
 | 
			
		||||
 | 
			
		||||
module FieldText = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~field, ~label) => <>
 | 
			
		||||
    <Form.Field
 | 
			
		||||
      field
 | 
			
		||||
      render={({handleChange, error, value, validate}) =>{
 | 
			
		||||
        Js.Console.log(CodeEditor.make);
 | 
			
		||||
        (<CodeEditor value onChange={r => handleChange(r)} />)
 | 
			
		||||
      }
 | 
			
		||||
      }
 | 
			
		||||
    />
 | 
			
		||||
  </>
 | 
			
		||||
}
 | 
			
		||||
module FieldString = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~field, ~label) =>
 | 
			
		||||
    <Form.Field
 | 
			
		||||
      field
 | 
			
		||||
      render={({handleChange, error, value, validate}) =>
 | 
			
		||||
        <Antd.Form.Item label={label}>
 | 
			
		||||
          <Antd.Input
 | 
			
		||||
            value onChange={ReForm.Helpers.handleChange(handleChange)} onBlur={_ => validate()}
 | 
			
		||||
          />
 | 
			
		||||
        </Antd.Form.Item>}
 | 
			
		||||
    />
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module FieldFloat = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~field, ~label, ~className=CssJs.style(. [])) =>
 | 
			
		||||
    <Form.Field
 | 
			
		||||
      field
 | 
			
		||||
      render={({handleChange, error, value, validate}) =>
 | 
			
		||||
          <Antd.Input
 | 
			
		||||
            value
 | 
			
		||||
            onChange={ReForm.Helpers.handleChange(handleChange)}
 | 
			
		||||
            onBlur={_ => validate()}
 | 
			
		||||
            style={className}
 | 
			
		||||
          />
 | 
			
		||||
        }
 | 
			
		||||
    />
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module Styles = {
 | 
			
		||||
  open CssJs
 | 
			
		||||
  let rows = style(. [ selector(. ">.antCol:firstChild", [ paddingLeft(em(0.25)), paddingRight(em(0.125)) ]),
 | 
			
		||||
  selector(. ">.antCol:lastChild", [ paddingLeft(em(0.125)), paddingRight(em(0.25)) ]),
 | 
			
		||||
  selector(. 
 | 
			
		||||
    ">.antCol:not(:firstChild):not(:lastChild)",
 | 
			
		||||
    [ paddingLeft(em(0.125)), paddingRight(em(0.125)) ],
 | 
			
		||||
  ),
 | 
			
		||||
])
 | 
			
		||||
let parent = style(. [ selector(. ".antInputNumber", [ width(#percent(100.)) ]),
 | 
			
		||||
selector(. ".anticon", [ verticalAlign(#zero) ]),
 | 
			
		||||
 ])
 | 
			
		||||
  let form = style(. [ backgroundColor(hex("eee")), padding(em(1.)) ])
 | 
			
		||||
  let dist = style(. [ padding(em(1.)) ])
 | 
			
		||||
  let spacer = style(. [ marginTop(em(1.)) ])
 | 
			
		||||
  let groupA = style(. [ selector(. ".antInputNumberInput", [ backgroundColor(hex("fff7db")) ]),
 | 
			
		||||
])
 | 
			
		||||
let groupB = style(. [ selector(. ".antInputNumberInput", [ backgroundColor(hex("eaf4ff")) ]),
 | 
			
		||||
 ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module DemoDist = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~squiggleString: string, ~options) =>
 | 
			
		||||
    <Antd.Card title={"Distribution"}>
 | 
			
		||||
      <div>
 | 
			
		||||
        {switch options {
 | 
			
		||||
        | Some(options) =>
 | 
			
		||||
          let inputs1 = ProgramEvaluator.Inputs.make(
 | 
			
		||||
            ~samplingInputs={
 | 
			
		||||
              sampleCount: Some(options.sampleCount),
 | 
			
		||||
              outputXYPoints: Some(options.outputXYPoints),
 | 
			
		||||
              kernelWidth: options.kernelWidth,
 | 
			
		||||
              shapeLength: Some(options.downsampleTo |> E.O.default(1000)),
 | 
			
		||||
            },
 | 
			
		||||
            ~squiggleString,
 | 
			
		||||
            ~environment=[
 | 
			
		||||
              ("K", #SymbolicDist(#Float(1000.0))),
 | 
			
		||||
              ("M", #SymbolicDist(#Float(1000000.0))),
 | 
			
		||||
              ("B", #SymbolicDist(#Float(1000000000.0))),
 | 
			
		||||
              ("T", #SymbolicDist(#Float(1000000000000.0))),
 | 
			
		||||
            ]->Belt.Map.String.fromArray,
 | 
			
		||||
            (),
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
          let distributionList = ProgramEvaluator.evaluateProgram(inputs1)
 | 
			
		||||
 | 
			
		||||
          let renderExpression = response1 => 
 | 
			
		||||
            switch response1 {
 | 
			
		||||
              | #DistPlus(distPlus1) => <DistPlusPlot distPlus={DistPlus.T.normalize(distPlus1)} />
 | 
			
		||||
              | #Float(f) => <NumberShower number=f precision=3 />
 | 
			
		||||
              | #Function((f, a), env) =>
 | 
			
		||||
                //  Problem: When it gets the function, it doesn't save state about previous commands
 | 
			
		||||
                let foo: ProgramEvaluator.Inputs.inputs = {
 | 
			
		||||
                  squiggleString: squiggleString,
 | 
			
		||||
                  samplingInputs: inputs1.samplingInputs,
 | 
			
		||||
                  environment: env,
 | 
			
		||||
                }
 | 
			
		||||
                let results =
 | 
			
		||||
                  E.A.Floats.range(options.diagramStart, options.diagramStop, options.diagramCount)
 | 
			
		||||
                  |> E.A.fmap(r =>
 | 
			
		||||
                    ProgramEvaluator.evaluateFunction(
 | 
			
		||||
                      foo,
 | 
			
		||||
                      (f, a),
 | 
			
		||||
                      [#SymbolicDist(#Float(r))],
 | 
			
		||||
                    ) |> E.R.bind(_, a =>
 | 
			
		||||
                      switch a {
 | 
			
		||||
                      | #DistPlus(d) => Ok((r, DistPlus.T.normalize(d)))
 | 
			
		||||
                      | n =>
 | 
			
		||||
                        Js.log2("Error here", n)
 | 
			
		||||
                        Error("wrong type")
 | 
			
		||||
                      }
 | 
			
		||||
                    )
 | 
			
		||||
                  )
 | 
			
		||||
                  |> E.A.R.firstErrorOrOpen
 | 
			
		||||
                switch results {
 | 
			
		||||
                | Ok(dists) => <PercentilesChart dists />
 | 
			
		||||
                | Error(r) => r |> R.ste
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
          // Render the list of distributions given by the
 | 
			
		||||
          switch distributionList {
 | 
			
		||||
            | Ok(xs) =>
 | 
			
		||||
                let childrenElements = List.map(renderExpression, xs)
 | 
			
		||||
                Js.Console.log(childrenElements)
 | 
			
		||||
                <ul>
 | 
			
		||||
                  {Belt.List.toArray(Belt.List.mapWithIndex(childrenElements, (i, child) => <li key={Belt.Int.toString(i)}>child</li>))->React.array}
 | 
			
		||||
                </ul>
 | 
			
		||||
            | Error(r) => r |> R.ste
 | 
			
		||||
          }
 | 
			
		||||
        | _ => "Nothing to show. Try to change the distribution description." |> R.ste
 | 
			
		||||
        }}
 | 
			
		||||
      </div>
 | 
			
		||||
    </Antd.Card>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
let make = () => {
 | 
			
		||||
  let (reloader, setReloader) = React.useState(() => 1)
 | 
			
		||||
  let reform = Form.use(
 | 
			
		||||
    ~validationStrategy=OnDemand,
 | 
			
		||||
    ~schema=Form.Validation.Schema([]),
 | 
			
		||||
    ~onSubmit=({state}) => None,
 | 
			
		||||
    ~initialState={
 | 
			
		||||
      //squiggleString: "mm(normal(-10, 2), uniform(18, 25), lognormal({mean: 10, stdev: 8}), triangular(31,40,50))",
 | 
			
		||||
      squiggleString: "mm(normal(5,2), normal(10,2))",
 | 
			
		||||
      sampleCount: "1000",
 | 
			
		||||
      outputXYPoints: "1000",
 | 
			
		||||
      downsampleTo: "",
 | 
			
		||||
      kernelWidth: "",
 | 
			
		||||
      diagramStart: "0",
 | 
			
		||||
      diagramStop: "10",
 | 
			
		||||
      diagramCount: "20",
 | 
			
		||||
    },
 | 
			
		||||
    (),
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  let onSubmit = e => {
 | 
			
		||||
    e->ReactEvent.Synthetic.preventDefault
 | 
			
		||||
    reform.submit()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let squiggleString = reform.state.values.squiggleString
 | 
			
		||||
  let sampleCount = reform.state.values.sampleCount |> Js.Float.fromString
 | 
			
		||||
  let outputXYPoints = reform.state.values.outputXYPoints |> Js.Float.fromString
 | 
			
		||||
  let downsampleTo = reform.state.values.downsampleTo |> Js.Float.fromString
 | 
			
		||||
  let kernelWidth = reform.state.values.kernelWidth |> Js.Float.fromString
 | 
			
		||||
  let diagramStart = reform.state.values.diagramStart |> Js.Float.fromString
 | 
			
		||||
  let diagramStop = reform.state.values.diagramStop |> Js.Float.fromString
 | 
			
		||||
  let diagramCount = reform.state.values.diagramCount |> Js.Float.fromString
 | 
			
		||||
 | 
			
		||||
  let options = switch (sampleCount, outputXYPoints, downsampleTo) {
 | 
			
		||||
  | (_, _, _)
 | 
			
		||||
    if !Js.Float.isNaN(sampleCount) &&
 | 
			
		||||
    (!Js.Float.isNaN(outputXYPoints) &&
 | 
			
		||||
    (!Js.Float.isNaN(downsampleTo) && (sampleCount > 10. && outputXYPoints > 10.))) =>
 | 
			
		||||
    Some({
 | 
			
		||||
      sampleCount: sampleCount |> int_of_float,
 | 
			
		||||
      outputXYPoints: outputXYPoints |> int_of_float,
 | 
			
		||||
      downsampleTo: int_of_float(downsampleTo) > 0 ? Some(int_of_float(downsampleTo)) : None,
 | 
			
		||||
      kernelWidth: kernelWidth == 0.0 ? None : Some(kernelWidth),
 | 
			
		||||
      diagramStart: diagramStart,
 | 
			
		||||
      diagramStop: diagramStop,
 | 
			
		||||
      diagramCount: diagramCount |> int_of_float,
 | 
			
		||||
    })
 | 
			
		||||
  | _ => None
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let demoDist = React.useMemo1(
 | 
			
		||||
    () => <DemoDist squiggleString options />,
 | 
			
		||||
    [
 | 
			
		||||
      reform.state.values.squiggleString,
 | 
			
		||||
      reform.state.values.sampleCount,
 | 
			
		||||
      reform.state.values.outputXYPoints,
 | 
			
		||||
      reform.state.values.downsampleTo,
 | 
			
		||||
      reform.state.values.kernelWidth,
 | 
			
		||||
      reform.state.values.diagramStart,
 | 
			
		||||
      reform.state.values.diagramStop,
 | 
			
		||||
      reform.state.values.diagramCount,
 | 
			
		||||
      reloader |> string_of_int,
 | 
			
		||||
    ],
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  let onReload = _ => setReloader(_ => reloader + 1)
 | 
			
		||||
 | 
			
		||||
  <div className="grid grid-cols-2 gap-4">
 | 
			
		||||
    <div>
 | 
			
		||||
      <Antd.Card
 | 
			
		||||
        title={"Distribution Form" |> R.ste}
 | 
			
		||||
        extra={<Antd.Button icon=Antd.IconName.reload shape=#circle onClick=onReload />}>
 | 
			
		||||
        <Form.Provider value=reform>
 | 
			
		||||
          <Antd.Form onSubmit>
 | 
			
		||||
            <Row _type="flex" style=Styles.rows>
 | 
			
		||||
              <Col span=24> <FieldText field=FormConfig.SquiggleString label="Program" /> </Col>
 | 
			
		||||
            </Row>
 | 
			
		||||
            <Row _type="flex" style=Styles.rows>
 | 
			
		||||
              <Col span=12> <FieldFloat field=FormConfig.SampleCount label="Sample Count" /> </Col>
 | 
			
		||||
              <Col span=12>
 | 
			
		||||
                <FieldFloat field=FormConfig.OutputXYPoints label="Output XY-points" />
 | 
			
		||||
              </Col>
 | 
			
		||||
              <Col span=12>
 | 
			
		||||
                <FieldFloat field=FormConfig.DownsampleTo label="Downsample To" />
 | 
			
		||||
              </Col>
 | 
			
		||||
              <Col span=12> <FieldFloat field=FormConfig.KernelWidth label="Kernel Width" /> </Col>
 | 
			
		||||
              <Col span=12>
 | 
			
		||||
                <FieldFloat field=FormConfig.DiagramStart label="Diagram Start" />
 | 
			
		||||
              </Col>
 | 
			
		||||
              <Col span=12> <FieldFloat field=FormConfig.DiagramStop label="Diagram Stop" /> </Col>
 | 
			
		||||
              <Col span=12>
 | 
			
		||||
                <FieldFloat field=FormConfig.DiagramCount label="Diagram Count" />
 | 
			
		||||
              </Col>
 | 
			
		||||
            </Row>
 | 
			
		||||
          </Antd.Form>
 | 
			
		||||
        </Form.Provider>
 | 
			
		||||
      </Antd.Card>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div> demoDist </div>
 | 
			
		||||
  </div>
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,306 +0,0 @@
 | 
			
		|||
open DistPlusPlotReducer
 | 
			
		||||
let plotBlue = #hex("1860ad")
 | 
			
		||||
 | 
			
		||||
let showAsForm = (distPlus: DistTypes.distPlus) =>
 | 
			
		||||
  <div> <Antd.Input value={distPlus.squiggleString |> E.O.default("")} /> </div>
 | 
			
		||||
 | 
			
		||||
let showFloat = (~precision=3, number) => <NumberShower number precision />
 | 
			
		||||
 | 
			
		||||
let table = (distPlus, x) =>
 | 
			
		||||
  <div>
 | 
			
		||||
    <table className="table-auto text-sm">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2 "> {"X Point" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"Discrete Value" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"Continuous Value" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"Y Integral to Point" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"Y Integral Total" |> React.string} </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
      <tbody>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2 border"> {x |> E.Float.toString |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2 border ">
 | 
			
		||||
            {distPlus
 | 
			
		||||
            |> DistPlus.T.xToY(x)
 | 
			
		||||
            |> DistTypes.MixedPoint.toDiscreteValue
 | 
			
		||||
            |> Js.Float.toPrecisionWithPrecision(_, ~digits=7)
 | 
			
		||||
            |> React.string}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border ">
 | 
			
		||||
            {distPlus
 | 
			
		||||
            |> DistPlus.T.xToY(x)
 | 
			
		||||
            |> DistTypes.MixedPoint.toContinuousValue
 | 
			
		||||
            |> Js.Float.toPrecisionWithPrecision(_, ~digits=7)
 | 
			
		||||
            |> React.string}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border ">
 | 
			
		||||
            {distPlus
 | 
			
		||||
            |> DistPlus.T.Integral.xToY(x)
 | 
			
		||||
            |> E.Float.with2DigitsPrecision
 | 
			
		||||
            |> React.string}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border ">
 | 
			
		||||
            {distPlus
 | 
			
		||||
            |> DistPlus.T.Integral.sum
 | 
			
		||||
            |> E.Float.with2DigitsPrecision
 | 
			
		||||
            |> React.string}
 | 
			
		||||
          </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    <table className="table-auto text-sm">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2"> {"Continuous Total" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"Discrete Total" |> React.string} </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
      <tbody>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus
 | 
			
		||||
            |> DistPlus.T.toContinuous
 | 
			
		||||
            |> E.O.fmap(Continuous.T.Integral.sum)
 | 
			
		||||
            |> E.O.fmap(E.Float.with2DigitsPrecision)
 | 
			
		||||
            |> E.O.default("")
 | 
			
		||||
            |> React.string}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border ">
 | 
			
		||||
            {distPlus
 | 
			
		||||
            |> DistPlus.T.toDiscrete
 | 
			
		||||
            |> E.O.fmap(Discrete.T.Integral.sum)
 | 
			
		||||
            |> E.O.fmap(E.Float.with2DigitsPrecision)
 | 
			
		||||
            |> E.O.default("")
 | 
			
		||||
            |> React.string}
 | 
			
		||||
          </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
  </div>
 | 
			
		||||
let percentiles = distPlus =>
 | 
			
		||||
  <div>
 | 
			
		||||
    <table className="table-auto text-sm">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2"> {"1" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"5" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"25" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"50" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"75" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"95" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"99" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"99.999" |> React.string} </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
      <tbody>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.01) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.05) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.25) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.5) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.75) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.95) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.99) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.Integral.yToX(0.99999) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    <table className="table-auto text-sm">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2"> {"mean" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"standard deviation" |> React.string} </td>
 | 
			
		||||
          <td className="px-4 py-2"> {"variance" |> React.string} </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
      <tbody>
 | 
			
		||||
        <tr>
 | 
			
		||||
          <td className="px-4 py-2 border"> {distPlus |> DistPlus.T.mean |> showFloat} </td>
 | 
			
		||||
          <td className="px-4 py-2 border">
 | 
			
		||||
            {distPlus |> DistPlus.T.variance |> (r => r ** 0.5) |> showFloat}
 | 
			
		||||
          </td>
 | 
			
		||||
          <td className="px-4 py-2 border"> {distPlus |> DistPlus.T.variance |> showFloat} </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
let adjustBoth = discreteProbabilityMassFraction => {
 | 
			
		||||
  let yMaxDiscreteDomainFactor = discreteProbabilityMassFraction
 | 
			
		||||
  let yMaxContinuousDomainFactor = 1.0 -. discreteProbabilityMassFraction
 | 
			
		||||
 | 
			
		||||
  // use the bigger proportion, such that whichever is the bigger proportion, the yMax is 1.
 | 
			
		||||
 | 
			
		||||
  let yMax = yMaxDiscreteDomainFactor > 0.5 ? yMaxDiscreteDomainFactor : yMaxContinuousDomainFactor
 | 
			
		||||
  (yMax /. yMaxDiscreteDomainFactor, yMax /. yMaxContinuousDomainFactor)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module DistPlusChart = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~distPlus: DistTypes.distPlus, ~config: chartConfig, ~onHover) => {
 | 
			
		||||
    open DistPlus
 | 
			
		||||
 | 
			
		||||
    let discrete = distPlus |> T.toDiscrete |> E.O.fmap(Discrete.getShape)
 | 
			
		||||
    let continuous = distPlus |> T.toContinuous |> E.O.fmap(Continuous.getShape)
 | 
			
		||||
 | 
			
		||||
    // // We subtract a bit from the range to make sure that it fits. Maybe this should be done in d3 instead.
 | 
			
		||||
    // let minX =
 | 
			
		||||
    //   switch (
 | 
			
		||||
    //     distPlus
 | 
			
		||||
    //     |> DistPlus.T.Integral.yToX(0.0001),
 | 
			
		||||
    //     range,
 | 
			
		||||
    //   ) {
 | 
			
		||||
    //   | (min, Some(range)) => Some(min -. range *. 0.001)
 | 
			
		||||
    //   | _ => None
 | 
			
		||||
    //   };
 | 
			
		||||
 | 
			
		||||
    let minX = distPlus |> DistPlus.T.Integral.yToX(0.00001)
 | 
			
		||||
 | 
			
		||||
    let maxX = distPlus |> DistPlus.T.Integral.yToX(0.99999)
 | 
			
		||||
 | 
			
		||||
    let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson
 | 
			
		||||
    let discreteProbabilityMassFraction = distPlus |> DistPlus.T.toDiscreteProbabilityMassFraction
 | 
			
		||||
 | 
			
		||||
    let (yMaxDiscreteDomainFactor, yMaxContinuousDomainFactor) = adjustBoth(
 | 
			
		||||
      discreteProbabilityMassFraction,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    <DistributionPlot
 | 
			
		||||
      xScale={config.xLog ? "log" : "linear"}
 | 
			
		||||
      yScale={config.yLog ? "log" : "linear"}
 | 
			
		||||
      height={DistPlusPlotReducer.heightToPix(config.height)}
 | 
			
		||||
      minX
 | 
			
		||||
      maxX
 | 
			
		||||
      yMaxDiscreteDomainFactor
 | 
			
		||||
      yMaxContinuousDomainFactor
 | 
			
		||||
      ?discrete
 | 
			
		||||
      ?continuous
 | 
			
		||||
      color=plotBlue
 | 
			
		||||
      onHover
 | 
			
		||||
      timeScale
 | 
			
		||||
    />
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module IntegralChart = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~distPlus: DistTypes.distPlus, ~config: chartConfig, ~onHover) => {
 | 
			
		||||
    let integral = distPlus.integralCache
 | 
			
		||||
    let continuous = integral |> Continuous.toLinear |> E.O.fmap(Continuous.getShape)
 | 
			
		||||
    let minX = distPlus |> DistPlus.T.Integral.yToX(0.00001)
 | 
			
		||||
 | 
			
		||||
    let maxX = distPlus |> DistPlus.T.Integral.yToX(0.99999)
 | 
			
		||||
    let timeScale = distPlus.unit |> DistTypes.DistributionUnit.toJson
 | 
			
		||||
    <DistributionPlot
 | 
			
		||||
      xScale={config.xLog ? "log" : "linear"}
 | 
			
		||||
      yScale={config.yLog ? "log" : "linear"}
 | 
			
		||||
      height={DistPlusPlotReducer.heightToPix(config.height)}
 | 
			
		||||
      minX
 | 
			
		||||
      maxX
 | 
			
		||||
      ?continuous
 | 
			
		||||
      color=plotBlue
 | 
			
		||||
      timeScale
 | 
			
		||||
      onHover
 | 
			
		||||
    />
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module Chart = {
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = (~distPlus: DistTypes.distPlus, ~config: chartConfig, ~onHover) => {
 | 
			
		||||
    let chart = React.useMemo2(
 | 
			
		||||
      () =>
 | 
			
		||||
        config.isCumulative
 | 
			
		||||
          ? <IntegralChart distPlus config onHover />
 | 
			
		||||
          : <DistPlusChart distPlus config onHover />,
 | 
			
		||||
      (distPlus, config),
 | 
			
		||||
    )
 | 
			
		||||
    <div
 | 
			
		||||
      style={
 | 
			
		||||
        open CssJs
 | 
			
		||||
        style(. [ minHeight(#px(DistPlusPlotReducer.heightToPix(config.height))) ])
 | 
			
		||||
      }>
 | 
			
		||||
      chart
 | 
			
		||||
    </div>
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let button = "bg-gray-300 hover:bg-gray-500 text-grey-darkest text-xs px-4 py-1"
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
let make = (~distPlus: DistTypes.distPlus) => {
 | 
			
		||||
  let (x, setX) = React.useState(() => 0.)
 | 
			
		||||
  let (state, dispatch) = React.useReducer(DistPlusPlotReducer.reducer, DistPlusPlotReducer.init)
 | 
			
		||||
 | 
			
		||||
  <div>
 | 
			
		||||
    {state.distributions
 | 
			
		||||
    |> E.L.fmapi((index, config) =>
 | 
			
		||||
      <div className="flex" key={string_of_int(index)}>
 | 
			
		||||
        <div className="w-4/5"> <Chart distPlus config onHover={r => setX(_ => r)} /> </div>
 | 
			
		||||
        <div className="w-1/5">
 | 
			
		||||
          <div className="opacity-50 hover:opacity-100">
 | 
			
		||||
            <button className=button onClick={_ => dispatch(CHANGE_X_LOG(index))}>
 | 
			
		||||
              {(config.xLog ? "x-log" : "x-linear") |> React.string}
 | 
			
		||||
            </button>
 | 
			
		||||
            <button className=button onClick={_ => dispatch(CHANGE_Y_LOG(index))}>
 | 
			
		||||
              {(config.yLog ? "y-log" : "y-linear") |> React.string}
 | 
			
		||||
            </button>
 | 
			
		||||
            <button
 | 
			
		||||
              className=button
 | 
			
		||||
              onClick={_ => dispatch(CHANGE_IS_CUMULATIVE(index, !config.isCumulative))}>
 | 
			
		||||
              {(config.isCumulative ? "cdf" : "pdf") |> React.string}
 | 
			
		||||
            </button>
 | 
			
		||||
            <button className=button onClick={_ => dispatch(HEIGHT_INCREMENT(index))}>
 | 
			
		||||
              {"expand" |> React.string}
 | 
			
		||||
            </button>
 | 
			
		||||
            <button className=button onClick={_ => dispatch(HEIGHT_DECREMENT(index))}>
 | 
			
		||||
              {"shrink" |> React.string}
 | 
			
		||||
            </button>
 | 
			
		||||
            {index != 0
 | 
			
		||||
              ? <button className=button onClick={_ => dispatch(REMOVE_DIST(index))}>
 | 
			
		||||
                  {"remove" |> React.string}
 | 
			
		||||
                </button>
 | 
			
		||||
              : React.null}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    )
 | 
			
		||||
    |> E.L.toArray
 | 
			
		||||
    |> React.array}
 | 
			
		||||
    <div className="inline-flex opacity-50 hover:opacity-100">
 | 
			
		||||
      <button className=button onClick={_ => dispatch(CHANGE_SHOW_PERCENTILES)}>
 | 
			
		||||
        {"Percentiles" |> React.string}
 | 
			
		||||
      </button>
 | 
			
		||||
      <button className=button onClick={_ => dispatch(CHANGE_SHOW_STATS)}>
 | 
			
		||||
        {"Debug Stats" |> React.string}
 | 
			
		||||
      </button>
 | 
			
		||||
      <button className=button onClick={_ => dispatch(CHANGE_SHOW_PARAMS)}>
 | 
			
		||||
        {"Params" |> React.string}
 | 
			
		||||
      </button>
 | 
			
		||||
      <button className=button onClick={_ => dispatch(ADD_DIST)}>
 | 
			
		||||
        {"Add" |> React.string}
 | 
			
		||||
      </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    {state.showParams ? showAsForm(distPlus) : React.null}
 | 
			
		||||
    {state.showStats ? table(distPlus, x) : React.null}
 | 
			
		||||
    {state.showPercentiles ? percentiles(distPlus) : React.null}
 | 
			
		||||
  </div>
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,112 +0,0 @@
 | 
			
		|||
type chartConfig = {
 | 
			
		||||
  xLog: bool,
 | 
			
		||||
  yLog: bool,
 | 
			
		||||
  isCumulative: bool,
 | 
			
		||||
  height: int,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type state = {
 | 
			
		||||
  showStats: bool,
 | 
			
		||||
  showPercentiles: bool,
 | 
			
		||||
  showParams: bool,
 | 
			
		||||
  distributions: list(chartConfig),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type action =
 | 
			
		||||
  | CHANGE_SHOW_STATS
 | 
			
		||||
  | CHANGE_SHOW_PARAMS
 | 
			
		||||
  | CHANGE_SHOW_PERCENTILES
 | 
			
		||||
  | REMOVE_DIST(int)
 | 
			
		||||
  | ADD_DIST
 | 
			
		||||
  | CHANGE_X_LOG(int)
 | 
			
		||||
  | CHANGE_Y_LOG(int)
 | 
			
		||||
  | CHANGE_IS_CUMULATIVE(int, bool)
 | 
			
		||||
  | HEIGHT_INCREMENT(int)
 | 
			
		||||
  | HEIGHT_DECREMENT(int);
 | 
			
		||||
 | 
			
		||||
let changeHeight = (currentHeight, foo: [ | `increment | `decrement]) =>
 | 
			
		||||
  switch (currentHeight, foo) {
 | 
			
		||||
  | (1, `decrement) => 1
 | 
			
		||||
  | (2, `decrement) => 1
 | 
			
		||||
  | (3, `decrement) => 2
 | 
			
		||||
  | (4, `decrement) => 3
 | 
			
		||||
  | (5, `decrement) => 4
 | 
			
		||||
  | (1, `increment) => 2
 | 
			
		||||
  | (2, `increment) => 3
 | 
			
		||||
  | (3, `increment) => 4
 | 
			
		||||
  | (4, `increment) => 5
 | 
			
		||||
  | (5, `increment) => 5
 | 
			
		||||
  | _ => 1
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
let heightToPix =
 | 
			
		||||
  fun
 | 
			
		||||
  | 1 => 80
 | 
			
		||||
  | 2 => 140
 | 
			
		||||
  | 3 => 240
 | 
			
		||||
  | 4 => 340
 | 
			
		||||
  | 5 => 440
 | 
			
		||||
  | _ => 140;
 | 
			
		||||
 | 
			
		||||
let distributionReducer = (index, state: list(chartConfig), action) => {
 | 
			
		||||
  switch (action, E.L.get(state, index)) {
 | 
			
		||||
  | (HEIGHT_INCREMENT(_), Some(dist)) =>
 | 
			
		||||
    E.L.update(
 | 
			
		||||
      {...dist, height: changeHeight(dist.height, `increment)},
 | 
			
		||||
      index,
 | 
			
		||||
      state,
 | 
			
		||||
    )
 | 
			
		||||
  | (HEIGHT_DECREMENT(_), Some(dist)) =>
 | 
			
		||||
    E.L.update(
 | 
			
		||||
      {...dist, height: changeHeight(dist.height, `decrement)},
 | 
			
		||||
      index,
 | 
			
		||||
      state,
 | 
			
		||||
    )
 | 
			
		||||
  | (CHANGE_IS_CUMULATIVE(_, isCumulative), Some(dist)) =>
 | 
			
		||||
    E.L.update({...dist, isCumulative}, index, state)
 | 
			
		||||
  | (CHANGE_X_LOG(_), Some(dist)) =>
 | 
			
		||||
    E.L.update({...dist, xLog: !dist.xLog}, index, state)
 | 
			
		||||
  | (CHANGE_Y_LOG(_), Some(dist)) =>
 | 
			
		||||
    E.L.update({...dist, yLog: !dist.yLog}, index, state)
 | 
			
		||||
  | (REMOVE_DIST(_), Some(_)) => E.L.remove(index, 1, state)
 | 
			
		||||
  | (ADD_DIST, Some(_)) =>
 | 
			
		||||
    E.L.append(
 | 
			
		||||
      state,
 | 
			
		||||
      [{yLog: false, xLog: false, isCumulative: false, height: 4}],
 | 
			
		||||
    )
 | 
			
		||||
  | _ => state
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
let reducer = (state: state, action: action) =>
 | 
			
		||||
  switch (action) {
 | 
			
		||||
  | CHANGE_X_LOG(i)
 | 
			
		||||
  | CHANGE_Y_LOG(i)
 | 
			
		||||
  | CHANGE_IS_CUMULATIVE(i, _)
 | 
			
		||||
  | HEIGHT_DECREMENT(i)
 | 
			
		||||
  | REMOVE_DIST(i)
 | 
			
		||||
  | HEIGHT_INCREMENT(i) => {
 | 
			
		||||
      ...state,
 | 
			
		||||
      distributions: distributionReducer(i, state.distributions, action),
 | 
			
		||||
    }
 | 
			
		||||
  | ADD_DIST => {
 | 
			
		||||
      ...state,
 | 
			
		||||
      distributions: distributionReducer(0, state.distributions, action),
 | 
			
		||||
    }
 | 
			
		||||
  | CHANGE_SHOW_STATS => {...state, showStats: !state.showStats}
 | 
			
		||||
  | CHANGE_SHOW_PARAMS => {...state, showParams: !state.showParams}
 | 
			
		||||
  | CHANGE_SHOW_PERCENTILES => {
 | 
			
		||||
      ...state,
 | 
			
		||||
      showPercentiles: !state.showPercentiles,
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
let init = {
 | 
			
		||||
  showStats: false,
 | 
			
		||||
  showParams: false,
 | 
			
		||||
  showPercentiles: false,
 | 
			
		||||
  distributions: [
 | 
			
		||||
    {yLog: false, xLog: false, isCumulative: false, height: 4},
 | 
			
		||||
    {yLog: false, xLog: false, isCumulative: true, height: 1},
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,108 +0,0 @@
 | 
			
		|||
module RawPlot = {
 | 
			
		||||
  type primaryDistribution = option<{"xs": array<float>, "ys": array<float>}>
 | 
			
		||||
 | 
			
		||||
  type discrete = option<{"xs": array<float>, "ys": array<float>}>
 | 
			
		||||
 | 
			
		||||
  type props
 | 
			
		||||
  type makeType = props => React.element
 | 
			
		||||
  @obj external makeProps: (
 | 
			
		||||
    ~height: int=?,
 | 
			
		||||
    ~marginBottom: int=?,
 | 
			
		||||
    ~marginTop: int=?,
 | 
			
		||||
    ~maxX: float=?,
 | 
			
		||||
    ~minX: float=?,
 | 
			
		||||
    ~yMaxContinuousDomainFactor: float=?,
 | 
			
		||||
    ~yMaxDiscreteDomainFactor: float=?,
 | 
			
		||||
    ~onHover: float => (),
 | 
			
		||||
    ~continuous: option<{"xs": array<float>, "ys": array<float>}>=?,
 | 
			
		||||
    ~discrete: option<{"xs": array<float>, "ys": array<float>}>=?,
 | 
			
		||||
    ~xScale: string=?,
 | 
			
		||||
    ~yScale: string=?,
 | 
			
		||||
    ~showDistributionLines: bool=?,
 | 
			
		||||
    ~showDistributionYAxis: bool=?,
 | 
			
		||||
    ~showVerticalLine: bool=?,
 | 
			
		||||
    ~timeScale:Js.Null.t<{"unit": string, "zero": MomentRe.Moment.t}>=?,
 | 
			
		||||
    ~verticalLine: int=?,
 | 
			
		||||
    ~children: array<React.element>=?,
 | 
			
		||||
    unit // This unit is a quirk of the type system. Apparently it must exist to have optional arguments in a type
 | 
			
		||||
    ) => props = "" 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  @module("./distPlotReact.js")
 | 
			
		||||
  external make : makeType = "default"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module Styles = {
 | 
			
		||||
  open CssJs
 | 
			
		||||
  let textOverlay = style(. [position(#absolute)])
 | 
			
		||||
  let mainText = style(. [ fontSize(#em(1.1))])
 | 
			
		||||
  let secondaryText = style(. [fontSize(#em(0.9))])
 | 
			
		||||
 | 
			
		||||
  let graph = chartColor =>
 | 
			
		||||
    style(. [
 | 
			
		||||
      position(#relative),
 | 
			
		||||
      selector(. ".xAxis", [fontSize(#px(9))]),
 | 
			
		||||
      selector(. ".xAxis .domain", [ display(#none) ]),
 | 
			
		||||
      selector(. ".xAxis .tick line", [ display(#none) ]),
 | 
			
		||||
      selector(. ".xAxis .tick text", [ color(#hex("7a8998")) ]),
 | 
			
		||||
      selector(. ".chart .areaPath", [ SVG.fill(chartColor) ]),
 | 
			
		||||
      selector(. ".lollipopsLine", [ SVG.stroke(#hex("bfcad4")) ]),
 | 
			
		||||
      selector(. ".lollipopsCircle", [ SVG.stroke(#hex("bfcad4")), SVG.fill(#hex("bfcad4")) ]),
 | 
			
		||||
      selector(. ".lollipopsXAxis .domain", [ display(#none) ]),
 | 
			
		||||
      selector(. ".lollipopsXAxis .tick line", [ display(#none) ]),
 | 
			
		||||
      selector(. ".lollipopsXAxis .tick text", [ display(#none) ]),
 | 
			
		||||
      selector(.
 | 
			
		||||
        ".lollipopsTooltip",
 | 
			
		||||
        [ position(#absolute),
 | 
			
		||||
          textAlign(#center),
 | 
			
		||||
          padding(px(2)),
 | 
			
		||||
          backgroundColor(hex("bfcad4")),
 | 
			
		||||
          borderRadius(px(3)),
 | 
			
		||||
      ],
 | 
			
		||||
      ),
 | 
			
		||||
      selector(.
 | 
			
		||||
        ".lollipopsCircleMouseover",
 | 
			
		||||
        [ SVG.fill(hex("ffa500")), SVG.stroke(#hex("fff")) ],
 | 
			
		||||
      ),
 | 
			
		||||
      selector(. ".lollipopsLineMouseover", [ SVG.stroke(#hex("ffa500")) ]),
 | 
			
		||||
    ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
let make = (
 | 
			
		||||
  ~color=#hex("111"),
 | 
			
		||||
  ~discrete=?,
 | 
			
		||||
  ~height=200,
 | 
			
		||||
  ~maxX=?,
 | 
			
		||||
  ~minX=?,
 | 
			
		||||
  ~yMaxDiscreteDomainFactor=?,
 | 
			
		||||
  ~yMaxContinuousDomainFactor=?,
 | 
			
		||||
  ~onHover: float => unit=_ => (),
 | 
			
		||||
  ~continuous=?,
 | 
			
		||||
  ~xScale=?,
 | 
			
		||||
  ~yScale=?,
 | 
			
		||||
  ~showDistributionLines=false,
 | 
			
		||||
  ~showDistributionYAxis=false,
 | 
			
		||||
  ~showVerticalLine=false,
 | 
			
		||||
  ~timeScale=?,
 | 
			
		||||
) =>
 | 
			
		||||
  <div style={Styles.graph(color)}>
 | 
			
		||||
    <RawPlot
 | 
			
		||||
      ?maxX
 | 
			
		||||
      ?minX
 | 
			
		||||
      ?yMaxDiscreteDomainFactor
 | 
			
		||||
      ?yMaxContinuousDomainFactor
 | 
			
		||||
      ?xScale
 | 
			
		||||
      ?yScale
 | 
			
		||||
      ?timeScale
 | 
			
		||||
      discrete={discrete |> E.O.fmap(XYShape.T.toJs)}
 | 
			
		||||
      height
 | 
			
		||||
      marginBottom=50
 | 
			
		||||
      marginTop=0
 | 
			
		||||
      onHover
 | 
			
		||||
      continuous={continuous |> E.O.fmap(XYShape.T.toJs)}
 | 
			
		||||
      showDistributionLines
 | 
			
		||||
      showDistributionYAxis
 | 
			
		||||
      showVerticalLine
 | 
			
		||||
    />
 | 
			
		||||
  </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
import * as _ from "lodash";
 | 
			
		||||
import { createClassFromSpec } from "react-vega";
 | 
			
		||||
import spec from "./spec-percentiles";
 | 
			
		||||
 | 
			
		||||
const PercentilesChart = createClassFromSpec({
 | 
			
		||||
  spec,
 | 
			
		||||
  style: "width: 100%",
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export { PercentilesChart };
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
@module("./PercentilesChart.js")
 | 
			
		||||
external percentilesChart: React.element = "PercentilesChart"
 | 
			
		||||
 | 
			
		||||
module Internal = {
 | 
			
		||||
  type props
 | 
			
		||||
  type makeType = props => React.element
 | 
			
		||||
  type dataType = { "facet": array<
 | 
			
		||||
    {
 | 
			
		||||
      "p1": float,
 | 
			
		||||
      "p10": float,
 | 
			
		||||
      "p20": float,
 | 
			
		||||
      "p30": float,
 | 
			
		||||
      "p40": float,
 | 
			
		||||
      "p5": float,
 | 
			
		||||
      "p50": float,
 | 
			
		||||
      "p60": float,
 | 
			
		||||
      "p70": float,
 | 
			
		||||
      "p80": float,
 | 
			
		||||
      "p90": float,
 | 
			
		||||
      "p95": float,
 | 
			
		||||
      "p99": float,
 | 
			
		||||
      "x": float,
 | 
			
		||||
    }>}
 | 
			
		||||
  @obj external makeProps: (~data: dataType, ~signalListeners: list<string>,~children:React.element, unit) => props = ""
 | 
			
		||||
 | 
			
		||||
  @module("./PercentilesChart.js")
 | 
			
		||||
  external make : makeType = "PercentilesChart"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
@module("./PercentilesChart.js")
 | 
			
		||||
let make = (~dists: array<(float, DistTypes.distPlus)>, ~children=React.null) => {
 | 
			
		||||
  let data = dists |> E.A.fmap(((x, r)) =>
 | 
			
		||||
    {
 | 
			
		||||
      "x": x,
 | 
			
		||||
      "p1": r |> DistPlus.T.Integral.yToX(0.01),
 | 
			
		||||
      "p5": r |> DistPlus.T.Integral.yToX(0.05),
 | 
			
		||||
      "p10": r |> DistPlus.T.Integral.yToX(0.1),
 | 
			
		||||
      "p20": r |> DistPlus.T.Integral.yToX(0.2),
 | 
			
		||||
      "p30": r |> DistPlus.T.Integral.yToX(0.3),
 | 
			
		||||
      "p40": r |> DistPlus.T.Integral.yToX(0.4),
 | 
			
		||||
      "p50": r |> DistPlus.T.Integral.yToX(0.5),
 | 
			
		||||
      "p60": r |> DistPlus.T.Integral.yToX(0.6),
 | 
			
		||||
      "p70": r |> DistPlus.T.Integral.yToX(0.7),
 | 
			
		||||
      "p80": r |> DistPlus.T.Integral.yToX(0.8),
 | 
			
		||||
      "p90": r |> DistPlus.T.Integral.yToX(0.9),
 | 
			
		||||
      "p95": r |> DistPlus.T.Integral.yToX(0.95),
 | 
			
		||||
      "p99": r |> DistPlus.T.Integral.yToX(0.99),
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
  Js.log3("Data", dists, data)
 | 
			
		||||
  let da = {"facet": data}
 | 
			
		||||
  <Internal data=da signalListeners=list{}>children</Internal>
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,658 +0,0 @@
 | 
			
		|||
const _ = require('lodash');
 | 
			
		||||
const d3 = require('d3');
 | 
			
		||||
const moment = require('moment');
 | 
			
		||||
require('./styles.css');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param arr
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
function exists(arr) {
 | 
			
		||||
  return arr.find(num => _.isFinite(num));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class DistPlotD3 {
 | 
			
		||||
 | 
			
		||||
  constructor() {
 | 
			
		||||
    this.attrs = {
 | 
			
		||||
      svgWidth: 400,
 | 
			
		||||
      svgHeight: 400,
 | 
			
		||||
      marginTop: 5,
 | 
			
		||||
      marginBottom: 5,
 | 
			
		||||
      marginRight: 50,
 | 
			
		||||
      marginLeft: 5,
 | 
			
		||||
 | 
			
		||||
      container: null,
 | 
			
		||||
 | 
			
		||||
      // X
 | 
			
		||||
      minX: null,
 | 
			
		||||
      maxX: null,
 | 
			
		||||
      xScaleType: 'linear',
 | 
			
		||||
      xScaleTimeOptions: null,
 | 
			
		||||
      xScaleLogBase: 10,
 | 
			
		||||
 | 
			
		||||
      // Y
 | 
			
		||||
      minY: null,
 | 
			
		||||
      maxY: null,
 | 
			
		||||
      yScaleType: 'linear',
 | 
			
		||||
      yScaleTimeOptions: null,
 | 
			
		||||
      yScaleLogBase: 10,
 | 
			
		||||
 | 
			
		||||
      xMinContinuousDomainFactor: 1,
 | 
			
		||||
      xMaxContinuousDomainFactor: 1,
 | 
			
		||||
      yMaxContinuousDomainFactor: 1,
 | 
			
		||||
      yMaxDiscreteDomainFactor: 1,
 | 
			
		||||
 | 
			
		||||
      showDistributionYAxis: false,
 | 
			
		||||
      showDistributionLines: true,
 | 
			
		||||
 | 
			
		||||
      areaColors: ['#E1E5EC', '#E1E5EC'],
 | 
			
		||||
      verticalLine: 110,
 | 
			
		||||
      showVerticalLine: true,
 | 
			
		||||
      data: {
 | 
			
		||||
        continuous: null,
 | 
			
		||||
        discrete: null,
 | 
			
		||||
      },
 | 
			
		||||
      onHover: (e) => {
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    this.calc = {
 | 
			
		||||
      chartLeftMargin: null,
 | 
			
		||||
      chartTopMargin: null,
 | 
			
		||||
      chartWidth: null,
 | 
			
		||||
      chartHeight: null,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    this.chart = null;
 | 
			
		||||
    this.svg = null;
 | 
			
		||||
    this._container = null;
 | 
			
		||||
 | 
			
		||||
    this.formatDates = this.formatDates.bind(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {string} name
 | 
			
		||||
   * @param value
 | 
			
		||||
   * @returns {DistPlotD3}
 | 
			
		||||
   */
 | 
			
		||||
  set(name, value) {
 | 
			
		||||
    _.set(this.attrs, [name], value);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param data
 | 
			
		||||
   * @returns {DistPlotD3}
 | 
			
		||||
   */
 | 
			
		||||
  data(data) {
 | 
			
		||||
    const continuousXs = _.get(data, 'continuous.xs', []);
 | 
			
		||||
    const continuousYs = _.get(data, 'continuous.ys', []);
 | 
			
		||||
    const discreteXs = _.get(data, 'discrete.xs', []);
 | 
			
		||||
    const discreteYs = _.get(data, 'discrete.ys', []);
 | 
			
		||||
    this.attrs.data = data;
 | 
			
		||||
    this.attrs.data.continuous = {
 | 
			
		||||
      xs: continuousXs,
 | 
			
		||||
      ys: continuousYs,
 | 
			
		||||
    };
 | 
			
		||||
    this.attrs.data.discrete = {
 | 
			
		||||
      xs: discreteXs,
 | 
			
		||||
      ys: discreteYs,
 | 
			
		||||
    };
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    this._container = d3.select(this.attrs.container);
 | 
			
		||||
    if (this._container.node() === null) {
 | 
			
		||||
      throw new Error('Container for D3 is not defined.');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!['log', 'linear'].includes(this.attrs.xScaleType)) {
 | 
			
		||||
      throw new Error('X-scale type should be either "log" or "linear".');
 | 
			
		||||
    }
 | 
			
		||||
    if (!['log', 'linear'].includes(this.attrs.yScaleType)) {
 | 
			
		||||
      throw new Error('Y-scale type should be either "log" or "linear".');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Log Scale.
 | 
			
		||||
    if (this.attrs.xScaleType === 'log') {
 | 
			
		||||
      this.logFilter('continuous', (x, y) => x > 0);
 | 
			
		||||
      this.logFilter('discrete', (x, y) => x > 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (this.attrs.yScaleType === 'log') {
 | 
			
		||||
      this.logFilter('continuous', (x, y) => y > 0);
 | 
			
		||||
      this.logFilter('discrete', (x, y) => y > 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
      this.attrs.xScaleType === 'log'
 | 
			
		||||
      && this.attrs.minX !== null
 | 
			
		||||
      && this.attrs.minX < 0
 | 
			
		||||
    ) {
 | 
			
		||||
      console.warn('minX should be positive.');
 | 
			
		||||
      this.attrs.minX = undefined;
 | 
			
		||||
    }
 | 
			
		||||
    if (
 | 
			
		||||
      this.attrs.yScaleType === 'log'
 | 
			
		||||
      && this.attrs.minY !== null
 | 
			
		||||
      && this.attrs.minY < 0
 | 
			
		||||
    ) {
 | 
			
		||||
      console.warn('minY should be positive.');
 | 
			
		||||
      this.attrs.minY = undefined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Fields.
 | 
			
		||||
    const fields = [
 | 
			
		||||
      'marginLeft', 'marginRight',
 | 
			
		||||
      'marginTop', 'marginBottom',
 | 
			
		||||
      'svgWidth', 'svgHeight',
 | 
			
		||||
      'yMaxContinuousDomainFactor',
 | 
			
		||||
      'yMaxDiscreteDomainFactor',
 | 
			
		||||
      'xScaleLogBase', 'yScaleLogBase',
 | 
			
		||||
    ];
 | 
			
		||||
    for (const field of fields) {
 | 
			
		||||
      if (!_.isNumber(this.attrs[field])) {
 | 
			
		||||
        throw new Error(`${field} should be a number.`);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Sets the width from the DOM element.
 | 
			
		||||
    const containerRect = this._container.node().getBoundingClientRect();
 | 
			
		||||
    if (containerRect.width > 0) {
 | 
			
		||||
      this.attrs.svgWidth = containerRect.width;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Calculated properties.
 | 
			
		||||
    this.calc.chartLeftMargin = this.attrs.marginLeft;
 | 
			
		||||
    this.calc.chartTopMargin = this.attrs.marginTop;
 | 
			
		||||
    this.calc.chartWidth = this.attrs.svgWidth
 | 
			
		||||
      - this.attrs.marginRight
 | 
			
		||||
      - this.attrs.marginLeft;
 | 
			
		||||
    this.calc.chartHeight = this.attrs.svgHeight
 | 
			
		||||
      - this.attrs.marginBottom
 | 
			
		||||
      - this.attrs.marginTop;
 | 
			
		||||
 | 
			
		||||
    // Add svg.
 | 
			
		||||
    this.svg = this._container
 | 
			
		||||
      .createObject({ tag: 'svg', selector: 'svg-chart-container' })
 | 
			
		||||
      .attr('width', '100%')
 | 
			
		||||
      .attr('height', this.attrs.svgHeight)
 | 
			
		||||
      .attr('pointer-events', 'none');
 | 
			
		||||
 | 
			
		||||
    // Add container 'g' (empty) element.
 | 
			
		||||
    this.chart = this.svg
 | 
			
		||||
      .createObject({ tag: 'g', selector: 'chart' })
 | 
			
		||||
      .attr(
 | 
			
		||||
        'transform',
 | 
			
		||||
        `translate(${this.calc.chartLeftMargin}, ${this.calc.chartTopMargin})`,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const common = this.getCommonThings();
 | 
			
		||||
      if (this.hasDate('continuous')) {
 | 
			
		||||
        this.addDistributionChart(common);
 | 
			
		||||
      }
 | 
			
		||||
      if (this.hasDate('discrete')) {
 | 
			
		||||
        this.addLollipopsChart(common);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      this._container.selectAll("*").remove();
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @returns {*}
 | 
			
		||||
   */
 | 
			
		||||
  getCommonThings() {
 | 
			
		||||
    // Boundaries.
 | 
			
		||||
    const xMin = exists([
 | 
			
		||||
      this.attrs.minX,
 | 
			
		||||
      d3.min(this.attrs.data.continuous.xs),
 | 
			
		||||
      d3.min(this.attrs.data.discrete.xs),
 | 
			
		||||
    ]);
 | 
			
		||||
    const xMax = exists([
 | 
			
		||||
      this.attrs.maxX,
 | 
			
		||||
      d3.max(this.attrs.data.continuous.xs),
 | 
			
		||||
      d3.max(this.attrs.data.discrete.xs),
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    const yMin = exists([
 | 
			
		||||
      this.attrs.minY,
 | 
			
		||||
      d3.min(this.attrs.data.continuous.ys),
 | 
			
		||||
      d3.min(this.attrs.data.discrete.ys),
 | 
			
		||||
    ]);
 | 
			
		||||
    const yMax = exists([
 | 
			
		||||
      this.attrs.maxY,
 | 
			
		||||
      d3.max(this.attrs.data.continuous.ys),
 | 
			
		||||
      d3.max(this.attrs.data.discrete.ys),
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    // Errors.
 | 
			
		||||
    if (!_.isFinite(xMin)) throw new Error('xMin is undefined');
 | 
			
		||||
    if (!_.isFinite(xMax)) throw new Error('xMax is undefined');
 | 
			
		||||
    if (!_.isFinite(yMin)) throw new Error('yMin is undefined');
 | 
			
		||||
    if (!_.isFinite(yMax)) throw new Error('yMax is undefined');
 | 
			
		||||
 | 
			
		||||
    // X-domains.
 | 
			
		||||
    const xMinDomainFactor = _.get(this.attrs, 'xMinContinuousDomainFactor', 1);
 | 
			
		||||
    const xMaxDomainFactor = _.get(this.attrs, 'xMaxContinuousDomainFactor', 1);
 | 
			
		||||
    const yMinDomainFactor = _.get(this.attrs, 'yMinContinuousDomainFactor', 1);
 | 
			
		||||
    const yMaxDomainFactor = _.get(this.attrs, 'yMaxContinuousDomainFactor', 1);
 | 
			
		||||
 | 
			
		||||
    const xMinDomain = xMin * xMinDomainFactor;
 | 
			
		||||
    const xMaxDomain = xMax * xMaxDomainFactor;
 | 
			
		||||
    const yMinDomain = yMin * yMinDomainFactor;
 | 
			
		||||
    const yMaxDomain = yMax * yMaxDomainFactor;
 | 
			
		||||
 | 
			
		||||
    // X-scale.
 | 
			
		||||
    const xScale = this.attrs.xScaleType === 'linear'
 | 
			
		||||
      ? d3.scaleLinear()
 | 
			
		||||
        .domain([xMinDomain, xMaxDomain])
 | 
			
		||||
        .range([0, this.calc.chartWidth])
 | 
			
		||||
      : d3.scaleLog()
 | 
			
		||||
        .base(this.attrs.xScaleLogBase)
 | 
			
		||||
        .domain([xMinDomain, xMaxDomain])
 | 
			
		||||
        .range([0, this.calc.chartWidth]);
 | 
			
		||||
 | 
			
		||||
    // Y-scale.
 | 
			
		||||
    const yScale = this.attrs.yScaleType === 'linear'
 | 
			
		||||
      ? d3.scaleLinear()
 | 
			
		||||
        .domain([yMinDomain, yMaxDomain])
 | 
			
		||||
        .range([this.calc.chartHeight, 0])
 | 
			
		||||
      : d3.scaleLog()
 | 
			
		||||
        .base(this.attrs.yScaleLogBase)
 | 
			
		||||
        .domain([yMinDomain, yMaxDomain])
 | 
			
		||||
        .range([this.calc.chartHeight, 0]);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      xMin, xMax,
 | 
			
		||||
      xScale, yScale,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param common
 | 
			
		||||
   */
 | 
			
		||||
  addDistributionChart(common) {
 | 
			
		||||
    const areaColorRange = d3.scaleOrdinal().range(this.attrs.areaColors);
 | 
			
		||||
    const dataPoints = [this.getDataPoints('continuous')];
 | 
			
		||||
 | 
			
		||||
    const { xMin, xMax, xScale, yScale } = common;
 | 
			
		||||
 | 
			
		||||
    // X-axis.
 | 
			
		||||
    let xAxis = null;
 | 
			
		||||
    if (!!this.attrs.xScaleTimeOptions) {
 | 
			
		||||
      // Calculates the projection on X-axis.
 | 
			
		||||
      const zero = _.get(this.attrs, 'xScaleTimeOptions.zero', moment());
 | 
			
		||||
      const unit = _.get(this.attrs, 'xScaleTimeOptions.unit', 'years');
 | 
			
		||||
      const diff = Math.abs(xMax - xMin);
 | 
			
		||||
      const left = zero.clone().add(xMin, unit);
 | 
			
		||||
      const right = left.clone().add(diff, unit);
 | 
			
		||||
 | 
			
		||||
      // X-time-scale.
 | 
			
		||||
      const xScaleTime = d3.scaleTime()
 | 
			
		||||
        .domain([left.toDate(), right.toDate()])
 | 
			
		||||
        .nice()
 | 
			
		||||
        .range([0, this.calc.chartWidth]);
 | 
			
		||||
 | 
			
		||||
      xAxis = d3.axisBottom()
 | 
			
		||||
        .scale(xScaleTime)
 | 
			
		||||
        .ticks(this.getTimeTicksByStr(unit))
 | 
			
		||||
        .tickFormat(this.formatDates);
 | 
			
		||||
    } else {
 | 
			
		||||
      xAxis = d3.axisBottom(xScale)
 | 
			
		||||
        .ticks(3)
 | 
			
		||||
        .tickFormat(d => {
 | 
			
		||||
          if (Math.abs(d) < 1) {
 | 
			
		||||
            return d3.format('.2')(d);
 | 
			
		||||
          } else if (xMin > 1000 && xMax < 3000) {
 | 
			
		||||
            // Condition which identifies years; 2019, 2020, 2021.
 | 
			
		||||
            return d3.format('.0')(d);
 | 
			
		||||
          } else {
 | 
			
		||||
            const prefix = d3.formatPrefix('.0', d);
 | 
			
		||||
            return prefix(d).replace('G', 'B');
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Y-axis.
 | 
			
		||||
    const yAxis = d3.axisRight(yScale);
 | 
			
		||||
 | 
			
		||||
    // Add axis.
 | 
			
		||||
    this.chart
 | 
			
		||||
      .createObject({ tag: 'g', selector: 'x-axis' })
 | 
			
		||||
      .attr('transform', `translate(0, ${this.calc.chartHeight})`)
 | 
			
		||||
      .call(xAxis);
 | 
			
		||||
 | 
			
		||||
    if (this.attrs.showDistributionYAxis) {
 | 
			
		||||
      this.chart
 | 
			
		||||
        .createObject({ tag: 'g', selector: 'y-axis' })
 | 
			
		||||
        .call(yAxis);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Draw area.
 | 
			
		||||
    const area = d3.area()
 | 
			
		||||
      .x(d => xScale(d.x))
 | 
			
		||||
      .y1(d => yScale(d.y))
 | 
			
		||||
      .y0(this.calc.chartHeight);
 | 
			
		||||
 | 
			
		||||
    this.chart
 | 
			
		||||
      .createObjectsWithData({
 | 
			
		||||
        tag: 'path',
 | 
			
		||||
        selector: 'area-path',
 | 
			
		||||
        data: dataPoints,
 | 
			
		||||
      })
 | 
			
		||||
      .attr('d', area)
 | 
			
		||||
      .attr('fill', (d, i) => areaColorRange(i))
 | 
			
		||||
      .attr('opacity', (d, i) => i === 0 ? 0.7 : 0.5);
 | 
			
		||||
 | 
			
		||||
    // Draw line.
 | 
			
		||||
    if (this.attrs.showDistributionLines) {
 | 
			
		||||
      const line = d3.line()
 | 
			
		||||
        .x(d => xScale(d.x))
 | 
			
		||||
        .y(d => yScale(d.y));
 | 
			
		||||
 | 
			
		||||
      this.chart
 | 
			
		||||
        .createObjectsWithData({
 | 
			
		||||
          tag: 'path',
 | 
			
		||||
          selector: 'line-path',
 | 
			
		||||
          data: dataPoints,
 | 
			
		||||
        })
 | 
			
		||||
        .attr('d', line)
 | 
			
		||||
        .attr('id', (d, i) => 'line-' + (i + 1))
 | 
			
		||||
        .attr('opacity', (d, i) => i === 0 ? 0.7 : 1)
 | 
			
		||||
        .attr('fill', 'none');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.attrs.showVerticalLine) {
 | 
			
		||||
      this.chart
 | 
			
		||||
        .createObject({ tag: 'line', selector: 'v-line' })
 | 
			
		||||
        .attr('x1', xScale(this.attrs.verticalLine))
 | 
			
		||||
        .attr('x2', xScale(this.attrs.verticalLine))
 | 
			
		||||
        .attr('y1', 0)
 | 
			
		||||
        .attr('y2', this.calc.chartHeight)
 | 
			
		||||
        .attr('stroke-width', 1.5)
 | 
			
		||||
        .attr('stroke-dasharray', '6 6')
 | 
			
		||||
        .attr('stroke', 'steelblue');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const hoverLine = this.chart
 | 
			
		||||
      .createObject({ tag: 'line', selector: 'hover-line' })
 | 
			
		||||
      .attr('x1', 0)
 | 
			
		||||
      .attr('x2', 0)
 | 
			
		||||
      .attr('y1', 0)
 | 
			
		||||
      .attr('y2', this.calc.chartHeight)
 | 
			
		||||
      .attr('opacity', 0)
 | 
			
		||||
      .attr('stroke-width', 1.5)
 | 
			
		||||
      .attr('stroke-dasharray', '6 6')
 | 
			
		||||
      .attr('stroke', '#22313F');
 | 
			
		||||
 | 
			
		||||
    // Add drawing rectangle.
 | 
			
		||||
    {
 | 
			
		||||
      const context = this;
 | 
			
		||||
 | 
			
		||||
      function mouseover() {
 | 
			
		||||
        const mouse = d3.mouse(this);
 | 
			
		||||
        hoverLine
 | 
			
		||||
          .attr('opacity', 1)
 | 
			
		||||
          .attr('x1', mouse[0])
 | 
			
		||||
          .attr('x2', mouse[0]);
 | 
			
		||||
        const xValue = xScale.invert(mouse[0]);
 | 
			
		||||
        context.attrs.onHover(xValue);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      function mouseout() {
 | 
			
		||||
        hoverLine.attr('opacity', 0);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.chart
 | 
			
		||||
        .createObject({ tag: 'rect', selector: 'mouse-rect' })
 | 
			
		||||
        .attr('width', this.calc.chartWidth)
 | 
			
		||||
        .attr('height', this.calc.chartHeight)
 | 
			
		||||
        .attr('fill', 'transparent')
 | 
			
		||||
        .attr('pointer-events', 'all')
 | 
			
		||||
        .on('mouseover', mouseover)
 | 
			
		||||
        .on('mousemove', mouseover)
 | 
			
		||||
        .on('mouseout', mouseout);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {object} common
 | 
			
		||||
   * @param {object} common.xScale
 | 
			
		||||
   * @param {object} common.yScale
 | 
			
		||||
   */
 | 
			
		||||
  addLollipopsChart(common) {
 | 
			
		||||
    const data = this.getDataPoints('discrete');
 | 
			
		||||
 | 
			
		||||
    const yMin = 0.;
 | 
			
		||||
    const yMax = d3.max(this.attrs.data.discrete.ys);
 | 
			
		||||
 | 
			
		||||
    // X axis.
 | 
			
		||||
    this.chart.append('g')
 | 
			
		||||
      .attr('class', 'lollipops-x-axis')
 | 
			
		||||
      .attr('transform', `translate(0, ${this.calc.chartHeight})`)
 | 
			
		||||
      .call(d3.axisBottom(common.xScale));
 | 
			
		||||
 | 
			
		||||
    // Y-domain.
 | 
			
		||||
    const yMinDomainFactor = _.get(this.attrs, 'yMinDiscreteDomainFactor', 1);
 | 
			
		||||
    const yMaxDomainFactor = _.get(this.attrs, 'yMaxDiscreteDomainFactor', 1);
 | 
			
		||||
    const yMinDomain = yMin * yMinDomainFactor;
 | 
			
		||||
    const yMaxDomain = yMax * yMaxDomainFactor;
 | 
			
		||||
 | 
			
		||||
    // Y-scale.
 | 
			
		||||
    const yScale = this.attrs.yScaleType === 'linear'
 | 
			
		||||
      ? d3.scaleLinear()
 | 
			
		||||
        .domain([yMinDomain, yMaxDomain])
 | 
			
		||||
        .range([this.calc.chartHeight, 0])
 | 
			
		||||
      : d3.scaleLog()
 | 
			
		||||
        .base(this.attrs.yScaleLogBase)
 | 
			
		||||
        .domain([yMinDomain, yMaxDomain])
 | 
			
		||||
        .range([this.calc.chartHeight, 0]);
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    const yTicks = Math.floor(this.calc.chartHeight / 20);
 | 
			
		||||
    const yAxis = d3.axisLeft(yScale).ticks(yTicks);
 | 
			
		||||
 | 
			
		||||
    // Adds 'g' for an y-axis.
 | 
			
		||||
    this.chart.append('g')
 | 
			
		||||
      .attr('class', 'lollipops-y-axis')
 | 
			
		||||
      .attr('transform', `translate(${this.calc.chartWidth}, 0)`)
 | 
			
		||||
      .call(yAxis);
 | 
			
		||||
 | 
			
		||||
    const thi$ = this;
 | 
			
		||||
 | 
			
		||||
    function showTooltip(d) {
 | 
			
		||||
      thi$.chart.select('.lollipops-line-' + d.id)
 | 
			
		||||
        .classed('lollipops-line-mouseover', true);
 | 
			
		||||
      thi$.chart.select('.lollipops-circle-' + d.id)
 | 
			
		||||
        .classed('lollipops-circle-mouseover', true)
 | 
			
		||||
        .attr('r', 6);
 | 
			
		||||
      tooltip.transition()
 | 
			
		||||
        .style('opacity', .9);
 | 
			
		||||
      tooltip.html(`x: ${d.x}, y: ${(d.y * 100).toFixed(1)}%`)
 | 
			
		||||
        .style('left', (common.xScale(d.x) + 60) + 'px')
 | 
			
		||||
        .style('top', yScale(d.y) + 'px');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function hideTooltip(d) {
 | 
			
		||||
      thi$.chart.select('.lollipops-line-' + d.id)
 | 
			
		||||
        .classed('lollipops-line-mouseover', false);
 | 
			
		||||
      thi$.chart.select('.lollipops-circle-' + d.id)
 | 
			
		||||
        .classed('lollipops-circle-mouseover', false)
 | 
			
		||||
        .attr('r', 4);
 | 
			
		||||
      tooltip.transition()
 | 
			
		||||
        .style('opacity', 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Lines.
 | 
			
		||||
    this.chart.selectAll('lollipops-line')
 | 
			
		||||
      .data(data)
 | 
			
		||||
      .enter()
 | 
			
		||||
      .append('line')
 | 
			
		||||
      .attr('class', 'lollipops-line')
 | 
			
		||||
      .attr('class', d => 'lollipops-line lollipops-line-' + d.id)
 | 
			
		||||
      .attr('x1', d => common.xScale(d.x))
 | 
			
		||||
      .attr('x2', d => common.xScale(d.x))
 | 
			
		||||
      .attr('y1', d => yScale(d.y))
 | 
			
		||||
      .attr('y2', yScale(yMin));
 | 
			
		||||
 | 
			
		||||
    // Define the div for the tooltip
 | 
			
		||||
    const tooltip = this._container.append('div')
 | 
			
		||||
      .attr('class', 'lollipop-tooltip')
 | 
			
		||||
      .style('opacity', 0);
 | 
			
		||||
 | 
			
		||||
    // Circles.
 | 
			
		||||
    this.chart.selectAll('lollipops-circle')
 | 
			
		||||
      .data(data)
 | 
			
		||||
      .enter()
 | 
			
		||||
      .append('circle')
 | 
			
		||||
      .attr('class', d => 'lollipops-circle lollipops-circle-' + d.id)
 | 
			
		||||
      .attr('cx', d => common.xScale(d.x))
 | 
			
		||||
      .attr('cy', d => yScale(d.y))
 | 
			
		||||
      .attr('r', '4');
 | 
			
		||||
 | 
			
		||||
    // Rectangles.
 | 
			
		||||
    this.chart.selectAll('lollipops-rectangle')
 | 
			
		||||
      .data(data)
 | 
			
		||||
      .enter()
 | 
			
		||||
      .append('rect')
 | 
			
		||||
      .attr('width', 30)
 | 
			
		||||
      .attr('height', d => this.calc.chartHeight - yScale(d.y) + 10)
 | 
			
		||||
      .attr('x', d => common.xScale(d.x) - 15)
 | 
			
		||||
      .attr('y', d => yScale(d.y) - 10)
 | 
			
		||||
      .attr('opacity', 0)
 | 
			
		||||
      .attr('pointer-events', 'all')
 | 
			
		||||
      .on('mouseover', showTooltip)
 | 
			
		||||
      .on('mouseout', hideTooltip)
 | 
			
		||||
    ;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param ts
 | 
			
		||||
   * @returns {string}
 | 
			
		||||
   */
 | 
			
		||||
  formatDates(ts) {
 | 
			
		||||
    return moment(ts).format('MMMM Do YYYY');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {string} unit
 | 
			
		||||
   * @returns {*}
 | 
			
		||||
   */
 | 
			
		||||
  getTimeTicksByStr(unit) {
 | 
			
		||||
    switch (unit) {
 | 
			
		||||
      case 'months':
 | 
			
		||||
        return d3.timeMonth.every(4);
 | 
			
		||||
      case 'quarters':
 | 
			
		||||
        // It is temporary solution, but it works
 | 
			
		||||
        // if the difference between edge dates is not
 | 
			
		||||
        // much more than 10 units.
 | 
			
		||||
        return d3.timeMonth.every(12);
 | 
			
		||||
      case 'hours':
 | 
			
		||||
        return d3.timeHour.every(10);
 | 
			
		||||
      case 'days':
 | 
			
		||||
        return d3.timeDay.every(7);
 | 
			
		||||
      case 'seconds':
 | 
			
		||||
        return d3.timeSecond.every(10);
 | 
			
		||||
      case 'years':
 | 
			
		||||
        return d3.timeYear.every(10);
 | 
			
		||||
      case 'minutes':
 | 
			
		||||
        return d3.timeMinute.every(10);
 | 
			
		||||
      case 'weeks':
 | 
			
		||||
        return d3.timeWeek.every(10);
 | 
			
		||||
      case 'milliseconds':
 | 
			
		||||
        return d3.timeMillisecond.every(10);
 | 
			
		||||
      default:
 | 
			
		||||
        return d3.timeYear.every(10);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {string} key
 | 
			
		||||
   * @returns {{x: number[], y: number[]}}
 | 
			
		||||
   */
 | 
			
		||||
  getDataPoints(key) {
 | 
			
		||||
    const dt = [];
 | 
			
		||||
    const emptyShape = { xs: [], ys: [] };
 | 
			
		||||
    const data = _.get(this.attrs.data, key, emptyShape);
 | 
			
		||||
    const len = data.xs.length;
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i < len; i++) {
 | 
			
		||||
      const x = data.xs[i];
 | 
			
		||||
      const y = data.ys[i];
 | 
			
		||||
      const id = i;
 | 
			
		||||
      dt.push({ x, y, id });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return dt;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {string} key
 | 
			
		||||
   * @param {function} pred
 | 
			
		||||
   * @returns {{x: number[], y: number[]}}
 | 
			
		||||
   */
 | 
			
		||||
  logFilter(key, pred) {
 | 
			
		||||
    const xs = [];
 | 
			
		||||
    const ys = [];
 | 
			
		||||
    const emptyShape = { xs: [], ys: [] };
 | 
			
		||||
    const data = _.get(this.attrs.data, key, emptyShape);
 | 
			
		||||
 | 
			
		||||
    for (let i = 0, len = data.xs.length; i < len; i++) {
 | 
			
		||||
      const x = data.xs[i];
 | 
			
		||||
      const y = data.ys[i];
 | 
			
		||||
      if (pred(x, y)) {
 | 
			
		||||
        xs.push(x);
 | 
			
		||||
        ys.push(y);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _.set(this.attrs.data, [key, 'xs'], xs);
 | 
			
		||||
    _.set(this.attrs.data, [key, 'ys'], ys);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {string} key
 | 
			
		||||
   * @returns {boolean}
 | 
			
		||||
   */
 | 
			
		||||
  hasDate(key) {
 | 
			
		||||
    const xs = _.get(this.attrs, ['data', key, 'xs']);
 | 
			
		||||
    return !!_.size(xs);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @docs: https://github.com/d3/d3-selection
 | 
			
		||||
 * @param {object} params
 | 
			
		||||
 * @param {string} params.selector
 | 
			
		||||
 * @param {string} params.tag
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
d3.selection.prototype.createObject = function createObject(params) {
 | 
			
		||||
  const selector = params.selector;
 | 
			
		||||
  const tag = params.tag;
 | 
			
		||||
  return this.insert(tag).attr('class', selector);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @docs: https://github.com/d3/d3-selection
 | 
			
		||||
 * @param {object} params
 | 
			
		||||
 * @param {string} params.selector
 | 
			
		||||
 * @param {string} params.tag
 | 
			
		||||
 * @param {*[]} params.data
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 */
 | 
			
		||||
d3.selection.prototype.createObjectsWithData = function createObjectsWithData(params) {
 | 
			
		||||
  const selector = params.selector;
 | 
			
		||||
  const tag = params.tag;
 | 
			
		||||
  const data = params.data;
 | 
			
		||||
 | 
			
		||||
  return this.selectAll('.' + selector)
 | 
			
		||||
    .data(data)
 | 
			
		||||
    .enter()
 | 
			
		||||
    .insert(tag)
 | 
			
		||||
    .attr('class', selector);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -1,81 +0,0 @@
 | 
			
		|||
import React, { useEffect } from 'react';
 | 
			
		||||
import { useSize } from 'react-use';
 | 
			
		||||
import { DistPlotD3 } from './distPlotD3';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param min
 | 
			
		||||
 * @param max
 | 
			
		||||
 * @returns {number}
 | 
			
		||||
 */
 | 
			
		||||
function getRandomInt(min, max) {
 | 
			
		||||
  min = Math.ceil(min);
 | 
			
		||||
  max = Math.floor(max);
 | 
			
		||||
  return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param props
 | 
			
		||||
 * @returns {*}
 | 
			
		||||
 * @constructor
 | 
			
		||||
 */
 | 
			
		||||
function DistPlotReact(props) {
 | 
			
		||||
  const containerRef = React.createRef();
 | 
			
		||||
  const key = "cdf-chart-react-" + getRandomInt(0, 1000);
 | 
			
		||||
  const style = !!props.width ? { width: props.width + "px" } : {};
 | 
			
		||||
 | 
			
		||||
  const [sized, { width }] = useSize(() => {
 | 
			
		||||
    return React.createElement("div", {
 | 
			
		||||
      key: "resizable-div",
 | 
			
		||||
    });
 | 
			
		||||
  }, {
 | 
			
		||||
    width: props.width,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    try {
 | 
			
		||||
      new DistPlotD3()
 | 
			
		||||
        .set('svgWidth', width)
 | 
			
		||||
        .set('svgHeight', props.height)
 | 
			
		||||
        .set('maxX', props.maxX)
 | 
			
		||||
        .set('minX', props.minX)
 | 
			
		||||
        .set('onHover', props.onHover)
 | 
			
		||||
        .set('marginBottom', props.marginBottom || 15)
 | 
			
		||||
        .set('marginLeft', 30)
 | 
			
		||||
        .set('marginRight', 30)
 | 
			
		||||
        .set('marginTop', 5)
 | 
			
		||||
        .set('showDistributionLines', props.showDistributionLines)
 | 
			
		||||
        .set('showDistributionYAxis', props.showDistributionYAxis)
 | 
			
		||||
        .set('verticalLine', props.verticalLine || 110)
 | 
			
		||||
        .set('showVerticalLine', props.showVerticalLine)
 | 
			
		||||
        .set('container', containerRef.current)
 | 
			
		||||
        .set('xScaleType', props.xScale || 'linear')
 | 
			
		||||
        .set('yScaleType', props.yScale || 'linear')
 | 
			
		||||
        .set('xScaleTimeOptions', props.timeScale)
 | 
			
		||||
        .set('yMaxContinuousDomainFactor', props.yMaxContinuousDomainFactor || 1)
 | 
			
		||||
        .set('yMaxDiscreteDomainFactor', props.yMaxDiscreteDomainFactor || 1)
 | 
			
		||||
        .data({
 | 
			
		||||
          continuous: props.continuous,
 | 
			
		||||
          discrete: props.discrete,
 | 
			
		||||
        })
 | 
			
		||||
        .render();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error("distPlotD3 Error: ", e)
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return React.createElement("div", {
 | 
			
		||||
    style: {
 | 
			
		||||
      paddingLeft: "10px",
 | 
			
		||||
      paddingRight: "10px",
 | 
			
		||||
    },
 | 
			
		||||
  }, [
 | 
			
		||||
    sized,
 | 
			
		||||
    React.createElement("div", {
 | 
			
		||||
      key,
 | 
			
		||||
      style,
 | 
			
		||||
      ref: containerRef,
 | 
			
		||||
    }),
 | 
			
		||||
  ]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default DistPlotReact;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,208 +0,0 @@
 | 
			
		|||
{
 | 
			
		||||
  "$schema": "https://vega.github.io/schema/vega/v5.json",
 | 
			
		||||
  "width": 500,
 | 
			
		||||
  "height": 400,
 | 
			
		||||
  "padding": 5,
 | 
			
		||||
  "data": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "facet",
 | 
			
		||||
      "values": [],
 | 
			
		||||
      "format": { "type": "json", "parse": { "timestamp": "date" } }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "table",
 | 
			
		||||
      "source": "facet",
 | 
			
		||||
      "transform": [
 | 
			
		||||
        {
 | 
			
		||||
          "type": "aggregate",
 | 
			
		||||
          "groupby": ["x"],
 | 
			
		||||
          "ops": [
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean",
 | 
			
		||||
            "mean"
 | 
			
		||||
          ],
 | 
			
		||||
          "fields": [
 | 
			
		||||
            "p1",
 | 
			
		||||
            "p5",
 | 
			
		||||
            "p10",
 | 
			
		||||
            "p20",
 | 
			
		||||
            "p30",
 | 
			
		||||
            "p40",
 | 
			
		||||
            "p50",
 | 
			
		||||
            "p60",
 | 
			
		||||
            "p70",
 | 
			
		||||
            "p80",
 | 
			
		||||
            "p90",
 | 
			
		||||
            "p95",
 | 
			
		||||
            "p99"
 | 
			
		||||
          ],
 | 
			
		||||
          "as": [
 | 
			
		||||
            "p1",
 | 
			
		||||
            "p5",
 | 
			
		||||
            "p10",
 | 
			
		||||
            "p20",
 | 
			
		||||
            "p30",
 | 
			
		||||
            "p40",
 | 
			
		||||
            "p50",
 | 
			
		||||
            "p60",
 | 
			
		||||
            "p70",
 | 
			
		||||
            "p80",
 | 
			
		||||
            "p90",
 | 
			
		||||
            "p95",
 | 
			
		||||
            "p99"
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "scales": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "xscale",
 | 
			
		||||
      "type": "linear",
 | 
			
		||||
      "nice": true,
 | 
			
		||||
      "domain": { "data": "facet", "field": "x" },
 | 
			
		||||
      "range": "width"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "yscale",
 | 
			
		||||
      "type": "linear",
 | 
			
		||||
      "range": "height",
 | 
			
		||||
      "nice": true,
 | 
			
		||||
      "zero": true,
 | 
			
		||||
      "domain": { "data": "facet", "field": "p99" }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "axes": [
 | 
			
		||||
    {
 | 
			
		||||
      "orient": "bottom",
 | 
			
		||||
      "scale": "xscale",
 | 
			
		||||
      "grid": false,
 | 
			
		||||
      "tickSize": 2,
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "grid": { "enter": { "stroke": { "value": "#ccc" } } },
 | 
			
		||||
        "ticks": { "enter": { "stroke": { "value": "#ccc" } } }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "orient": "left",
 | 
			
		||||
      "scale": "yscale",
 | 
			
		||||
      "grid": false,
 | 
			
		||||
      "domain": false,
 | 
			
		||||
      "tickSize": 2,
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "grid": { "enter": { "stroke": { "value": "#ccc" } } },
 | 
			
		||||
        "ticks": { "enter": { "stroke": { "value": "#ccc" } } }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "marks": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "area",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "enter": { "fill": { "value": "#4C78A8" } },
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p1" },
 | 
			
		||||
          "y2": { "scale": "yscale", "field": "p99" },
 | 
			
		||||
          "opacity": { "value": 0.05 }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "area",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "enter": { "fill": { "value": "#4C78A8" } },
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p5" },
 | 
			
		||||
          "y2": { "scale": "yscale", "field": "p95" },
 | 
			
		||||
          "opacity": { "value": 0.1 }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "area",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "enter": { "fill": { "value": "#4C78A8" } },
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p10" },
 | 
			
		||||
          "y2": { "scale": "yscale", "field": "p90" },
 | 
			
		||||
          "opacity": { "value": 0.15 }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "area",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "enter": { "fill": { "value": "#4C78A8" } },
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p20" },
 | 
			
		||||
          "y2": { "scale": "yscale", "field": "p80" },
 | 
			
		||||
          "opacity": { "value": 0.2 }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "area",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "enter": { "fill": { "value": "#4C78A8" } },
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p30" },
 | 
			
		||||
          "y2": { "scale": "yscale", "field": "p70" },
 | 
			
		||||
          "opacity": { "value": 0.2 }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "area",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "enter": { "fill": { "value": "#4C78A8" } },
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p40" },
 | 
			
		||||
          "y2": { "scale": "yscale", "field": "p60" },
 | 
			
		||||
          "opacity": { "value": 0.2 }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "line",
 | 
			
		||||
      "from": { "data": "table" },
 | 
			
		||||
      "encode": {
 | 
			
		||||
        "update": {
 | 
			
		||||
          "interpolate": { "value": "monotone" },
 | 
			
		||||
          "stroke": { "value": "#4C78A8" },
 | 
			
		||||
          "strokeWidth": { "value": 2 },
 | 
			
		||||
          "opacity": { "value": 0.8 },
 | 
			
		||||
          "x": { "scale": "xscale", "field": "x" },
 | 
			
		||||
          "y": { "scale": "yscale", "field": "p50" }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
.lollipops-line-mouseover {
 | 
			
		||||
    stroke-dasharray: 4;
 | 
			
		||||
    animation: dash 2s linear infinite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes dash {
 | 
			
		||||
    to {
 | 
			
		||||
        stroke-dashoffset: 1000;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,31 +0,0 @@
 | 
			
		|||
module JS = {
 | 
			
		||||
  @deriving(abstract)
 | 
			
		||||
  type numberPresentation = {
 | 
			
		||||
    value: string,
 | 
			
		||||
    power: option<float>,
 | 
			
		||||
    symbol: option<string>,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @module("./numberShower.js")
 | 
			
		||||
  external numberShow: (float, int) => numberPresentation = "numberShow"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let sup = {
 | 
			
		||||
  open CssJs
 | 
			
		||||
  style(. [ fontSize(#em(0.6)), verticalAlign(#super) ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
let make = (~number, ~precision) => {
 | 
			
		||||
  let numberWithPresentation = JS.numberShow(number, precision)
 | 
			
		||||
  <span>
 | 
			
		||||
    {JS.valueGet(numberWithPresentation) |> React.string}
 | 
			
		||||
    {JS.symbolGet(numberWithPresentation) |> E.O.React.fmapOrNull(React.string)}
 | 
			
		||||
    {JS.powerGet(numberWithPresentation) |> E.O.React.fmapOrNull(e =>
 | 
			
		||||
      <span>
 | 
			
		||||
        {j`\\u00b710` |> React.string}
 | 
			
		||||
        <span style=sup> {e |> E.Float.toString |> React.string} </span>
 | 
			
		||||
      </span>
 | 
			
		||||
    )}
 | 
			
		||||
  </span>
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,65 +0,0 @@
 | 
			
		|||
// 105 -> 3
 | 
			
		||||
const orderOfMagnitudeNum = (n) => {
 | 
			
		||||
  return Math.pow(10, n);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 105 -> 3
 | 
			
		||||
const orderOfMagnitude = (n) => {
 | 
			
		||||
  return Math.floor(Math.log(n) / Math.LN10 + 0.000000001);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function withXSigFigs(number, sigFigs) {
 | 
			
		||||
  const withPrecision = number.toPrecision(sigFigs);
 | 
			
		||||
  const formatted = Number(withPrecision);
 | 
			
		||||
  return `${formatted}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NumberShower {
 | 
			
		||||
  constructor(number, precision = 2) {
 | 
			
		||||
    this.number = number;
 | 
			
		||||
    this.precision = precision;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  convert() {
 | 
			
		||||
    const number = Math.abs(this.number);
 | 
			
		||||
    const response = this.evaluate(number);
 | 
			
		||||
    if (this.number < 0) {
 | 
			
		||||
      response.value = '-' + response.value;
 | 
			
		||||
    }
 | 
			
		||||
    return response
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  metricSystem(number, order) {
 | 
			
		||||
    const newNumber = number / orderOfMagnitudeNum(order);
 | 
			
		||||
    const precision = this.precision;
 | 
			
		||||
    return `${withXSigFigs(newNumber, precision)}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  evaluate(number) {
 | 
			
		||||
    if (number === 0) {
 | 
			
		||||
      return { value: this.metricSystem(0, 0) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const order = orderOfMagnitude(number);
 | 
			
		||||
    if (order < -2) {
 | 
			
		||||
      return { value: this.metricSystem(number, order), power: order };
 | 
			
		||||
    } else if (order < 4) {
 | 
			
		||||
      return { value: this.metricSystem(number, 0) };
 | 
			
		||||
    } else if (order < 6) {
 | 
			
		||||
      return { value: this.metricSystem(number, 3), symbol: 'K' };
 | 
			
		||||
    } else if (order < 9) {
 | 
			
		||||
      return { value: this.metricSystem(number, 6), symbol: 'M' };
 | 
			
		||||
    } else if (order < 12) {
 | 
			
		||||
      return { value: this.metricSystem(number, 9), symbol: 'B' };
 | 
			
		||||
    } else if (order < 15) {
 | 
			
		||||
      return { value: this.metricSystem(number, 12), symbol: 'T' };
 | 
			
		||||
    } else {
 | 
			
		||||
      return { value: this.metricSystem(number, order), power: order };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function numberShow(number, precision = 2) {
 | 
			
		||||
  const ns = new NumberShower(number, precision);
 | 
			
		||||
  return ns.convert();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -85,11 +85,6 @@ module O = {
 | 
			
		|||
 | 
			
		||||
  let min = compare(\"<")
 | 
			
		||||
  let max = compare(\">")
 | 
			
		||||
  module React = {
 | 
			
		||||
    let defaultNull = default(React.null)
 | 
			
		||||
    let fmapOrNull = fn => \"||>"(fmap(fn), default(React.null))
 | 
			
		||||
    let flatten = default(React.null)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Functions */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
  <meta charset="UTF-8">
 | 
			
		||||
  <title>Squiggle Language</title>
 | 
			
		||||
  <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700,900" rel="stylesheet">
 | 
			
		||||
  <link href="./styles/index.css" rel="stylesheet">
 | 
			
		||||
  <script src="./Index.bs.js" defer></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
<body>
 | 
			
		||||
  <div id="app" style="height: 100%"></div>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +0,0 @@
 | 
			
		|||
module Styles = {
 | 
			
		||||
  open CssJs
 | 
			
		||||
  let h3 = style(. [ fontSize(#em(1.5)), marginBottom(#em(1.5)) ])
 | 
			
		||||
  let card = style(. [ marginTop(#em(2.)), marginBottom(#em(2.)) ])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module Table = {
 | 
			
		||||
  module TableStyles = {
 | 
			
		||||
    open CssJs
 | 
			
		||||
    let row = style(. [ display(#flex), height(#em(4.)) ])
 | 
			
		||||
    let col = (~f=1.0, ()) => style(. [ flex(#num(f)) ])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @react.component
 | 
			
		||||
  let make = () => <> </>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@react.component
 | 
			
		||||
let make = () => <div> <div style=Styles.card> <Table /> </div> </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
@tailwind base;
 | 
			
		||||
 | 
			
		||||
@tailwind components;
 | 
			
		||||
 | 
			
		||||
@tailwind utilities;
 | 
			
		||||
							
								
								
									
										67342
									
								
								src/styles/tailwind.css
									
									
									
									
									
								
							
							
						
						
									
										67342
									
								
								src/styles/tailwind.css
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										694
									
								
								tailwind.js
									
									
									
									
									
								
							
							
						
						
									
										694
									
								
								tailwind.js
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,694 +0,0 @@
 | 
			
		|||
module.exports = {
 | 
			
		||||
  prefix: '',
 | 
			
		||||
  important: false,
 | 
			
		||||
  separator: ':',
 | 
			
		||||
  theme: {
 | 
			
		||||
    screens: {
 | 
			
		||||
      sm: '640px',
 | 
			
		||||
      md: '768px',
 | 
			
		||||
      lg: '1024px',
 | 
			
		||||
      xl: '1280px',
 | 
			
		||||
    },
 | 
			
		||||
    colors: {
 | 
			
		||||
      transparent: 'transparent',
 | 
			
		||||
 | 
			
		||||
      black: '#000',
 | 
			
		||||
      white: '#fff',
 | 
			
		||||
 | 
			
		||||
      gray: {
 | 
			
		||||
        100: '#f7fafc',
 | 
			
		||||
        200: '#edf2f7',
 | 
			
		||||
        300: '#e2e8f0',
 | 
			
		||||
        400: '#cbd5e0',
 | 
			
		||||
        500: '#a0aec0',
 | 
			
		||||
        600: '#718096',
 | 
			
		||||
        700: '#4a5568',
 | 
			
		||||
        800: '#2d3748',
 | 
			
		||||
        900: '#1a202c',
 | 
			
		||||
      },
 | 
			
		||||
      red: {
 | 
			
		||||
        100: '#fff5f5',
 | 
			
		||||
        200: '#fed7d7',
 | 
			
		||||
        300: '#feb2b2',
 | 
			
		||||
        400: '#fc8181',
 | 
			
		||||
        500: '#f56565',
 | 
			
		||||
        600: '#e53e3e',
 | 
			
		||||
        700: '#c53030',
 | 
			
		||||
        800: '#9b2c2c',
 | 
			
		||||
        900: '#742a2a',
 | 
			
		||||
      },
 | 
			
		||||
      orange: {
 | 
			
		||||
        100: '#fffaf0',
 | 
			
		||||
        200: '#feebc8',
 | 
			
		||||
        300: '#fbd38d',
 | 
			
		||||
        400: '#f6ad55',
 | 
			
		||||
        500: '#ed8936',
 | 
			
		||||
        600: '#dd6b20',
 | 
			
		||||
        700: '#c05621',
 | 
			
		||||
        800: '#9c4221',
 | 
			
		||||
        900: '#7b341e',
 | 
			
		||||
      },
 | 
			
		||||
      yellow: {
 | 
			
		||||
        100: '#fffff0',
 | 
			
		||||
        200: '#fefcbf',
 | 
			
		||||
        300: '#faf089',
 | 
			
		||||
        400: '#f6e05e',
 | 
			
		||||
        500: '#ecc94b',
 | 
			
		||||
        600: '#d69e2e',
 | 
			
		||||
        700: '#b7791f',
 | 
			
		||||
        800: '#975a16',
 | 
			
		||||
        900: '#744210',
 | 
			
		||||
      },
 | 
			
		||||
      green: {
 | 
			
		||||
        100: '#f0fff4',
 | 
			
		||||
        200: '#c6f6d5',
 | 
			
		||||
        300: '#9ae6b4',
 | 
			
		||||
        400: '#68d391',
 | 
			
		||||
        500: '#48bb78',
 | 
			
		||||
        600: '#38a169',
 | 
			
		||||
        700: '#2f855a',
 | 
			
		||||
        800: '#276749',
 | 
			
		||||
        900: '#22543d',
 | 
			
		||||
      },
 | 
			
		||||
      teal: {
 | 
			
		||||
        100: '#e6fffa',
 | 
			
		||||
        200: '#b2f5ea',
 | 
			
		||||
        300: '#81e6d9',
 | 
			
		||||
        400: '#4fd1c5',
 | 
			
		||||
        500: '#38b2ac',
 | 
			
		||||
        600: '#319795',
 | 
			
		||||
        700: '#2c7a7b',
 | 
			
		||||
        800: '#285e61',
 | 
			
		||||
        900: '#234e52',
 | 
			
		||||
      },
 | 
			
		||||
      blue: {
 | 
			
		||||
        100: '#ebf8ff',
 | 
			
		||||
        200: '#bee3f8',
 | 
			
		||||
        300: '#90cdf4',
 | 
			
		||||
        400: '#63b3ed',
 | 
			
		||||
        500: '#4299e1',
 | 
			
		||||
        600: '#3182ce',
 | 
			
		||||
        700: '#2b6cb0',
 | 
			
		||||
        800: '#2c5282',
 | 
			
		||||
        900: '#2a4365',
 | 
			
		||||
      },
 | 
			
		||||
      indigo: {
 | 
			
		||||
        100: '#ebf4ff',
 | 
			
		||||
        200: '#c3dafe',
 | 
			
		||||
        300: '#a3bffa',
 | 
			
		||||
        400: '#7f9cf5',
 | 
			
		||||
        500: '#667eea',
 | 
			
		||||
        600: '#5a67d8',
 | 
			
		||||
        700: '#4c51bf',
 | 
			
		||||
        800: '#434190',
 | 
			
		||||
        900: '#3c366b',
 | 
			
		||||
      },
 | 
			
		||||
      purple: {
 | 
			
		||||
        100: '#faf5ff',
 | 
			
		||||
        200: '#e9d8fd',
 | 
			
		||||
        300: '#d6bcfa',
 | 
			
		||||
        400: '#b794f4',
 | 
			
		||||
        500: '#9f7aea',
 | 
			
		||||
        600: '#805ad5',
 | 
			
		||||
        700: '#6b46c1',
 | 
			
		||||
        800: '#553c9a',
 | 
			
		||||
        900: '#44337a',
 | 
			
		||||
      },
 | 
			
		||||
      pink: {
 | 
			
		||||
        100: '#fff5f7',
 | 
			
		||||
        200: '#fed7e2',
 | 
			
		||||
        300: '#fbb6ce',
 | 
			
		||||
        400: '#f687b3',
 | 
			
		||||
        500: '#ed64a6',
 | 
			
		||||
        600: '#d53f8c',
 | 
			
		||||
        700: '#b83280',
 | 
			
		||||
        800: '#97266d',
 | 
			
		||||
        900: '#702459',
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    spacing: {
 | 
			
		||||
      px: '1px',
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '1': '0.25rem',
 | 
			
		||||
      '2': '0.5rem',
 | 
			
		||||
      '3': '0.75rem',
 | 
			
		||||
      '4': '1rem',
 | 
			
		||||
      '5': '1.25rem',
 | 
			
		||||
      '6': '1.5rem',
 | 
			
		||||
      '8': '2rem',
 | 
			
		||||
      '10': '2.5rem',
 | 
			
		||||
      '12': '3rem',
 | 
			
		||||
      '16': '4rem',
 | 
			
		||||
      '20': '5rem',
 | 
			
		||||
      '24': '6rem',
 | 
			
		||||
      '32': '8rem',
 | 
			
		||||
      '40': '10rem',
 | 
			
		||||
      '48': '12rem',
 | 
			
		||||
      '56': '14rem',
 | 
			
		||||
      '64': '16rem',
 | 
			
		||||
    },
 | 
			
		||||
    backgroundColor: theme => theme('colors'),
 | 
			
		||||
    backgroundPosition: {
 | 
			
		||||
      bottom: 'bottom',
 | 
			
		||||
      center: 'center',
 | 
			
		||||
      left: 'left',
 | 
			
		||||
      'left-bottom': 'left bottom',
 | 
			
		||||
      'left-top': 'left top',
 | 
			
		||||
      right: 'right',
 | 
			
		||||
      'right-bottom': 'right bottom',
 | 
			
		||||
      'right-top': 'right top',
 | 
			
		||||
      top: 'top',
 | 
			
		||||
    },
 | 
			
		||||
    backgroundSize: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      cover: 'cover',
 | 
			
		||||
      contain: 'contain',
 | 
			
		||||
    },
 | 
			
		||||
    borderColor: theme => ({
 | 
			
		||||
      ...theme('colors'),
 | 
			
		||||
      default: theme('colors.gray.300', 'currentColor'),
 | 
			
		||||
    }),
 | 
			
		||||
    borderRadius: {
 | 
			
		||||
      none: '0',
 | 
			
		||||
      sm: '0.125rem',
 | 
			
		||||
      default: '0.25rem',
 | 
			
		||||
      md: '0.375rem',
 | 
			
		||||
      lg: '0.5rem',
 | 
			
		||||
      full: '9999px',
 | 
			
		||||
    },
 | 
			
		||||
    borderWidth: {
 | 
			
		||||
      default: '1px',
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '2': '2px',
 | 
			
		||||
      '4': '4px',
 | 
			
		||||
      '8': '8px',
 | 
			
		||||
    },
 | 
			
		||||
    boxShadow: {
 | 
			
		||||
      xs: '0 0 0 1px rgba(0, 0, 0, 0.05)',
 | 
			
		||||
      sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
 | 
			
		||||
      default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
 | 
			
		||||
      md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
 | 
			
		||||
      lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
 | 
			
		||||
      xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
 | 
			
		||||
      '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
 | 
			
		||||
      inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
 | 
			
		||||
      outline: '0 0 0 3px rgba(66, 153, 225, 0.5)',
 | 
			
		||||
      none: 'none',
 | 
			
		||||
    },
 | 
			
		||||
    container: {},
 | 
			
		||||
    cursor: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      default: 'default',
 | 
			
		||||
      pointer: 'pointer',
 | 
			
		||||
      wait: 'wait',
 | 
			
		||||
      text: 'text',
 | 
			
		||||
      move: 'move',
 | 
			
		||||
      'not-allowed': 'not-allowed',
 | 
			
		||||
    },
 | 
			
		||||
    fill: {
 | 
			
		||||
      current: 'currentColor',
 | 
			
		||||
    },
 | 
			
		||||
    flex: {
 | 
			
		||||
      '1': '1 1 0%',
 | 
			
		||||
      auto: '1 1 auto',
 | 
			
		||||
      initial: '0 1 auto',
 | 
			
		||||
      none: 'none',
 | 
			
		||||
    },
 | 
			
		||||
    flexGrow: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      default: '1',
 | 
			
		||||
    },
 | 
			
		||||
    flexShrink: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      default: '1',
 | 
			
		||||
    },
 | 
			
		||||
    fontFamily: {
 | 
			
		||||
      sans: [
 | 
			
		||||
        'system-ui',
 | 
			
		||||
        '-apple-system',
 | 
			
		||||
        'BlinkMacSystemFont',
 | 
			
		||||
        '"Segoe UI"',
 | 
			
		||||
        'Roboto',
 | 
			
		||||
        '"Helvetica Neue"',
 | 
			
		||||
        'Arial',
 | 
			
		||||
        '"Noto Sans"',
 | 
			
		||||
        'sans-serif',
 | 
			
		||||
        '"Apple Color Emoji"',
 | 
			
		||||
        '"Segoe UI Emoji"',
 | 
			
		||||
        '"Segoe UI Symbol"',
 | 
			
		||||
        '"Noto Color Emoji"',
 | 
			
		||||
      ],
 | 
			
		||||
      serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'],
 | 
			
		||||
      mono: ['Menlo', 'Monaco', 'Consolas', '"Liberation Mono"', '"Courier New"', 'monospace'],
 | 
			
		||||
    },
 | 
			
		||||
    fontSize: {
 | 
			
		||||
      xs: '0.75rem',
 | 
			
		||||
      sm: '0.875rem',
 | 
			
		||||
      base: '1rem',
 | 
			
		||||
      lg: '1.125rem',
 | 
			
		||||
      xl: '1.25rem',
 | 
			
		||||
      '2xl': '1.5rem',
 | 
			
		||||
      '3xl': '1.875rem',
 | 
			
		||||
      '4xl': '2.25rem',
 | 
			
		||||
      '5xl': '3rem',
 | 
			
		||||
      '6xl': '4rem',
 | 
			
		||||
    },
 | 
			
		||||
    fontWeight: {
 | 
			
		||||
      hairline: '100',
 | 
			
		||||
      thin: '200',
 | 
			
		||||
      light: '300',
 | 
			
		||||
      normal: '400',
 | 
			
		||||
      medium: '500',
 | 
			
		||||
      semibold: '600',
 | 
			
		||||
      bold: '700',
 | 
			
		||||
      extrabold: '800',
 | 
			
		||||
      black: '900',
 | 
			
		||||
    },
 | 
			
		||||
    height: theme => ({
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      ...theme('spacing'),
 | 
			
		||||
      full: '100%',
 | 
			
		||||
      screen: '100vh',
 | 
			
		||||
    }),
 | 
			
		||||
    inset: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
    },
 | 
			
		||||
    letterSpacing: {
 | 
			
		||||
      tighter: '-0.05em',
 | 
			
		||||
      tight: '-0.025em',
 | 
			
		||||
      normal: '0',
 | 
			
		||||
      wide: '0.025em',
 | 
			
		||||
      wider: '0.05em',
 | 
			
		||||
      widest: '0.1em',
 | 
			
		||||
    },
 | 
			
		||||
    lineHeight: {
 | 
			
		||||
      none: '1',
 | 
			
		||||
      tight: '1.25',
 | 
			
		||||
      snug: '1.375',
 | 
			
		||||
      normal: '1.5',
 | 
			
		||||
      relaxed: '1.625',
 | 
			
		||||
      loose: '2',
 | 
			
		||||
      '3': '.75rem',
 | 
			
		||||
      '4': '1rem',
 | 
			
		||||
      '5': '1.25rem',
 | 
			
		||||
      '6': '1.5rem',
 | 
			
		||||
      '7': '1.75rem',
 | 
			
		||||
      '8': '2rem',
 | 
			
		||||
      '9': '2.25rem',
 | 
			
		||||
      '10': '2.5rem',
 | 
			
		||||
    },
 | 
			
		||||
    listStyleType: {
 | 
			
		||||
      none: 'none',
 | 
			
		||||
      disc: 'disc',
 | 
			
		||||
      decimal: 'decimal',
 | 
			
		||||
    },
 | 
			
		||||
    margin: (theme, { negative }) => ({
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      ...theme('spacing'),
 | 
			
		||||
      ...negative(theme('spacing')),
 | 
			
		||||
    }),
 | 
			
		||||
    maxHeight: {
 | 
			
		||||
      full: '100%',
 | 
			
		||||
      screen: '100vh',
 | 
			
		||||
    },
 | 
			
		||||
    maxWidth: (theme, { breakpoints }) => ({
 | 
			
		||||
      none: 'none',
 | 
			
		||||
      xs: '20rem',
 | 
			
		||||
      sm: '24rem',
 | 
			
		||||
      md: '28rem',
 | 
			
		||||
      lg: '32rem',
 | 
			
		||||
      xl: '36rem',
 | 
			
		||||
      '2xl': '42rem',
 | 
			
		||||
      '3xl': '48rem',
 | 
			
		||||
      '4xl': '56rem',
 | 
			
		||||
      '5xl': '64rem',
 | 
			
		||||
      '6xl': '72rem',
 | 
			
		||||
      full: '100%',
 | 
			
		||||
      ...breakpoints(theme('screens')),
 | 
			
		||||
    }),
 | 
			
		||||
    minHeight: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      full: '100%',
 | 
			
		||||
      screen: '100vh',
 | 
			
		||||
    },
 | 
			
		||||
    minWidth: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      full: '100%',
 | 
			
		||||
    },
 | 
			
		||||
    objectPosition: {
 | 
			
		||||
      bottom: 'bottom',
 | 
			
		||||
      center: 'center',
 | 
			
		||||
      left: 'left',
 | 
			
		||||
      'left-bottom': 'left bottom',
 | 
			
		||||
      'left-top': 'left top',
 | 
			
		||||
      right: 'right',
 | 
			
		||||
      'right-bottom': 'right bottom',
 | 
			
		||||
      'right-top': 'right top',
 | 
			
		||||
      top: 'top',
 | 
			
		||||
    },
 | 
			
		||||
    opacity: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '25': '0.25',
 | 
			
		||||
      '50': '0.5',
 | 
			
		||||
      '75': '0.75',
 | 
			
		||||
      '100': '1',
 | 
			
		||||
    },
 | 
			
		||||
    order: {
 | 
			
		||||
      first: '-9999',
 | 
			
		||||
      last: '9999',
 | 
			
		||||
      none: '0',
 | 
			
		||||
      '1': '1',
 | 
			
		||||
      '2': '2',
 | 
			
		||||
      '3': '3',
 | 
			
		||||
      '4': '4',
 | 
			
		||||
      '5': '5',
 | 
			
		||||
      '6': '6',
 | 
			
		||||
      '7': '7',
 | 
			
		||||
      '8': '8',
 | 
			
		||||
      '9': '9',
 | 
			
		||||
      '10': '10',
 | 
			
		||||
      '11': '11',
 | 
			
		||||
      '12': '12',
 | 
			
		||||
    },
 | 
			
		||||
    padding: theme => theme('spacing'),
 | 
			
		||||
    placeholderColor: theme => theme('colors'),
 | 
			
		||||
    stroke: {
 | 
			
		||||
      current: 'currentColor',
 | 
			
		||||
    },
 | 
			
		||||
    strokeWidth: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '1': '1',
 | 
			
		||||
      '2': '2',
 | 
			
		||||
    },
 | 
			
		||||
    textColor: theme => theme('colors'),
 | 
			
		||||
    width: theme => ({
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      ...theme('spacing'),
 | 
			
		||||
      '1/2': '50%',
 | 
			
		||||
      '1/3': '33.333333%',
 | 
			
		||||
      '2/3': '66.666667%',
 | 
			
		||||
      '1/4': '25%',
 | 
			
		||||
      '2/4': '50%',
 | 
			
		||||
      '3/4': '75%',
 | 
			
		||||
      '1/5': '20%',
 | 
			
		||||
      '2/5': '40%',
 | 
			
		||||
      '3/5': '60%',
 | 
			
		||||
      '4/5': '80%',
 | 
			
		||||
      '1/6': '16.666667%',
 | 
			
		||||
      '2/6': '33.333333%',
 | 
			
		||||
      '3/6': '50%',
 | 
			
		||||
      '4/6': '66.666667%',
 | 
			
		||||
      '5/6': '83.333333%',
 | 
			
		||||
      '1/12': '8.333333%',
 | 
			
		||||
      '2/12': '16.666667%',
 | 
			
		||||
      '3/12': '25%',
 | 
			
		||||
      '4/12': '33.333333%',
 | 
			
		||||
      '5/12': '41.666667%',
 | 
			
		||||
      '6/12': '50%',
 | 
			
		||||
      '7/12': '58.333333%',
 | 
			
		||||
      '8/12': '66.666667%',
 | 
			
		||||
      '9/12': '75%',
 | 
			
		||||
      '10/12': '83.333333%',
 | 
			
		||||
      '11/12': '91.666667%',
 | 
			
		||||
      full: '100%',
 | 
			
		||||
      screen: '100vw',
 | 
			
		||||
    }),
 | 
			
		||||
    zIndex: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '10': '10',
 | 
			
		||||
      '20': '20',
 | 
			
		||||
      '30': '30',
 | 
			
		||||
      '40': '40',
 | 
			
		||||
      '50': '50',
 | 
			
		||||
    },
 | 
			
		||||
    gap: theme => theme('spacing'),
 | 
			
		||||
    gridTemplateColumns: {
 | 
			
		||||
      none: 'none',
 | 
			
		||||
      '1': 'repeat(1, minmax(0, 1fr))',
 | 
			
		||||
      '2': 'repeat(2, minmax(0, 1fr))',
 | 
			
		||||
      '3': 'repeat(3, minmax(0, 1fr))',
 | 
			
		||||
      '4': 'repeat(4, minmax(0, 1fr))',
 | 
			
		||||
      '5': 'repeat(5, minmax(0, 1fr))',
 | 
			
		||||
      '6': 'repeat(6, minmax(0, 1fr))',
 | 
			
		||||
      '7': 'repeat(7, minmax(0, 1fr))',
 | 
			
		||||
      '8': 'repeat(8, minmax(0, 1fr))',
 | 
			
		||||
      '9': 'repeat(9, minmax(0, 1fr))',
 | 
			
		||||
      '10': 'repeat(10, minmax(0, 1fr))',
 | 
			
		||||
      '11': 'repeat(11, minmax(0, 1fr))',
 | 
			
		||||
      '12': 'repeat(12, minmax(0, 1fr))',
 | 
			
		||||
    },
 | 
			
		||||
    gridColumn: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      'span-1': 'span 1 / span 1',
 | 
			
		||||
      'span-2': 'span 2 / span 2',
 | 
			
		||||
      'span-3': 'span 3 / span 3',
 | 
			
		||||
      'span-4': 'span 4 / span 4',
 | 
			
		||||
      'span-5': 'span 5 / span 5',
 | 
			
		||||
      'span-6': 'span 6 / span 6',
 | 
			
		||||
      'span-7': 'span 7 / span 7',
 | 
			
		||||
      'span-8': 'span 8 / span 8',
 | 
			
		||||
      'span-9': 'span 9 / span 9',
 | 
			
		||||
      'span-10': 'span 10 / span 10',
 | 
			
		||||
      'span-11': 'span 11 / span 11',
 | 
			
		||||
      'span-12': 'span 12 / span 12',
 | 
			
		||||
    },
 | 
			
		||||
    gridColumnStart: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      '1': '1',
 | 
			
		||||
      '2': '2',
 | 
			
		||||
      '3': '3',
 | 
			
		||||
      '4': '4',
 | 
			
		||||
      '5': '5',
 | 
			
		||||
      '6': '6',
 | 
			
		||||
      '7': '7',
 | 
			
		||||
      '8': '8',
 | 
			
		||||
      '9': '9',
 | 
			
		||||
      '10': '10',
 | 
			
		||||
      '11': '11',
 | 
			
		||||
      '12': '12',
 | 
			
		||||
      '13': '13',
 | 
			
		||||
    },
 | 
			
		||||
    gridColumnEnd: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      '1': '1',
 | 
			
		||||
      '2': '2',
 | 
			
		||||
      '3': '3',
 | 
			
		||||
      '4': '4',
 | 
			
		||||
      '5': '5',
 | 
			
		||||
      '6': '6',
 | 
			
		||||
      '7': '7',
 | 
			
		||||
      '8': '8',
 | 
			
		||||
      '9': '9',
 | 
			
		||||
      '10': '10',
 | 
			
		||||
      '11': '11',
 | 
			
		||||
      '12': '12',
 | 
			
		||||
      '13': '13',
 | 
			
		||||
    },
 | 
			
		||||
    gridTemplateRows: {
 | 
			
		||||
      none: 'none',
 | 
			
		||||
      '1': 'repeat(1, minmax(0, 1fr))',
 | 
			
		||||
      '2': 'repeat(2, minmax(0, 1fr))',
 | 
			
		||||
      '3': 'repeat(3, minmax(0, 1fr))',
 | 
			
		||||
      '4': 'repeat(4, minmax(0, 1fr))',
 | 
			
		||||
      '5': 'repeat(5, minmax(0, 1fr))',
 | 
			
		||||
      '6': 'repeat(6, minmax(0, 1fr))',
 | 
			
		||||
    },
 | 
			
		||||
    gridRow: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      'span-1': 'span 1 / span 1',
 | 
			
		||||
      'span-2': 'span 2 / span 2',
 | 
			
		||||
      'span-3': 'span 3 / span 3',
 | 
			
		||||
      'span-4': 'span 4 / span 4',
 | 
			
		||||
      'span-5': 'span 5 / span 5',
 | 
			
		||||
      'span-6': 'span 6 / span 6',
 | 
			
		||||
    },
 | 
			
		||||
    gridRowStart: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      '1': '1',
 | 
			
		||||
      '2': '2',
 | 
			
		||||
      '3': '3',
 | 
			
		||||
      '4': '4',
 | 
			
		||||
      '5': '5',
 | 
			
		||||
      '6': '6',
 | 
			
		||||
      '7': '7',
 | 
			
		||||
    },
 | 
			
		||||
    gridRowEnd: {
 | 
			
		||||
      auto: 'auto',
 | 
			
		||||
      '1': '1',
 | 
			
		||||
      '2': '2',
 | 
			
		||||
      '3': '3',
 | 
			
		||||
      '4': '4',
 | 
			
		||||
      '5': '5',
 | 
			
		||||
      '6': '6',
 | 
			
		||||
      '7': '7',
 | 
			
		||||
    },
 | 
			
		||||
    transformOrigin: {
 | 
			
		||||
      center: 'center',
 | 
			
		||||
      top: 'top',
 | 
			
		||||
      'top-right': 'top right',
 | 
			
		||||
      right: 'right',
 | 
			
		||||
      'bottom-right': 'bottom right',
 | 
			
		||||
      bottom: 'bottom',
 | 
			
		||||
      'bottom-left': 'bottom left',
 | 
			
		||||
      left: 'left',
 | 
			
		||||
      'top-left': 'top left',
 | 
			
		||||
    },
 | 
			
		||||
    scale: {
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '50': '.5',
 | 
			
		||||
      '75': '.75',
 | 
			
		||||
      '90': '.9',
 | 
			
		||||
      '95': '.95',
 | 
			
		||||
      '100': '1',
 | 
			
		||||
      '105': '1.05',
 | 
			
		||||
      '110': '1.1',
 | 
			
		||||
      '125': '1.25',
 | 
			
		||||
      '150': '1.5',
 | 
			
		||||
    },
 | 
			
		||||
    rotate: {
 | 
			
		||||
      '-180': '-180deg',
 | 
			
		||||
      '-90': '-90deg',
 | 
			
		||||
      '-45': '-45deg',
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '45': '45deg',
 | 
			
		||||
      '90': '90deg',
 | 
			
		||||
      '180': '180deg',
 | 
			
		||||
    },
 | 
			
		||||
    translate: (theme, { negative }) => ({
 | 
			
		||||
      ...theme('spacing'),
 | 
			
		||||
      ...negative(theme('spacing')),
 | 
			
		||||
      '-full': '-100%',
 | 
			
		||||
      '-1/2': '-50%',
 | 
			
		||||
      '1/2': '50%',
 | 
			
		||||
      full: '100%',
 | 
			
		||||
    }),
 | 
			
		||||
    skew: {
 | 
			
		||||
      '-12': '-12deg',
 | 
			
		||||
      '-6': '-6deg',
 | 
			
		||||
      '-3': '-3deg',
 | 
			
		||||
      '0': '0',
 | 
			
		||||
      '3': '3deg',
 | 
			
		||||
      '6': '6deg',
 | 
			
		||||
      '12': '12deg',
 | 
			
		||||
    },
 | 
			
		||||
    transitionProperty: {
 | 
			
		||||
      none: 'none',
 | 
			
		||||
      all: 'all',
 | 
			
		||||
      default: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',
 | 
			
		||||
      colors: 'background-color, border-color, color, fill, stroke',
 | 
			
		||||
      opacity: 'opacity',
 | 
			
		||||
      shadow: 'box-shadow',
 | 
			
		||||
      transform: 'transform',
 | 
			
		||||
    },
 | 
			
		||||
    transitionTimingFunction: {
 | 
			
		||||
      linear: 'linear',
 | 
			
		||||
      in: 'cubic-bezier(0.4, 0, 1, 1)',
 | 
			
		||||
      out: 'cubic-bezier(0, 0, 0.2, 1)',
 | 
			
		||||
      'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
 | 
			
		||||
    },
 | 
			
		||||
    transitionDuration: {
 | 
			
		||||
      '75': '75ms',
 | 
			
		||||
      '100': '100ms',
 | 
			
		||||
      '150': '150ms',
 | 
			
		||||
      '200': '200ms',
 | 
			
		||||
      '300': '300ms',
 | 
			
		||||
      '500': '500ms',
 | 
			
		||||
      '700': '700ms',
 | 
			
		||||
      '1000': '1000ms',
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  variants: {
 | 
			
		||||
    accessibility: ['responsive', 'focus'],
 | 
			
		||||
    alignContent: ['responsive'],
 | 
			
		||||
    alignItems: ['responsive'],
 | 
			
		||||
    alignSelf: ['responsive'],
 | 
			
		||||
    appearance: ['responsive'],
 | 
			
		||||
    backgroundAttachment: ['responsive'],
 | 
			
		||||
    backgroundColor: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    backgroundPosition: ['responsive'],
 | 
			
		||||
    backgroundRepeat: ['responsive'],
 | 
			
		||||
    backgroundSize: ['responsive'],
 | 
			
		||||
    borderCollapse: ['responsive'],
 | 
			
		||||
    borderColor: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    borderRadius: ['responsive'],
 | 
			
		||||
    borderStyle: ['responsive'],
 | 
			
		||||
    borderWidth: ['responsive'],
 | 
			
		||||
    boxShadow: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    boxSizing: ['responsive'],
 | 
			
		||||
    cursor: ['responsive'],
 | 
			
		||||
    display: ['responsive'],
 | 
			
		||||
    fill: ['responsive'],
 | 
			
		||||
    flex: ['responsive'],
 | 
			
		||||
    flexDirection: ['responsive'],
 | 
			
		||||
    flexGrow: ['responsive'],
 | 
			
		||||
    flexShrink: ['responsive'],
 | 
			
		||||
    flexWrap: ['responsive'],
 | 
			
		||||
    float: ['responsive'],
 | 
			
		||||
    clear: ['responsive'],
 | 
			
		||||
    fontFamily: ['responsive'],
 | 
			
		||||
    fontSize: ['responsive'],
 | 
			
		||||
    fontSmoothing: ['responsive'],
 | 
			
		||||
    fontStyle: ['responsive'],
 | 
			
		||||
    fontWeight: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    height: ['responsive'],
 | 
			
		||||
    inset: ['responsive'],
 | 
			
		||||
    justifyContent: ['responsive'],
 | 
			
		||||
    letterSpacing: ['responsive'],
 | 
			
		||||
    lineHeight: ['responsive'],
 | 
			
		||||
    listStylePosition: ['responsive'],
 | 
			
		||||
    listStyleType: ['responsive'],
 | 
			
		||||
    margin: ['responsive'],
 | 
			
		||||
    maxHeight: ['responsive'],
 | 
			
		||||
    maxWidth: ['responsive'],
 | 
			
		||||
    minHeight: ['responsive'],
 | 
			
		||||
    minWidth: ['responsive'],
 | 
			
		||||
    objectFit: ['responsive'],
 | 
			
		||||
    objectPosition: ['responsive'],
 | 
			
		||||
    opacity: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    order: ['responsive'],
 | 
			
		||||
    outline: ['responsive', 'focus'],
 | 
			
		||||
    overflow: ['responsive'],
 | 
			
		||||
    padding: ['responsive'],
 | 
			
		||||
    placeholderColor: ['responsive', 'focus'],
 | 
			
		||||
    pointerEvents: ['responsive'],
 | 
			
		||||
    position: ['responsive'],
 | 
			
		||||
    resize: ['responsive'],
 | 
			
		||||
    stroke: ['responsive'],
 | 
			
		||||
    strokeWidth: ['responsive'],
 | 
			
		||||
    tableLayout: ['responsive'],
 | 
			
		||||
    textAlign: ['responsive'],
 | 
			
		||||
    textColor: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    textDecoration: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    textTransform: ['responsive'],
 | 
			
		||||
    userSelect: ['responsive'],
 | 
			
		||||
    verticalAlign: ['responsive'],
 | 
			
		||||
    visibility: ['responsive'],
 | 
			
		||||
    whitespace: ['responsive'],
 | 
			
		||||
    width: ['responsive'],
 | 
			
		||||
    wordBreak: ['responsive'],
 | 
			
		||||
    zIndex: ['responsive'],
 | 
			
		||||
    gap: ['responsive'],
 | 
			
		||||
    gridAutoFlow: ['responsive'],
 | 
			
		||||
    gridTemplateColumns: ['responsive'],
 | 
			
		||||
    gridColumn: ['responsive'],
 | 
			
		||||
    gridColumnStart: ['responsive'],
 | 
			
		||||
    gridColumnEnd: ['responsive'],
 | 
			
		||||
    gridTemplateRows: ['responsive'],
 | 
			
		||||
    gridRow: ['responsive'],
 | 
			
		||||
    gridRowStart: ['responsive'],
 | 
			
		||||
    gridRowEnd: ['responsive'],
 | 
			
		||||
    transform: ['responsive'],
 | 
			
		||||
    transformOrigin: ['responsive'],
 | 
			
		||||
    scale: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    rotate: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    translate: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    skew: ['responsive', 'hover', 'focus'],
 | 
			
		||||
    transitionProperty: ['responsive'],
 | 
			
		||||
    transitionTimingFunction: ['responsive'],
 | 
			
		||||
    transitionDuration: ['responsive'],
 | 
			
		||||
  },
 | 
			
		||||
  corePlugins: {},
 | 
			
		||||
  plugins: [],
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								test.res
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								test.res
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,48 +0,0 @@
 | 
			
		|||
@react.component
 | 
			
		||||
let make = (
 | 
			
		||||
  ~disabled: bool=?,
 | 
			
		||||
  ~ghost: bool=?,
 | 
			
		||||
  ~href: string=?,
 | 
			
		||||
  ~htmlType: @string [#button | #submit | #submit]=?,
 | 
			
		||||
  ~icon: 'a=?,
 | 
			
		||||
  ~shape: @string [#circle | #round]=?,
 | 
			
		||||
  ~size: @string [#small | #large]=?,
 | 
			
		||||
  ~target: string=?,
 | 
			
		||||
  ~loading: bool=?,
 | 
			
		||||
  ~_type: @string
 | 
			
		||||
  [
 | 
			
		||||
    | #primary
 | 
			
		||||
    | #default
 | 
			
		||||
    | #dashed
 | 
			
		||||
    | #danger
 | 
			
		||||
    | #link
 | 
			
		||||
    | #ghost
 | 
			
		||||
  ]=?,
 | 
			
		||||
  ~onClick: ReactEvent.Mouse.t => unit=?,
 | 
			
		||||
  ~block: bool=?,
 | 
			
		||||
  ~children: React.element=?,
 | 
			
		||||
  ~className: string=?,
 | 
			
		||||
  ~id: string=?,
 | 
			
		||||
  ~testId: string=?,
 | 
			
		||||
) =>
 | 
			
		||||
  ReasonReact.cloneElement(
 | 
			
		||||
    <AntButton
 | 
			
		||||
      _type
 | 
			
		||||
      disabled
 | 
			
		||||
      ghost
 | 
			
		||||
      href
 | 
			
		||||
      htmlType
 | 
			
		||||
      icon={Antd_Utils.tts(Antd_Icon.iconToJsSafe(~icon, ()))}
 | 
			
		||||
      shape
 | 
			
		||||
      size
 | 
			
		||||
      target
 | 
			
		||||
      onClick
 | 
			
		||||
      block
 | 
			
		||||
      loading
 | 
			
		||||
      className
 | 
			
		||||
      id>
 | 
			
		||||
      children
 | 
			
		||||
    </AntButton>,
 | 
			
		||||
    ~props={"data-testid": testId},
 | 
			
		||||
    [],
 | 
			
		||||
  )
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user