update code
parent
d9d0e6ad8d
commit
7c659bc337
|
@ -5,7 +5,7 @@
|
|||
<link rel="icon" href="logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>算法测试验证软件平台</title>
|
||||
<link rel="stylesheet" href="./css/main.css">
|
||||
<link rel="stylesheet" href="./css/main.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"lint:eslint": "eslint --fix --ext .ts,.js,.vue ./src ",
|
||||
"lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}\"",
|
||||
"lint:stylelint": "stylelint \"**/*.{css,scss,vue}\" --fix",
|
||||
"lint:lint-staged": "lint-staged",
|
||||
"lint:lint-staged": "lint-staged",
|
||||
"prepare": "husky",
|
||||
"commit": "git-cz"
|
||||
},
|
||||
|
@ -44,6 +44,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@logicflow/core": "^1.2.27",
|
||||
"@logicflow/extension": "^1.2.27",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "5.1.10",
|
||||
|
|
|
@ -0,0 +1,503 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>onnx_viewer</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover, shrink-to-fit=no">
|
||||
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./onnx_view/grapher.css" />
|
||||
|
||||
<script type="text/javascript" src="./onnx_view/base.js"></script>
|
||||
<script type="text/javascript" src="./onnx_view/dagre.js"></script>
|
||||
<script type="text/javascript" src="./onnx_view/grapher.js"></script>
|
||||
<script type="text/javascript" src="./onnx_view/onnx_model.js"></script>
|
||||
<script type="text/javascript" src="./onnx_view/onnx_view.js"></script>
|
||||
|
||||
<style>
|
||||
html { touch-action: none; overflow: hidden; width: 100%; height: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; text-rendering: optimizeLegibility; -webkit-text-rendering: optimizeLegibility; -moz-text-rendering: optimizeLegibility; -ms-text-rendering: optimizeLegibility; -o-text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-font-smoothing: antialiased; -ms-font-smoothing: antialiased; -o-font-smoothing: antialiased; }
|
||||
body { touch-action: none; overflow: hidden; width: 100%; height: 100%; margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "PingFang SC"; font-size: 12px; text-rendering: geometricPrecision; }
|
||||
button { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "PingFang SC"; }
|
||||
.center { position: absolute; margin: auto; top: 0; right: 0; bottom: 0; left: 0; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.select { user-select: text; -webkit-user-select: text; -moz-user-select: text; }
|
||||
.graph { display: flex; height: 100%; width: 100%; overflow: auto; outline: none; touch-action: pan-x pan-y; }
|
||||
.canvas { margin: auto; flex-shrink: 0; text-rendering: geometricPrecision; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.default { background-color: #ffffff; }
|
||||
.default .logo { display: none; }
|
||||
.default .graph { display: flex; opacity: 1; }
|
||||
.default .toolbar { display: table; }
|
||||
.toolbar { position: absolute; bottom: 10px; left: 10px; padding: 0; margin: 0; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.toolbar button:focus { outline: 0; }
|
||||
.toolbar-button { float: left; background: None; border-radius: 6px; border: 0; margin: 0; margin-right: 1px; padding: 0; fill: None; stroke: #777; cursor: pointer; width: 24px; height: 24px; user-select: none; }
|
||||
.toolbar-path { float: left }
|
||||
.toolbar-path-back-button { float: left; background: #777; border-top-left-radius: 6px; border-bottom-left-radius: 6px; border: 0px solid; border-color: #777; margin: 2px 0px 2px 8px; padding: 0 8px 0 8px; cursor: pointer; height: 20px; color: #ffffff; font-size: 11px; line-height: 0; transition: 0.1s; }
|
||||
.toolbar-path-back-button:hover { background: #000000; border-color: #000000; }
|
||||
.toolbar-path-name-button { float: left; background: #777; border: 0px solid; border-color: #777; color: #ffffff; border-left: 1px; border-left-color: #ffffff; margin: 2px 0 2px 1px; padding: 0 8px 0 8px; cursor: pointer; width: auto; height: 20px; font-size: 11px; line-height: 0; transition: 0.1s; }
|
||||
.toolbar-path-name-button:hover { background: #000000; border-color: #000000; }
|
||||
.toolbar-path-name-button:last-child { border-top-right-radius: 6px; border-bottom-right-radius: 6px; }
|
||||
.toolbar-icon .border { stroke: #fff; }
|
||||
.toolbar-icon .stroke { stroke: #808080; }
|
||||
.toolbar-icon:hover .stroke { stroke: #000000; }
|
||||
.welcome body { background-color: #ececec; }
|
||||
.welcome { background-color: #ececec; color: #242424; }
|
||||
.logo-icon { left: 0px; top: -18px; width: 106px; height: 106px; transition: 0.1s; }
|
||||
.logo-spinner { left: 0px; top: -18px; width: 106px; height: 106px; display: none; }
|
||||
.logo-stroke { stroke: #444444; }
|
||||
.logo-fill { fill: #444444; }
|
||||
.logo-border { stroke: #555555; }
|
||||
.logo-glyph { fill: #444444; }
|
||||
.logo-button { font-size: 12px; font-weight: bold; line-height: 1.25; text-align: center; vertical-align: middle; min-width: 5em; height: 2.7em; border-radius: 1.3em; transition: 0.1s; user-select: none; -webkit-user-select: none; -moz-user-select: none; color: #444444; background-color: #ececec; border: 1px solid #444444; }
|
||||
.logo-button:hover { color: #ececec; background-color: #444444; cursor: pointer; transition: 0.2s; }
|
||||
.logo-button:focus { outline: 0; }
|
||||
.progress { top: 120px; height: 2px; width: 400px; }
|
||||
.progress-bar { height: 100%; width: 0%; background-color: #444444; }
|
||||
.message .progress { display:none; }
|
||||
.welcome .graph { display: none; opacity: 0; }
|
||||
.welcome .menu { background-color: #ffffff; }
|
||||
.welcome.spinner .logo-spinner { display: block; -webkit-animation: orbit 0.5s infinite linear; animation: orbit 0.5s infinite linear; cursor: wait; }
|
||||
.welcome.spinner .menu-button { display: none; }
|
||||
.welcome.message .menu-button { display: none; }
|
||||
.titlebar { color: #aaaaaa; display: none; height: 32px; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2; -webkit-app-region: drag; }
|
||||
.titlebar-visible { display: block; }
|
||||
.titlebar-content { display: block; padding: 0 142px; height: 100%; text-align: center; font-size: 14px; line-height: 32px; transition: all .1s ease-in-out; user-select: none; }
|
||||
.titlebar-content-text { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.spinner .titlebar-content { opacity: 0; }
|
||||
.active .titlebar { color: #464646; transition: all 0.05s ease-in-out; }
|
||||
.titlebar-control-box { display: none; align-items: center; flex-direction: row-reverse; height: 100%; position: absolute; top: 0; right: 0; width: 138px; }
|
||||
.titlebar-control-box-visible { display: flex; }
|
||||
.titlebar-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; }
|
||||
.titlebar-button { display: flex; justify-content: center; align-items: center; width: 46px; height: 32px; user-select: none; -webkit-app-region: no-drag; }
|
||||
.titlebar-button:hover { color: #000000; background-color: rgba(0, 0, 0, 0.15); }
|
||||
.titlebar-button-close:hover { color: #ffffff; background-color: #b43029; }
|
||||
.menu-button { display: flex; justify-content: center; align-items: center; color: #aaaaaa; font-size: 20px; height: 32px; width: 32px; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2; -webkit-app-region: no-drag; -webkit-app-region: no-drag; user-select: none; }
|
||||
.menu-button:hover { color: #000000; }
|
||||
.menu { display: block; position: absolute; left: -17em; width: 17em; top: 0; height: 100%; z-index: 2; background-color: #ececec; border-right: 1px solid rgba(255, 255, 255, 0.5); padding-top: 40px; padding-bottom: 2px; margin-left: 0; margin-top: 0; overflow: hidden; transition: 0.1s; }
|
||||
.menu .menu-group { margin-bottom: 12px; }
|
||||
.menu .menu-group .menu-group-header { display: block; border: none; border-radius: 0; color: black; width: 100%; text-align: left; margin: 4px 12px 5px 12px; white-space: no-wrap; font-size: 11px; font-weight: bold; color: #bbbbbb; white-space: nowrap; }
|
||||
.menu .menu-group .menu-command { display: block; border: none; border-radius: 0; background-color: transparent; color: black; width: 100%; text-align: left; padding: 4px 12px 5px 12px; font-size: 12px; }
|
||||
.menu .menu-group .menu-command:focus { color: #ffffff; background-color: #2e6bd2; outline: none; }
|
||||
.menu .menu-group .menu-command:disabled { color: #888888; }
|
||||
.menu .menu-group .menu-command .menu-label { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
|
||||
.menu .menu-group .menu-command .menu-shortcut { display: block; float: right; margin-left: 25px; color: #888888; }
|
||||
.menu .menu-group .menu-separator { border-top: 1px; border-bottom: 0; border-style: solid; border-color: #e5e5e5; margin-left: 12px; margin-right: 12px; }
|
||||
@-webkit-keyframes orbit { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }
|
||||
@keyframes orbit { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }
|
||||
.welcome.spinner .logo-spinner-stroke { stroke: #ececec; }
|
||||
.welcome.spinner .graph { display: flex; opacity: 0; }
|
||||
.welcome .toolbar { display: none; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root { color-scheme: dark; }
|
||||
.default { background-color: #404040; }
|
||||
.graph { background-color: #404040; }
|
||||
.welcome { background-color: #1e1e1e; color: #888888; }
|
||||
.logo-stroke { stroke: #888888; }
|
||||
.logo-fill { fill: #888888; }
|
||||
.logo-border { stroke: #000000; }
|
||||
.logo-glyph { fill: #888888; }
|
||||
.logo-spinner-stroke { stroke: #ffffff; }
|
||||
.logo-button { color: #888888; background-color: #1e1e1e; border-color: #888888; }
|
||||
.logo-button:hover { color: #1e1e1e; background-color: #888888; }
|
||||
.welcome .progress-bar { background-color: #888888; }
|
||||
.welcome .menu { background-color: #2d2d2d }
|
||||
.toolbar-icon .border { stroke: #1d1d1d; }
|
||||
.toolbar-icon .stroke { stroke: #aaaaaa; }
|
||||
.toolbar-icon:hover .stroke { stroke: #dfdfdf; }
|
||||
.toolbar-path-back-button { background: #aaaaaa; border-color: #aaaaaa; color: #333333; }
|
||||
.toolbar-path-back-button:hover { background: #dfdfdf; border-color: #dfdfdf; }
|
||||
.toolbar-path-name-button { background: #aaaaaa ; border-color: #aaaaaa; color: #404040; }
|
||||
.toolbar-path-name-button:hover { background: #dfdfdf; border-color: #dfdfdf; }
|
||||
.titlebar { color: #949494; }
|
||||
.welcome body { background-color: #1e1e1e; }
|
||||
.default body { background-color: #404040; }
|
||||
.active .titlebar { color: #c4c4c4; }
|
||||
.titlebar-button:hover { color: #ffffff; background-color: rgba(0, 0, 0, 0.15); }
|
||||
.titlebar-button-close:hover { color: #ffffff; background-color: #b43029; }
|
||||
.menu-button { color: #aaaaaa; }
|
||||
.menu-button:hover { color: #ffffff; }
|
||||
.menu { background-color: #2d2d2d; border-color: rgba(0, 0, 0, 0); }
|
||||
.menu .menu-group .menu-group-header { color: #666666; }
|
||||
.menu .menu-group .menu-command { color: #ffffff; }
|
||||
.menu .menu-group .menu-command:focus { color: #ffffff; background-color: #2e6bd2; }
|
||||
.menu .menu-group .menu-command:disabled { color: #888888; }
|
||||
.menu .menu-group .menu-command .shortcut { color: #888888; }
|
||||
.menu .menu-group .menu-separator { border-color: #363636; }
|
||||
}
|
||||
@media all and (max-width: 640px) {
|
||||
.logo { width: 240px; }
|
||||
.logo-icon { left: 0; top: 0; width: 128px; height: 128px; }
|
||||
.logo-spinner { left: 0; top: 0; width: 128px; height: 128px; }
|
||||
.progress { top: 160px; height: 2px; width: 100px; }
|
||||
}
|
||||
@media only screen and (max-device-width: 1024px) {
|
||||
.toolbar-button { width: 32px; height: 32px; }
|
||||
.toolbar-path-back-button { margin-top: 6px; margin-bottom: 6px; }
|
||||
.toolbar-path-name-button { margin-top: 6px; margin-bottom: 6px; }
|
||||
}
|
||||
.sidebar { display: flex; flex-direction: column; font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif; font-size: 12px; height: 100%; right: -100%; position: fixed; transition: 0.1s; top: 0; background-color: #ececec; color: #242424; overflow: hidden; border-left: 1px solid rgba(255, 255, 255, 0.5); opacity: 0; }
|
||||
.sidebar-title { font-weight: bold; font-size: 12px; letter-spacing: 0.5px; text-transform: uppercase; height: 20px; margin: 0; padding: 20px; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.sidebar-closebutton { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; color: #777777; opacity: 1.0; display: block; transition: 0.2s; position: absolute; top: 0; right: 15px; margin-left: 50px; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.sidebar-closebutton:hover { color: #242424; }
|
||||
.sidebar-content { display: flex; flex-direction: column; flex-grow: 1; height: 0; }
|
||||
.sidebar-header { font-weight: bold; font-size: 11px; text-transform: uppercase; line-height: 1.25; margin-top: 16px; margin-bottom: 16px; border-bottom: 1px solid #ececec; display: block; user-select: none; -webkit-user-select: none; -moz-user-select: none; cursor: default; }
|
||||
.sidebar-object { flex-grow: 1; padding: 0px 20px 20px 20px; overflow-y: auto; }
|
||||
.sidebar-item { margin-bottom: 0px; display: block; }
|
||||
.sidebar-item-name { float: left; font-size: 11px; min-width: 95px; max-width: 95px; padding-right: 5px; padding-top: 7px; display: block; }
|
||||
.sidebar-item-name input { color: #777; font-family: inherit; font-size: inherit; color: inherit; background-color: inherit; width: 100%; text-align: right; margin: 0; padding: 0; border: 0; outline: none; text-overflow: ellipsis; }
|
||||
.sidebar-item-value-list { margin: 0; margin-left: 105px; overflow: hidden; display: block; padding: 0; }
|
||||
.sidebar-item-value { font-size: 11px; background-color: #fcfcfc; border-radius: 2px; border: 1px solid #fcfcfc; margin-top: 3px; margin-bottom: 3px; overflow: auto; }
|
||||
.sidebar-item-value-dark { background-color: #f8f8f8; border: 1px solid #f8f8f8; }
|
||||
.sidebar-item-value b { font-weight: bold; }
|
||||
.sidebar-item-value code { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
|
||||
.sidebar-item-value pre { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; margin: 0; overflow: auto; white-space: pre; word-wrap: normal; display: block; }
|
||||
.sidebar-item-value-line { padding: 4px 6px 4px 6px; }
|
||||
.sidebar-item-value-line-link { padding: 4px 6px 4px 6px; cursor: default; overflow-x: auto; }
|
||||
.sidebar-item-value-line-link:hover { text-decoration: underline; }
|
||||
.sidebar-item-value-line-border { padding: 4px 6px 4px 6px; border-top: 1px solid rgba(27, 31, 35, 0.05); }
|
||||
.sidebar-item-value-line-content { white-space: pre; word-wrap: normal; overflow: auto; display: block; }
|
||||
.sidebar-item-value-expander { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; float: right; color: #aaa; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; padding: 4px 6px 4px 6px; }
|
||||
.sidebar-item-value-expander:hover { color: #000; }
|
||||
.sidebar-item-select {
|
||||
font-family: inherit; font-size: 12px;
|
||||
background-color: #fcfcfc; border: #fcfcfc; color: #333;
|
||||
border-radius: 2px; width: 100%; height: 23px; padding: 3px 12px 3px 7px;
|
||||
margin-top: 3px; margin-bottom: 3px; outline: none;
|
||||
box-sizing: border-box; -moz-box-sizing: border-box;
|
||||
appearance: none; -webkit-appearance: none; -moz-appearance: none;
|
||||
background-image: linear-gradient(45deg, transparent 50%, #333 50%), linear-gradient(135deg, #333 50%, transparent 50%);
|
||||
background-position: calc(100% - 12px) calc(10px), calc(100% - 7px) calc(10px);
|
||||
background-size: 5px 5px, 5px 5px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.sidebar-separator { margin-bottom: 20px; }
|
||||
.sidebar-find-search { font-family: inherit; font-size: 13px; margin: 0px 20px 8px 20px; padding: 8px 16px 8px 16px; background: #fff; border-radius: 16px; border: 0; outline: 0; }
|
||||
.sidebar-find-content { flex-grow: 1; padding: 0px 20px 20px 20px; padding-right: 20px; overflow-y: auto; list-style-type: none; overflow-y: auto; margin: 0; }
|
||||
.sidebar-find-content li { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; margin: 0; padding: 5px 8px 5px 18px; outline: 0; white-space: nowrap; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.sidebar-find-content li:hover { background: #e5e5e5; }
|
||||
.sidebar-documentation { flex-grow: 1; padding: 0px 20px 20px 20px; overflow-y: auto; font-size: 13px; line-height: 1.5; margin: 0; }
|
||||
.sidebar-documentation h1 { font-weight: bold; font-size: 13px; line-height: 1.25; border-bottom: 1px solid #e8e8e8; padding-bottom: 0.3em; margin-top: 0; margin-bottom: 16px; }
|
||||
.sidebar-documentation h2 { font-weight: bold; font-size: 11px; line-height: 1.25; margin-top: 20px; margin-bottom: 16px; text-transform: uppercase; border: 0; }
|
||||
.sidebar-documentation h3 { font-weight: bold; font-size: 11px; line-height: 1.25; }
|
||||
.sidebar-documentation p { margin-top: 4px; margin-bottom: 4px; margin-left: 0px; }
|
||||
.sidebar-documentation a { color: #237; }
|
||||
.sidebar-documentation code { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; background-color: rgba(27, 31, 35, 0.05); padding: 0.2em 0.4em; margin: 0; border-radius: 3px; }
|
||||
.sidebar-documentation pre { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; }
|
||||
.sidebar-documentation pre code { font-size: 13px; padding: 16px; line-height: 1.45; background-color: transparent; padding: 0; border-radius: 0; }
|
||||
.sidebar-documentation tt { font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-weight: bold; font-size: 90%; background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; padding: 0.2em 0.4em; margin: 0; }
|
||||
.sidebar-documentation dl dt { font-size: 13px; font-weight: bold; padding: 0; margin-top: 16px; margin-left: 0px; }
|
||||
.sidebar-documentation dd { padding: 0 16px; margin-left: 0; margin-bottom: 16px; }
|
||||
.sidebar-documentation ul { margin-top: 6px; margin-bottom: 6px; padding-left: 20px; }
|
||||
.sidebar-documentation blockquote { margin-left: 15px; margin-right: 15px; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.sidebar html { color: #dfdfdf; }
|
||||
.sidebar { background-color: #2d2d2d; color: #dfdfdf; border-left: 1px solid rgba(0, 0, 0, 0); }
|
||||
.sidebar-closebutton { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 25px; color: #777777; opacity: 1.0; display: block; transition: 0.2s; position: absolute; top: 0; right: 15px; margin-left: 50px; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
|
||||
.sidebar-closebutton:hover { color: #ffffff; }
|
||||
.sidebar-item-value { background-color: #383838; border-color: #383838; }
|
||||
.sidebar-item-value-dark { background-color: #3e3e3e; border-color: #3e3e3e; }
|
||||
.sidebar-item-value-line-border { border-color: rgba(0, 0, 0, 0.09); }
|
||||
.sidebar-item-select { background-color: #383838; border: #383838; color: #dfdfdf; background-image: linear-gradient(45deg, transparent 50%, #aaa 50%), linear-gradient(135deg, #aaa 50%, transparent 50%); }
|
||||
.sidebar-header { border-bottom-color: #2d2d2d; color: #dfdfdf; }
|
||||
.sidebar-documentation h1 { border-bottom: 1px solid #424242; color: #dfdfdf; }
|
||||
.sidebar-documentation h2 { color: #dfdfdf; }
|
||||
.sidebar-documentation p { color: #aaaaaa; }
|
||||
.sidebar-documentation a { color: #6688aa; }
|
||||
.sidebar-documentation tt { background-color:#1e1e1e; }
|
||||
.sidebar-documentation code { background-color: #1e1e1e; }
|
||||
.sidebar-documentation pre { background-color: #1e1e1e; }
|
||||
.sidebar-find-search { background: #383838; color: #dfdfdf; border-color: #424242; }
|
||||
.sidebar-find-content li:hover { background: #383838; }
|
||||
}
|
||||
@media screen and (prefers-reduced-motion: reduce) {
|
||||
.menu { transition: none; }
|
||||
.sidebar { transition: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="welcome spinner">
|
||||
<div id="graph" class="graph" tabindex="0">
|
||||
<svg id="canvas" class="canvas" preserveaspectratio="xMidYMid meet" width="100%" height="100%"></svg>
|
||||
</div>
|
||||
<div id="sidebar" class="sidebar">
|
||||
<h1 id="sidebar-title" class="sidebar-title"></h1>
|
||||
<a id="sidebar-closebutton" class="sidebar-closebutton" href="javascript:void(0)" draggable="false">×</a>
|
||||
<div id="sidebar-content" class="sidebar-content"></div>
|
||||
</div>
|
||||
<div id="toolbar" class="toolbar">
|
||||
<button id="sidebar-button" class="toolbar-button" title="Model Properties">
|
||||
<svg class="toolbar-icon" viewbox="0 0 100 100">
|
||||
<rect class="border" x="12" y="12" width="76" height="76" rx="16" ry="16" stroke-width="8"></rect>
|
||||
<line class="border" x1="28" y1="37" x2="32" y2="37" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="28" y1="50" x2="32" y2="50" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="28" y1="63" x2="32" y2="63" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="40" y1="37" x2="70" y2="37" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="40" y1="50" x2="70" y2="50" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="40" y1="63" x2="70" y2="63" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<rect class="stroke" x="12" y="12" width="76" height="76" rx="16" ry="16" stroke-width="4"></rect>
|
||||
<line class="stroke" x1="28" y1="37" x2="32" y2="37" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="28" y1="50" x2="32" y2="50" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="28" y1="63" x2="32" y2="63" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="40" y1="37" x2="70" y2="37" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="40" y1="50" x2="70" y2="50" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="40" y1="63" x2="70" y2="63" stroke-width="4" stroke-linecap="round"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="zoom-in-button" class="toolbar-button" title="Zoom In">
|
||||
<svg class="toolbar-icon" viewbox="0 0 100 100">
|
||||
<circle class="border" cx="50" cy="50" r="35" stroke-width="8" stroke="#fff"></circle>
|
||||
<line class="border" x1="50" y1="38" x2="50" y2="62" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="38" y1="50" x2="62" y2="50" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="78" y1="78" x2="82" y2="82" stroke-width="12" stroke-linecap="square"
|
||||
stroke="#fff"></line>
|
||||
<circle class="stroke" cx="50" cy="50" r="35" stroke-width="4"></circle>
|
||||
<line class="stroke" x1="50" y1="38" x2="50" y2="62" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="38" y1="50" x2="62" y2="50" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="78" y1="78" x2="82" y2="82" stroke-width="8" stroke-linecap="square"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="zoom-out-button" class="toolbar-button" title="Zoom Out">
|
||||
<svg class="toolbar-icon" viewbox="0 0 100 100">
|
||||
<circle class="border" cx="50" cy="50" r="35" stroke-width="8" stroke="#fff"></circle>
|
||||
<line class="border" x1="38" y1="50" x2="62" y2="50" stroke-width="8" stroke-linecap="round"
|
||||
stroke="#fff"></line>
|
||||
<line class="border" x1="78" y1="78" x2="82" y2="82" stroke-width="12" stroke-linecap="square"
|
||||
stroke="#fff"></line>
|
||||
<circle class="stroke" cx="50" cy="50" r="35" stroke-width="4"></circle>
|
||||
<line class="stroke" x1="38" y1="50" x2="62" y2="50" stroke-width="4" stroke-linecap="round"></line>
|
||||
<line class="stroke" x1="78" y1="78" x2="82" y2="82" stroke-width="8" stroke-linecap="square"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<div id="toolbar-path" class="toolbar-path">
|
||||
<button id="toolbar-path-back-button" class="toolbar-path-back-button" title="Back">
|
||||
❮
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="logo" class="center logo">
|
||||
<a href="javascript:;" target="blank_">
|
||||
<svg class="center logo-icon" viewbox="0 0 1024 1024">
|
||||
<circle class="logo-stroke" cx="512" cy="512" r="431" fill="none" stroke-width="32"></circle>
|
||||
<circle class="logo-border" cx="512" cy="512" r="450" fill="none" stroke-width="6"></circle>
|
||||
<circle class="logo-border" cx="512" cy="512" r="412" fill="none" stroke-width="6"></circle>
|
||||
<line class="logo-stroke" x1="296" y1="392" x2="540" y2="280" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="632" x2="540" y2="280" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="392" x2="540" y2="435" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="632" x2="540" y2="435" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="392" x2="540" y2="590" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="632" x2="540" y2="590" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="392" x2="540" y2="744" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="296" y1="632" x2="540" y2="744" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="540" y1="280" x2="785" y2="512" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="540" y1="590" x2="785" y2="512" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="540" y1="435" x2="785" y2="512" stroke-width="12"></line>
|
||||
<line class="logo-stroke" x1="540" y1="744" x2="785" y2="512" stroke-width="12"></line>
|
||||
<g transform="translate(296, 392)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
<g transform="translate(296, 632)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
<g transform="translate(540, 280)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
<g transform="translate(540, 435)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
<g transform="translate(540, 590)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
<g transform="translate(540, 744)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
<g transform="translate(785, 512)">
|
||||
<circle class="logo-fill" cx="0" cy="0" r="51"></circle>
|
||||
<circle class="logo-border" cx="0" cy="0" r="51" fill="none" stroke-width="6"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
<svg id="logo-spinner" class="center logo-spinner" viewbox="0 0 1024 1024">
|
||||
<g transform="translate(512, 512)" style="opacity: 1">
|
||||
<path class="logo-spinner-stroke" d="M-431,0 A-431,-431 0 0,1 0,-431" stroke-width="24" fill="None">
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
<div class="center progress">
|
||||
<div id="progress-bar" class="progress-bar"></div>
|
||||
</div>
|
||||
<!-- Preload fonts to workaround Chrome SVG layout issue -->
|
||||
<div style="font-weight: normal; color: rgba(0, 0, 0, 0.01); user-select: none;">.</div>
|
||||
<div style="font-weight: bold; color: rgba(0, 0, 0, 0.01); user-select: none;">.</div>
|
||||
<div style="font-weight: bold; color: rgba(0, 0, 0, 0.01); user-select: none;">.</div>
|
||||
</div>
|
||||
<div id="titlebar" class="titlebar">
|
||||
<svg style="position: absolute; width: 0px; height: 0px; overflow: hidden;" aria-hidden="true">
|
||||
<symbol id="icon-arrow-right" viewBox="0 0 1024 1024">
|
||||
<path
|
||||
d="M698.75712 565.02272l-191.488 225.4848a81.73568 81.73568 0 0 1-62.48448 28.89728 81.89952 81.89952 0 0 1-62.40256-134.94272l146.432-172.4416-146.432-172.4416a81.92 81.92 0 0 1 124.88704-106.06592l191.488 225.4848a81.87904 81.87904 0 0 1 0 106.02496z">
|
||||
</path>
|
||||
</symbol>
|
||||
</svg>
|
||||
<div id="titlebar-content" class="titlebar-content">
|
||||
<span id="titlebar-content-text" class="titlebar-content-text"></span>
|
||||
</div>
|
||||
<div id="titlebar-control-box" class="titlebar-control-box">
|
||||
<div id="titlebar-close" class="titlebar-button titlebar-button-close" title="Close">
|
||||
<svg class="titlebar-icon" aria-hidden="true">
|
||||
<path
|
||||
d="M 0,0 0,0.7 4.3,5 0,9.3 0,10 0.7,10 5,5.7 9.3,10 10,10 10,9.3 5.7,5 10,0.7 10,0 9.3,0 5,4.3 0.7,0 Z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="titlebar-toggle" class="titlebar-button" title="Maximize">
|
||||
<svg id="titlebar-maximize" class="titlebar-icon" aria-hidden="true" style="position: absolute;">
|
||||
<path d="M 0,0 0,10 10,10 10,0 Z M 1,1 9,1 9,9 1,9 Z"></path>
|
||||
</svg>
|
||||
<svg id="titlebar-restore" class="titlebar-icon" aria-hidden="true" style="position: absolute;">
|
||||
<path
|
||||
d="m 2,1e-5 0,2 -2,0 0,8 8,0 0,-2 2,0 0,-8 z m 1,1 6,0 0,6 -1,0 0,-5 -5,0 z m -2,2 6,0 0,6 -6,0 z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="titlebar-minimize" class="titlebar-button" title="Minimize">
|
||||
<svg class="titlebar-icon" aria-hidden="true">
|
||||
<path d="M 0,5 10,5 10,6 0,6 Z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="menu" class="menu" style="opacity: 1; left: 0px;display: none;">
|
||||
<div id="menu-item-0" class="menu-group" style="opacity: 1">
|
||||
<div class="menu-group-header"><u>F</u>ile</div>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.export(document.body.title+'.png')">
|
||||
<span class="menu-label">Export as PNG</span>
|
||||
</button>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.export(document.body.title+'.svg')" >
|
||||
<span class="menu-label">Export as SVG</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="menu-item-1" class="menu-group" style="opacity: 1">
|
||||
<div class="menu-group-header"><u>E</u>dit</div>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.find()">
|
||||
<span class="menu-label">Find...</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="menu-item-2" class="menu-group" style="opacity: 1">
|
||||
<div class="menu-group-header"><u>V</u>iew</div>
|
||||
<button class="menu-command" style="display: block" onclick="doToggle('attributes')">
|
||||
<span class="menu-label" id="opAtt">Show Attributes</span></button>
|
||||
<button class="menu-command" style="display: block" onclick="doToggle('weights')">
|
||||
<span class="menu-label" id="opWeight">Show &Weights</span></button>
|
||||
<button class="menu-command" style="display: block" onclick="doToggle('names')">
|
||||
<span class="menu-label" id="opName">Show Names</span></button>
|
||||
<button class="menu-command" style="display: block" onclick="doToggle('direction')">
|
||||
<span class="menu-label" id="opDir">Show Horizontal</span>
|
||||
</button>
|
||||
<button class="menu-command" style="display: block" onclick="doToggle('mousewheel')">
|
||||
<span class="menu-label" id="opMouse">Mouse Wheel: Zoom</span>
|
||||
</button>
|
||||
<div class="menu-separator" style="display: block"></div>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.zoomIn()">
|
||||
<span class="menu-label">Zoom In</span></button>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.zoomOut()">
|
||||
<span class="menu-label">Zoom Out</span></button>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.resetZoom()">
|
||||
<span class="menu-label">Actual Size</span>
|
||||
</button>
|
||||
<div class="menu-separator" style="display: block" ></div>
|
||||
<button class="menu-command" style="display: block" onclick="mainView.showModelProperties()">
|
||||
<span class="menu-label">Properties...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="menu-button" class="menu-button" onclick="toggleMenu()">≡</div>
|
||||
<script>
|
||||
function init(){
|
||||
var s=location.search;
|
||||
var url="";
|
||||
var onnxModelName="";
|
||||
if(s.indexOf("=")>=0){
|
||||
url=s.substring(s.indexOf("=")+1);
|
||||
if(url.toLocaleLowerCase().indexOf(".onnx")>=0){
|
||||
onnxModelName=url.substring(url.lastIndexOf("/")+1)
|
||||
}else{
|
||||
console.error("使用方法:onnx.html?url=[onnx路径]")
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
console.error("使用方法:onnx.html?url=[onnx路径]")
|
||||
return;
|
||||
}
|
||||
document.body.title=onnxModelName;
|
||||
//url='./siamRPN_192.onnx'
|
||||
var http=new XMLHttpRequest();
|
||||
http.responseType="arraybuffer"
|
||||
http.open('GET',url);
|
||||
http.onload=function(){
|
||||
if(http.status==200){
|
||||
var reader=proto.protobuf.Reader.create(new Uint8Array(http.response));
|
||||
var onnxProtoModel = window.proto.onnx.ModelProto.decode(reader);
|
||||
let { locations, graphs } = window.getExternalLocations(onnxProtoModel);
|
||||
let model = new window.onnx.Model(onnxProtoModel, graphs, new Map());
|
||||
|
||||
let host = window;
|
||||
let view = new window.View(host);
|
||||
view.start().then((data) => {
|
||||
view.open(model, onnxModelName);
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
window.mainView=view;
|
||||
}
|
||||
};
|
||||
http.send();
|
||||
}
|
||||
init();
|
||||
</script>
|
||||
<script>
|
||||
function exportImg(file, blob) {
|
||||
const element = this.document.createElement('a');
|
||||
element.download = file;
|
||||
element.href = URL.createObjectURL(blob);
|
||||
this.document.body.appendChild(element);
|
||||
element.click();
|
||||
this.document.body.removeChild(element);
|
||||
}
|
||||
function toggleMenu(){
|
||||
let el=document.getElementById("menu");
|
||||
if(el.style.display=="none"){
|
||||
el.style.display="block"
|
||||
updateState();
|
||||
}else{
|
||||
el.style.display="none"
|
||||
}
|
||||
}
|
||||
function doToggle(att){
|
||||
mainView.toggle(att)
|
||||
updateState();
|
||||
}
|
||||
function updateState(){
|
||||
var op=mainView.options;
|
||||
document.getElementById("opAtt").innerText=op.attributes ? 'Hide Attributes' : 'Show Attributes';
|
||||
document.getElementById("opWeight").innerText=op.weights ? 'Hide Weights' : 'Show Weights';
|
||||
document.getElementById("opName").innerText=op.names ? 'Hide Names' : 'Show Names';
|
||||
document.getElementById("opDir").innerText=op.direction == 'vertical' ? 'Show Horizontal' : 'Show Vertical';
|
||||
document.getElementById("opMouse").innerText=op.mousewheel == 'scroll' ? 'Mouse Wheel: Zoom' : 'Mouse Wheel: Scroll';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,726 @@
|
|||
const base = {};
|
||||
|
||||
base.Int64 = class Int64 {
|
||||
|
||||
constructor(low, high) {
|
||||
this.low = low | 0;
|
||||
this.high = high | 0;
|
||||
}
|
||||
|
||||
static create(value) {
|
||||
if (isNaN(value)) {
|
||||
return base.Int64.zero;
|
||||
}
|
||||
if (value <= -9223372036854776000) {
|
||||
return base.Int64.min;
|
||||
}
|
||||
if (value + 1 >= 9223372036854776000) {
|
||||
return base.Int64.max;
|
||||
}
|
||||
if (value < 0) {
|
||||
return base.Int64.create(-value).negate();
|
||||
}
|
||||
return new base.Int64((value % 4294967296) | 0, (value / 4294967296));
|
||||
}
|
||||
|
||||
get isZero() {
|
||||
return this.low === 0 && this.high === 0;
|
||||
}
|
||||
|
||||
get isNegative() {
|
||||
return this.high < 0;
|
||||
}
|
||||
|
||||
negate() {
|
||||
if (this.equals(base.Int64.min)) {
|
||||
return base.Int64.min;
|
||||
}
|
||||
return this.not().add(base.Int64.one);
|
||||
}
|
||||
|
||||
not() {
|
||||
return new base.Int64(~this.low, ~this.high);
|
||||
}
|
||||
|
||||
equals(other) {
|
||||
if (!(other instanceof base.Int64) && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) {
|
||||
return false;
|
||||
}
|
||||
return this.high === other.high && this.low === other.low;
|
||||
}
|
||||
|
||||
compare(other) {
|
||||
if (this.equals(other)) {
|
||||
return 0;
|
||||
}
|
||||
const thisNeg = this.isNegative;
|
||||
const otherNeg = other.isNegative;
|
||||
if (thisNeg && !otherNeg) {
|
||||
return -1;
|
||||
}
|
||||
if (!thisNeg && otherNeg) {
|
||||
return 1;
|
||||
}
|
||||
return this.subtract(other).isNegative ? -1 : 1;
|
||||
}
|
||||
|
||||
add(other) {
|
||||
return base.Utility.add(this, other, false);
|
||||
}
|
||||
|
||||
subtract(other) {
|
||||
return base.Utility.subtract(this, other, false);
|
||||
}
|
||||
|
||||
multiply(other) {
|
||||
return base.Utility.multiply(this, other, false);
|
||||
}
|
||||
|
||||
divide(other) {
|
||||
return base.Utility.divide(this, other, false);
|
||||
}
|
||||
|
||||
toInteger() {
|
||||
return this.low;
|
||||
}
|
||||
|
||||
toNumber() {
|
||||
if (this.high === 0) {
|
||||
return this.low >>> 0;
|
||||
}
|
||||
if (this.high === -1) {
|
||||
return this.low;
|
||||
}
|
||||
return (this.high * 4294967296) + (this.low >>> 0);
|
||||
}
|
||||
|
||||
toString(radix) {
|
||||
const r = radix || 10;
|
||||
if (r < 2 || r > 16) {
|
||||
throw new RangeError('radix');
|
||||
}
|
||||
if (this.isZero) {
|
||||
return '0';
|
||||
}
|
||||
if (this.high < 0) {
|
||||
if (this.equals(base.Int64.min)) {
|
||||
const radix = new base.Int64(r, 0);
|
||||
const div = this.divide(radix);
|
||||
const remainder = div.multiply(radix).subtract(this);
|
||||
return div.toString(radix) + (remainder.low >>> 0).toString(radix);
|
||||
}
|
||||
return '-' + this.negate().toString(r);
|
||||
}
|
||||
if (this.high === 0) {
|
||||
return this.low.toString(radix);
|
||||
}
|
||||
return base.Utility.text(this, false, r);
|
||||
}
|
||||
};
|
||||
|
||||
base.Int64.min = new base.Int64(0, -2147483648);
|
||||
base.Int64.zero = new base.Int64(0, 0);
|
||||
base.Int64.one = new base.Int64(1, 0);
|
||||
base.Int64.negativeOne = new base.Int64(-1, 0);
|
||||
base.Int64.power24 = new base.Int64(1 << 24, 0);
|
||||
base.Int64.max = new base.Int64(0, 2147483647);
|
||||
|
||||
base.Uint64 = class Uint64 {
|
||||
|
||||
constructor(low, high) {
|
||||
this.low = low | 0;
|
||||
this.high = high | 0;
|
||||
}
|
||||
|
||||
static create(value) {
|
||||
if (isNaN(value)) {
|
||||
return base.Uint64.zero;
|
||||
}
|
||||
if (value < 0) {
|
||||
return base.Uint64.zero;
|
||||
}
|
||||
if (value >= 18446744073709552000) {
|
||||
return base.Uint64.max;
|
||||
}
|
||||
if (value < 0) {
|
||||
return base.Uint64.create(-value).negate();
|
||||
}
|
||||
return new base.Uint64((value % 4294967296) | 0, (value / 4294967296));
|
||||
}
|
||||
|
||||
get isZero() {
|
||||
return this.low === 0 && this.high === 0;
|
||||
}
|
||||
|
||||
get isNegative() {
|
||||
return false;
|
||||
}
|
||||
|
||||
negate() {
|
||||
return this.not().add(base.Int64.one);
|
||||
}
|
||||
|
||||
not() {
|
||||
return new base.Uint64(~this.low, ~this.high);
|
||||
}
|
||||
|
||||
equals(other) {
|
||||
if (!(other instanceof base.Uint64) && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) {
|
||||
return false;
|
||||
}
|
||||
return this.high === other.high && this.low === other.low;
|
||||
}
|
||||
|
||||
compare(other) {
|
||||
if (this.equals(other)) {
|
||||
return 0;
|
||||
}
|
||||
const thisNeg = this.isNegative;
|
||||
const otherNeg = other.isNegative;
|
||||
if (thisNeg && !otherNeg) {
|
||||
return -1;
|
||||
}
|
||||
if (!thisNeg && otherNeg) {
|
||||
return 1;
|
||||
}
|
||||
return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
|
||||
}
|
||||
|
||||
add(other) {
|
||||
return base.Utility.add(this, other, true);
|
||||
}
|
||||
|
||||
subtract(other) {
|
||||
return base.Utility.subtract(this, other, true);
|
||||
}
|
||||
|
||||
multiply(other) {
|
||||
return base.Utility.multiply(this, other, true);
|
||||
}
|
||||
|
||||
divide(other) {
|
||||
return base.Utility.divide(this, other, true);
|
||||
}
|
||||
|
||||
toInteger() {
|
||||
return this.low >>> 0;
|
||||
}
|
||||
|
||||
toNumber() {
|
||||
if (this.high === 0) {
|
||||
return this.low >>> 0;
|
||||
}
|
||||
return ((this.high >>> 0) * 4294967296) + (this.low >>> 0);
|
||||
}
|
||||
|
||||
toString(radix) {
|
||||
const r = radix || 10;
|
||||
if (r < 2 || 36 < r) {
|
||||
throw new RangeError('radix');
|
||||
}
|
||||
if (this.isZero) {
|
||||
return '0';
|
||||
}
|
||||
if (this.high === 0) {
|
||||
return this.low.toString(radix);
|
||||
}
|
||||
return base.Utility.text(this, true, r);
|
||||
}
|
||||
};
|
||||
|
||||
base.Utility = class {
|
||||
|
||||
static add(a, b, unsigned) {
|
||||
const a48 = a.high >>> 16;
|
||||
const a32 = a.high & 0xFFFF;
|
||||
const a16 = a.low >>> 16;
|
||||
const a00 = a.low & 0xFFFF;
|
||||
const b48 = b.high >>> 16;
|
||||
const b32 = b.high & 0xFFFF;
|
||||
const b16 = b.low >>> 16;
|
||||
const b00 = b.low & 0xFFFF;
|
||||
let c48 = 0;
|
||||
let c32 = 0;
|
||||
let c16 = 0;
|
||||
let c00 = 0;
|
||||
c00 += a00 + b00;
|
||||
c16 += c00 >>> 16;
|
||||
c00 &= 0xFFFF;
|
||||
c16 += a16 + b16;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c32 += a32 + b32;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c48 += a48 + b48;
|
||||
c48 &= 0xFFFF;
|
||||
return base.Utility._create((c16 << 16) | c00, (c48 << 16) | c32, unsigned);
|
||||
}
|
||||
|
||||
static subtract(a, b, unsigned) {
|
||||
return base.Utility.add(a, b.negate(), unsigned);
|
||||
}
|
||||
|
||||
static multiply(a, b, unsigned) {
|
||||
if (a.isZero) {
|
||||
return base.Int64.zero;
|
||||
}
|
||||
if (b.isZero) {
|
||||
return base.Int64.zero;
|
||||
}
|
||||
if (a.equals(base.Int64.min)) {
|
||||
return b.isOdd() ? base.Int64.min : base.Int64.zero;
|
||||
}
|
||||
if (b.equals(base.Int64.min)) {
|
||||
return a.isOdd() ? base.Int64.min : base.Int64.zero;
|
||||
}
|
||||
if (a.isNegative) {
|
||||
if (b.isNegative) {
|
||||
return a.negate().multiply(b.negate());
|
||||
}
|
||||
return a.negate().multiply(b).negate();
|
||||
} else if (b.isNegative) {
|
||||
return a.multiply(b.negate()).negate();
|
||||
}
|
||||
if (a.compare(base.Int64.power24) < 0 && b.compare(base.Int64.power24) < 0) {
|
||||
return unsigned ? base.Uint64.create(a.toNumber() * b.toNumber()) : base.Int64.create(a.toNumber() * b.toNumber());
|
||||
}
|
||||
const a48 = a.high >>> 16;
|
||||
const a32 = a.high & 0xFFFF;
|
||||
const a16 = a.low >>> 16;
|
||||
const a00 = a.low & 0xFFFF;
|
||||
const b48 = b.high >>> 16;
|
||||
const b32 = b.high & 0xFFFF;
|
||||
const b16 = b.low >>> 16;
|
||||
const b00 = b.low & 0xFFFF;
|
||||
let c48 = 0;
|
||||
let c32 = 0;
|
||||
let c16 = 0;
|
||||
let c00 = 0;
|
||||
c00 += a00 * b00;
|
||||
c16 += c00 >>> 16;
|
||||
c00 &= 0xFFFF;
|
||||
c16 += a16 * b00;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c16 += a00 * b16;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c32 += a32 * b00;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c32 += a16 * b16;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c32 += a00 * b32;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
|
||||
c48 &= 0xFFFF;
|
||||
return base.Utility._create((c16 << 16) | c00, (c48 << 16) | c32, unsigned);
|
||||
}
|
||||
|
||||
static divide(a, b, unsigned) {
|
||||
if (b.isZero) {
|
||||
throw new Error('Division by zero.');
|
||||
}
|
||||
if (a.isZero) {
|
||||
return unsigned ? base.Uint64.zero : base.Int64.zero;
|
||||
}
|
||||
let approx;
|
||||
let remainder;
|
||||
let result;
|
||||
if (!unsigned) {
|
||||
if (a.equals(base.Int64.min)) {
|
||||
if (b.equals(base.Int64.one) || b.equals(base.Int64.negativeOne)) {
|
||||
return base.Int64.min;
|
||||
} else if (b.equals(base.Int64.min)) {
|
||||
return base.Int64.one;
|
||||
}
|
||||
const half = base.Utility._shiftRight(a, unsigned, 1);
|
||||
const halfDivide = half.divide(b);
|
||||
approx = base.Utility._shiftLeft(halfDivide, halfDivide instanceof base.Uint64, 1);
|
||||
if (approx.equals(base.Int64.zero)) {
|
||||
return b.isNegative ? base.Int64.one : base.Int64.negativeOne;
|
||||
}
|
||||
remainder = a.subtract(b.multiply(approx));
|
||||
result = approx.add(remainder.divide(b));
|
||||
return result;
|
||||
} else if (b.equals(base.Int64.min)) {
|
||||
return base.Int64.zero;
|
||||
}
|
||||
if (a.isNegative) {
|
||||
if (b.isNegative) {
|
||||
return this.negate().divide(b.negate());
|
||||
}
|
||||
return a.negate().divide(b).negate();
|
||||
} else if (b.isNegative) {
|
||||
return a.divide(b.negate()).negate();
|
||||
}
|
||||
result = base.Int64.zero;
|
||||
} else {
|
||||
if (!(b instanceof base.Uint64)) {
|
||||
b = new base.Uint64(b.low, b.high);
|
||||
}
|
||||
if (b.compare(a) > 0) {
|
||||
return base.Int64.zero;
|
||||
}
|
||||
if (b.compare(base.Utility._shiftRight(a, unsigned, 1)) > 0) {
|
||||
return base.Uint64.one;
|
||||
}
|
||||
result = base.Uint64.zero;
|
||||
}
|
||||
remainder = a;
|
||||
while (remainder.compare(b) >= 0) {
|
||||
let approx = Math.max(1, Math.floor(remainder.toNumber() / b.toNumber()));
|
||||
const log2 = Math.ceil(Math.log(approx) / Math.LN2);
|
||||
const delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
|
||||
let approxResult = base.Int64.create(approx);
|
||||
let approxRemainder = approxResult.multiply(b);
|
||||
while (approxRemainder.isNegative || approxRemainder.compare(remainder) > 0) {
|
||||
approx -= delta;
|
||||
approxResult = unsigned ? base.Uint64.create(approx) : base.Int64.create(approx);
|
||||
approxRemainder = approxResult.multiply(b);
|
||||
}
|
||||
if (approxResult.isZero) {
|
||||
approxResult = base.Int64.one;
|
||||
}
|
||||
result = result.add(approxResult);
|
||||
remainder = remainder.subtract(approxRemainder);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static text(value, unsigned, radix) {
|
||||
const power = unsigned ? base.Uint64.create(Math.pow(radix, 6)) : base.Int64.create(Math.pow(radix, 6));
|
||||
let remainder = value;
|
||||
let result = '';
|
||||
for (; ;) {
|
||||
const remainderDiv = remainder.divide(power);
|
||||
const intval = remainder.subtract(remainderDiv.multiply(power)).toInteger() >>> 0;
|
||||
let digits = intval.toString(radix);
|
||||
remainder = remainderDiv;
|
||||
if (remainder.low === 0 && remainder.high === 0) {
|
||||
return digits + result;
|
||||
}
|
||||
while (digits.length < 6) {
|
||||
digits = '0' + digits;
|
||||
}
|
||||
result = '' + digits + result;
|
||||
}
|
||||
}
|
||||
|
||||
static _shiftLeft(value, unsigned, shift) {
|
||||
return base.Utility._create(value.low << shift, (value.high << shift) | (value.low >>> (32 - shift)), unsigned);
|
||||
}
|
||||
|
||||
static _shiftRight(value, unsigned, shift) {
|
||||
return base.Utility._create((value.low >>> shift) | (value.high << (32 - shift)), value.high >> shift, unsigned);
|
||||
}
|
||||
|
||||
static _create(low, high, unsigned) {
|
||||
return unsigned ? new base.Uint64(low, high) : new base.Int64(low, high);
|
||||
}
|
||||
};
|
||||
|
||||
base.Uint64.zero = new base.Uint64(0, 0);
|
||||
base.Uint64.one = new base.Uint64(1, 0);
|
||||
base.Uint64.max = new base.Uint64(-1, -1);
|
||||
|
||||
base.Complex64 = class Complex {
|
||||
|
||||
constructor(real, imaginary) {
|
||||
this.real = real;
|
||||
this.imaginary = imaginary;
|
||||
}
|
||||
|
||||
static create(real, imaginary) {
|
||||
return new base.Complex64(real, imaginary);
|
||||
}
|
||||
|
||||
toString(/* radix */) {
|
||||
return this.real + ' + ' + this.imaginary + 'i';
|
||||
}
|
||||
};
|
||||
|
||||
base.Complex128 = class Complex {
|
||||
|
||||
constructor(real, imaginary) {
|
||||
this.real = real;
|
||||
this.imaginary = imaginary;
|
||||
}
|
||||
|
||||
static create(real, imaginary) {
|
||||
return new base.Complex128(real, imaginary);
|
||||
}
|
||||
|
||||
toString(/* radix */) {
|
||||
return this.real + ' + ' + this.imaginary + 'i';
|
||||
}
|
||||
};
|
||||
|
||||
if (!DataView.prototype.getFloat16) {
|
||||
DataView.prototype.getFloat16 = function (byteOffset, littleEndian) {
|
||||
const value = this.getUint16(byteOffset, littleEndian);
|
||||
const e = (value & 0x7C00) >> 10;
|
||||
let f = value & 0x03FF;
|
||||
if (e == 0) {
|
||||
f = 0.00006103515625 * (f / 1024);
|
||||
} else if (e == 0x1F) {
|
||||
f = f ? NaN : Infinity;
|
||||
} else {
|
||||
f = DataView.__float16_pow[e] * (1 + (f / 1024));
|
||||
}
|
||||
return value & 0x8000 ? -f : f;
|
||||
};
|
||||
DataView.__float16_pow = {
|
||||
1: 1 / 16384, 2: 1 / 8192, 3: 1 / 4096, 4: 1 / 2048, 5: 1 / 1024, 6: 1 / 512, 7: 1 / 256, 8: 1 / 128,
|
||||
9: 1 / 64, 10: 1 / 32, 11: 1 / 16, 12: 1 / 8, 13: 1 / 4, 14: 1 / 2, 15: 1, 16: 2,
|
||||
17: 4, 18: 8, 19: 16, 20: 32, 21: 64, 22: 128, 23: 256, 24: 512,
|
||||
25: 1024, 26: 2048, 27: 4096, 28: 8192, 29: 16384, 30: 32768, 31: 65536
|
||||
};
|
||||
}
|
||||
|
||||
if (!DataView.prototype.setFloat16) {
|
||||
DataView.prototype.setFloat16 = function (byteOffset, value, littleEndian) {
|
||||
DataView.__float16_float[0] = value;
|
||||
[value] = DataView.__float16_int;
|
||||
const s = (value >>> 16) & 0x8000;
|
||||
const e = (value >>> 23) & 0xff;
|
||||
const f = value & 0x7fffff;
|
||||
const v = s | DataView.__float16_base[e] | (f >> DataView.__float16_shift[e]);
|
||||
this.setUint16(byteOffset, v, littleEndian);
|
||||
};
|
||||
DataView.__float16_float = new Float32Array(1);
|
||||
DataView.__float16_int = new Uint32Array(DataView.__float16_float.buffer, 0, DataView.__float16_float.length);
|
||||
DataView.__float16_base = new Uint32Array(256);
|
||||
DataView.__float16_shift = new Uint32Array(256);
|
||||
for (let i = 0; i < 256; ++i) {
|
||||
const e = i - 127;
|
||||
if (e < -27) {
|
||||
DataView.__float16_base[i] = 0x0000;
|
||||
DataView.__float16_shift[i] = 24;
|
||||
} else if (e < -14) {
|
||||
DataView.__float16_base[i] = 0x0400 >> -e - 14;
|
||||
DataView.__float16_shift[i] = -e - 1;
|
||||
} else if (e <= 15) {
|
||||
DataView.__float16_base[i] = e + 15 << 10;
|
||||
DataView.__float16_shift[i] = 13;
|
||||
} else if (e < 128) {
|
||||
DataView.__float16_base[i] = 0x7c00;
|
||||
DataView.__float16_shift[i] = 24;
|
||||
} else {
|
||||
DataView.__float16_base[i] = 0x7c00;
|
||||
DataView.__float16_shift[i] = 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DataView.prototype.getBfloat16) {
|
||||
DataView.prototype.getBfloat16 = function (byteOffset, littleEndian) {
|
||||
if (littleEndian) {
|
||||
DataView.__bfloat16_get_uint16_le[1] = this.getUint16(byteOffset, littleEndian);
|
||||
return DataView.__bfloat16_get_float32_le[0];
|
||||
}
|
||||
DataView.__bfloat16_uint16_be[0] = this.getUint16(byteOffset, littleEndian);
|
||||
return DataView.__bfloat16_get_float32_be[0];
|
||||
};
|
||||
DataView.__bfloat16_get_float32_le = new Float32Array(1);
|
||||
DataView.__bfloat16_get_float32_be = new Float32Array(1);
|
||||
DataView.__bfloat16_get_uint16_le = new Uint16Array(DataView.__bfloat16_get_float32_le.buffer, DataView.__bfloat16_get_float32_le.byteOffset, 2);
|
||||
DataView.__bfloat16_get_uint16_be = new Uint16Array(DataView.__bfloat16_get_float32_be.buffer, DataView.__bfloat16_get_float32_be.byteOffset, 2);
|
||||
}
|
||||
|
||||
DataView.__float8e4m3_float32 = new Float32Array(1);
|
||||
DataView.__float8e4m3_uint32 = new Uint32Array(DataView.__float8e4m3_float32.buffer, DataView.__float8e4m3_float32.byteOffset, 1);
|
||||
DataView.prototype.getFloat8e4m3 = function (byteOffset, fn, uz) {
|
||||
const value = this.getUint8(byteOffset);
|
||||
let exponent_bias = 7;
|
||||
if (uz) {
|
||||
exponent_bias = 8;
|
||||
if (value == 0x80) {
|
||||
return NaN;
|
||||
}
|
||||
} else if (value === 255) {
|
||||
return -NaN;
|
||||
} else if (value === 0x7f) {
|
||||
return NaN;
|
||||
}
|
||||
let expo = (value & 0x78) >> 3;
|
||||
let mant = value & 0x07;
|
||||
const sign = value & 0x80;
|
||||
let res = sign << 24;
|
||||
if (expo == 0) {
|
||||
if (mant > 0) {
|
||||
expo = 0x7F - exponent_bias;
|
||||
if (mant & 0x4 == 0) {
|
||||
mant &= 0x3;
|
||||
mant <<= 1;
|
||||
expo -= 1;
|
||||
}
|
||||
if (mant & 0x4 == 0) {
|
||||
mant &= 0x3;
|
||||
mant <<= 1;
|
||||
expo -= 1;
|
||||
}
|
||||
res |= (mant & 0x3) << 21;
|
||||
res |= expo << 23;
|
||||
}
|
||||
} else {
|
||||
res |= mant << 20;
|
||||
expo += 0x7F - exponent_bias;
|
||||
res |= expo << 23;
|
||||
}
|
||||
DataView.__float8e4m3_uint32[0] = res;
|
||||
return DataView.__float8e4m3_float32[0];
|
||||
};
|
||||
|
||||
DataView.__float8e5m2_float32 = new Float32Array(1);
|
||||
DataView.__float8e5m2_uint32 = new Uint32Array(DataView.__float8e5m2_float32.buffer, DataView.__float8e5m2_float32.byteOffset, 1);
|
||||
DataView.prototype.getFloat8e5m2 = function (byteOffset, fn, uz) {
|
||||
const value = this.getUint8(byteOffset);
|
||||
let exponent_bias = NaN;
|
||||
if (fn && uz) {
|
||||
if (value == 0x80) {
|
||||
return NaN;
|
||||
}
|
||||
exponent_bias = 16;
|
||||
} else if (!fn && !uz) {
|
||||
if (value >= 253 && value <= 255) {
|
||||
return -NaN;
|
||||
}
|
||||
if (value >= 126 && value <= 127) {
|
||||
return NaN;
|
||||
}
|
||||
if (value === 252) {
|
||||
return -Infinity;
|
||||
}
|
||||
if (value === 124) {
|
||||
return Infinity;
|
||||
}
|
||||
exponent_bias = 15;
|
||||
}
|
||||
let expo = (value & 0x7C) >> 2;
|
||||
let mant = value & 0x03;
|
||||
let res = (value & 0x80) << 24;
|
||||
if (expo == 0) {
|
||||
if (mant > 0) {
|
||||
expo = 0x7F - exponent_bias;
|
||||
if (mant & 0x2 == 0) {
|
||||
mant &= 0x1;
|
||||
mant <<= 1;
|
||||
expo -= 1;
|
||||
}
|
||||
res |= (mant & 0x1) << 22;
|
||||
res |= expo << 23;
|
||||
}
|
||||
} else {
|
||||
res |= mant << 21;
|
||||
expo += 0x7F - exponent_bias;
|
||||
res |= expo << 23;
|
||||
}
|
||||
DataView.__float8e5m2_uint32[0] = res;
|
||||
return DataView.__float8e5m2_float32[0];
|
||||
};
|
||||
|
||||
DataView.prototype.getInt64 = DataView.prototype.getInt64 || function (byteOffset, littleEndian) {
|
||||
return littleEndian ?
|
||||
new base.Int64(this.getUint32(byteOffset, true), this.getUint32(byteOffset + 4, true)) :
|
||||
new base.Int64(this.getUint32(byteOffset + 4, true), this.getUint32(byteOffset, true));
|
||||
};
|
||||
|
||||
DataView.prototype.setInt64 = DataView.prototype.setInt64 || function (byteOffset, value, littleEndian) {
|
||||
if (littleEndian) {
|
||||
this.setUint32(byteOffset, value.low, true);
|
||||
this.setUint32(byteOffset + 4, value.high, true);
|
||||
} else {
|
||||
this.setUint32(byteOffset + 4, value.low, false);
|
||||
this.setUint32(byteOffset, value.high, false);
|
||||
}
|
||||
};
|
||||
|
||||
DataView.prototype.getIntBits = DataView.prototype.getUintBits || function (offset, bits) {
|
||||
offset = offset * bits;
|
||||
const available = (this.byteLength << 3) - offset;
|
||||
if (bits > available) {
|
||||
throw new RangeError("Invalid bit size '" + bits + "'.");
|
||||
}
|
||||
let value = 0;
|
||||
let index = 0;
|
||||
while (index < bits) {
|
||||
const remainder = offset & 7;
|
||||
const size = Math.min(bits - index, 8 - remainder);
|
||||
value <<= size;
|
||||
value |= (this.getUint8(offset >> 3) >> (8 - size - remainder)) & ~(0xff << size);
|
||||
offset += size;
|
||||
index += size;
|
||||
}
|
||||
return (value < (2 << (bits - 1)) ? value : (2 << bits));
|
||||
};
|
||||
|
||||
DataView.prototype.getUint64 = DataView.prototype.getUint64 || function (byteOffset, littleEndian) {
|
||||
return littleEndian ?
|
||||
new base.Uint64(this.getUint32(byteOffset, true), this.getUint32(byteOffset + 4, true)) :
|
||||
new base.Uint64(this.getUint32(byteOffset + 4, true), this.getUint32(byteOffset, true));
|
||||
};
|
||||
|
||||
DataView.prototype.setUint64 = DataView.prototype.setUint64 || function (byteOffset, value, littleEndian) {
|
||||
if (littleEndian) {
|
||||
this.setUint32(byteOffset, value.low, true);
|
||||
this.setUint32(byteOffset + 4, value.high, true);
|
||||
} else {
|
||||
this.setUint32(byteOffset + 4, value.low, false);
|
||||
this.setUint32(byteOffset, value.high, false);
|
||||
}
|
||||
};
|
||||
|
||||
DataView.prototype.getUintBits = DataView.prototype.getUintBits || function (offset, bits) {
|
||||
offset = offset * bits;
|
||||
const available = (this.byteLength << 3) - offset;
|
||||
if (bits > available) {
|
||||
throw new RangeError("Invalid bit size '" + bits + "'.");
|
||||
}
|
||||
let value = 0;
|
||||
let index = 0;
|
||||
while (index < bits) {
|
||||
const remainder = offset & 7;
|
||||
const size = Math.min(bits - index, 8 - remainder);
|
||||
value <<= size;
|
||||
value |= (this.getUint8(offset >> 3) >> (8 - size - remainder)) & ~(0xff << size);
|
||||
offset += size;
|
||||
index += size;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
DataView.prototype.getComplex64 = DataView.prototype.getComplex64 || function (byteOffset, littleEndian) {
|
||||
const real = littleEndian ? this.getFloat32(byteOffset, littleEndian) : this.getFloat32(byteOffset + 4, littleEndian);
|
||||
const imaginary = littleEndian ? this.getFloat32(byteOffset + 4, littleEndian) : this.getFloat32(byteOffset, littleEndian);
|
||||
return base.Complex64.create(real, imaginary);
|
||||
};
|
||||
|
||||
DataView.prototype.setComplex64 = DataView.prototype.setComplex64 || function (byteOffset, value, littleEndian) {
|
||||
if (littleEndian) {
|
||||
this.setFloat32(byteOffset, value.real, littleEndian);
|
||||
this.setFloat32(byteOffset + 4, value.imaginary, littleEndian);
|
||||
} else {
|
||||
this.setFloat32(byteOffset + 4, value.real, littleEndian);
|
||||
this.setFloat32(byteOffset, value.imaginary, littleEndian);
|
||||
}
|
||||
};
|
||||
|
||||
DataView.prototype.getComplex128 = DataView.prototype.getComplex128 || function (byteOffset, littleEndian) {
|
||||
const real = littleEndian ? this.getFloat64(byteOffset, littleEndian) : this.getFloat64(byteOffset + 8, littleEndian);
|
||||
const imaginary = littleEndian ? this.getFloat64(byteOffset + 8, littleEndian) : this.getFloat64(byteOffset, littleEndian);
|
||||
return base.Complex128.create(real, imaginary);
|
||||
};
|
||||
|
||||
DataView.prototype.setComplex128 = DataView.prototype.setComplex128 || function (byteOffset, value, littleEndian) {
|
||||
if (littleEndian) {
|
||||
this.setFloat64(byteOffset, value.real, littleEndian);
|
||||
this.setFloat64(byteOffset + 8, value.imaginary, littleEndian);
|
||||
} else {
|
||||
this.setFloat64(byteOffset + 8, value.real, littleEndian);
|
||||
this.setFloat64(byteOffset, value.imaginary, littleEndian);
|
||||
}
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,142 @@
|
|||
/* this file is from https://github.com/lutzroeder/netron/blob/main/source/grapher.css */
|
||||
.node path { stroke: #333; fill: none; stroke-width: 1px; }
|
||||
.node line { stroke: #333; fill: none; stroke-width: 1px; }
|
||||
|
||||
.node-item path { stroke-width: 0; stroke: #000; fill: #fff; }
|
||||
.node-item text { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "PingFang SC"; font-size: 11px; text-rendering: geometricPrecision; user-select: none; }
|
||||
|
||||
.node-item-function path { fill: #fff; }
|
||||
.node-item-function text { fill: #000; }
|
||||
.node-item-function:hover { cursor: pointer; }
|
||||
.node-item-function:hover path { fill: #eee; }
|
||||
|
||||
.node-item-type path { fill: #000; }
|
||||
.node-item-type text { fill: #fff; }
|
||||
.node-item-type:hover { cursor: pointer; }
|
||||
.node-item-type:hover path { fill: #fff; }
|
||||
.node-item-type:hover text { fill: #000; }
|
||||
|
||||
.node-item-type-constant path { fill: #eee; }
|
||||
.node-item-type-constant text { fill: #000; }
|
||||
.node-item-type-constant:hover path { fill: #fff; }
|
||||
|
||||
.node-item-type-control path { fill: #eee; }
|
||||
.node-item-type-control text { fill: #000; }
|
||||
.node-item-type-control:hover path { fill: #fff; }
|
||||
|
||||
.node-item-type-layer path { fill: rgb(51, 85, 136); }
|
||||
.node-item-type-wrapper path { fill: rgb(238, 238, 238); }
|
||||
.node-item-type-wrapper text { fill: rgb(0, 0, 0) }
|
||||
.node-item-type-activation path { fill: rgb(112, 41, 33); }
|
||||
.node-item-type-pool path { fill: rgb(51, 85, 51); }
|
||||
.node-item-type-normalization path { fill: rgb(51, 85, 68); }
|
||||
.node-item-type-dropout path { fill: rgb(69, 71, 112); }
|
||||
.node-item-type-shape path { fill: rgb(108, 79, 71); }
|
||||
.node-item-type-tensor path { fill: rgb(89, 66, 59); }
|
||||
.node-item-type-transform path { fill: rgb(51, 85, 68); }
|
||||
.node-item-type-data path { fill: rgb(85, 85, 85); }
|
||||
.node-item-type-quantization path { fill: rgb(80, 40, 0); }
|
||||
.node-item-type-custom path { fill: rgb(128, 128, 128); }
|
||||
|
||||
.node-item-input path { fill: #fff; }
|
||||
.node-item-input:hover { cursor: pointer; }
|
||||
.node-item-input:hover path { fill: #fff; }
|
||||
|
||||
.node-item-constant path { fill: #eee; }
|
||||
.node-item-constant:hover { cursor: pointer; }
|
||||
.node-item-constant:hover path { fill: #fff; }
|
||||
|
||||
.node-item-undefined path { fill: #f00; }
|
||||
.node-item-undefined:hover { cursor: pointer; }
|
||||
.node-item-undefined:hover path { fill: #fff; }
|
||||
|
||||
.node-attribute-list > path { fill: #fff; stroke-width: 0; stroke: #000; }
|
||||
.node-attribute-list:hover { cursor: pointer; }
|
||||
.node-attribute-list:hover > path { fill: #f6f6f6; }
|
||||
.node-attribute > text { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "PingFang SC"; font-size: 9px; font-weight: normal; text-rendering: geometricPrecision; user-select: none; }
|
||||
|
||||
.graph-item-input path { fill: #eee; }
|
||||
.graph-item-input:hover { cursor: pointer; }
|
||||
.graph-item-input:hover path { fill: #fff; }
|
||||
|
||||
.graph-item-output path { fill: #eee; }
|
||||
.graph-item-output:hover { cursor: pointer; }
|
||||
.graph-item-output:hover path { fill: #fff; }
|
||||
|
||||
#arrowhead { fill: #000; }
|
||||
#arrowhead-select { fill: #e00; }
|
||||
|
||||
.edge-path { stroke: #000; stroke-width: 1px; fill: none; marker-end: url("#arrowhead"); }
|
||||
.edge-path-hit-test { pointer-events: stroke; stroke-width: 0.5em; fill: none; stroke: #000; stroke-opacity: 0.001; }
|
||||
|
||||
.select > .node.node-border { stroke: #e00; stroke-width: 2px; }
|
||||
.select.edge-path { stroke: #e00; stroke-width: 1px; marker-end: url("#arrowhead-select"); }
|
||||
|
||||
.edge-label { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif, "PingFang SC"; font-size: 10px; }
|
||||
.edge-path-control-dependency { stroke-dasharray: 3, 2; }
|
||||
|
||||
.cluster rect { stroke: #000; fill: #000; fill-opacity: 0.02; stroke-opacity: 0.06; stroke-width: 1px; }
|
||||
|
||||
@keyframes pulse { from { stroke-dashoffset: 100px; } to { stroke-dashoffset: 0; } }
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.edge-path { stroke: #888; }
|
||||
|
||||
.node path { stroke: #1d1d1d; }
|
||||
.node line { stroke: #1d1d1d; }
|
||||
|
||||
.select > .node.node-border { stroke: #b00; }
|
||||
.select.edge-path { stroke: #b00; }
|
||||
|
||||
#arrowhead { fill: #888; }
|
||||
#arrowhead-hover { fill: #b00; }
|
||||
#arrowhead-select { fill: #b00 }
|
||||
|
||||
.edge-label { fill: #b2b2b2; }
|
||||
|
||||
.node-item-function path { fill: #404040; }
|
||||
.node-item-function text { fill: #dfdfdfdf; }
|
||||
.node-item-function:hover { cursor: pointer; }
|
||||
.node-item-function:hover path { fill: #666666; }
|
||||
|
||||
.node-item-type path { fill: #303030; }
|
||||
.node-item-type text { fill: #dfdfdf; }
|
||||
.node-item-type:hover { cursor: pointer; }
|
||||
.node-item-type:hover path { fill: #808080; }
|
||||
.node-item-type:hover text { fill: #dfdfdf; }
|
||||
|
||||
.node-item path { stroke: #fff; }
|
||||
.node-item text { fill: #dfdfdf; }
|
||||
|
||||
.node-attribute > text { fill: #b2b2b2; }
|
||||
.node-attribute-list > path { fill: #2d2d2d; }
|
||||
.node-attribute-list:hover > path { fill: #666666; }
|
||||
|
||||
.graph-item-input path { fill: #404040; }
|
||||
.graph-item-input:hover { cursor: pointer; }
|
||||
.graph-item-input:hover path { fill: #666666; }
|
||||
|
||||
.graph-item-output path { fill: #404040; }
|
||||
.graph-item-output:hover { cursor: pointer; }
|
||||
.graph-item-output:hover path { fill: #666666; }
|
||||
|
||||
.node-item-input path { fill: #404040; }
|
||||
.node-item-input:hover path { fill: #666666; }
|
||||
.node-item-constant path { fill: #4b4b4b; }
|
||||
.node-item-constant:hover path { fill: #666666; }
|
||||
|
||||
.node-item-type-layer path { fill: rgba(51, 85, 136, 0.7); }
|
||||
.node-item-type-activation path { fill: rgba(75, 27, 22, 0.7); }
|
||||
.node-item-type-activation path { fill: rgba(75, 27, 22, 0.7); }
|
||||
.node-item-type-pool path { fill: rgba(51, 85, 51, 0.7); }
|
||||
.node-item-type-pool path { fill: rgba(51, 85, 51, 0.7); }
|
||||
.node-item-type-normalization path { fill: rgba(51, 85, 68, 0.7); }
|
||||
.node-item-type-dropout path { fill: rgba(69, 71, 112, 0.7); }
|
||||
.node-item-type-shape path { fill: rgba(108, 79, 71, 0.7); }
|
||||
.node-item-type-tensor path { fill: rgba(89, 66, 59, 0.7); }
|
||||
.node-item-type-transform path { fill: rgba(51, 85, 68, 0.7); }
|
||||
.node-item-type-data path { fill: rgba(85, 85, 85, 0.7); }
|
||||
.node-item-type-quantization path { fill: rgb(80, 40, 0, 0.7); }
|
||||
.node-item-type-custom path { fill: rgb(64, 64, 64, 0.7); }
|
||||
}
|
|
@ -0,0 +1,885 @@
|
|||
// this file is from https://github.com/lutzroeder/netron/blob/main/source/grapher.js
|
||||
var grapher = grapher || {};
|
||||
var dagre = window.dagre;
|
||||
|
||||
grapher.Graph = class {
|
||||
|
||||
constructor(compound, layout) {
|
||||
this._layout = layout;
|
||||
this._isCompound = compound;
|
||||
this._nodes = new Map();
|
||||
this._edges = new Map();
|
||||
this._children = {};
|
||||
this._children['\x00'] = {};
|
||||
this._parent = {};
|
||||
}
|
||||
|
||||
setNode(node) {
|
||||
const key = node.name;
|
||||
const value = this._nodes.get(key);
|
||||
if (value) {
|
||||
value.label = node;
|
||||
} else {
|
||||
this._nodes.set(key, { v: key, label: node });
|
||||
if (this._isCompound) {
|
||||
this._parent[key] = '\x00';
|
||||
this._children[key] = {};
|
||||
this._children['\x00'][key] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setEdge(edge) {
|
||||
if (!this._nodes.has(edge.v)) {
|
||||
throw new grapher.Error("Invalid edge '" + JSON.stringify(edge.v) + "'.");
|
||||
}
|
||||
if (!this._nodes.has(edge.w)) {
|
||||
throw new grapher.Error("Invalid edge '" + JSON.stringify(edge.w) + "'.");
|
||||
}
|
||||
const key = edge.v + ':' + edge.w;
|
||||
if (!this._edges.has(key)) {
|
||||
this._edges.set(key, { v: edge.v, w: edge.w, label: edge });
|
||||
}
|
||||
}
|
||||
|
||||
setParent(node, parent) {
|
||||
if (!this._isCompound) {
|
||||
throw new Error("Cannot set parent in a non-compound graph");
|
||||
}
|
||||
parent += "";
|
||||
for (let ancestor = parent; ancestor; ancestor = this.parent(ancestor)) {
|
||||
if (ancestor === node) {
|
||||
throw new Error("Setting " + parent + " as parent of " + node + " would create a cycle");
|
||||
}
|
||||
}
|
||||
delete this._children[this._parent[node]][node];
|
||||
this._parent[node] = parent;
|
||||
this._children[parent][node] = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
get nodes() {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
hasNode(key) {
|
||||
return this._nodes.has(key);
|
||||
}
|
||||
|
||||
node(key) {
|
||||
return this._nodes.get(key);
|
||||
}
|
||||
|
||||
get edges() {
|
||||
return this._edges;
|
||||
}
|
||||
|
||||
parent(key) {
|
||||
if (this._isCompound) {
|
||||
const parent = this._parent[key];
|
||||
if (parent !== '\x00') {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
children(key) {
|
||||
key = key === undefined ? '\x00' : key;
|
||||
if (this._isCompound) {
|
||||
const children = this._children[key];
|
||||
if (children) {
|
||||
return Object.keys(children);
|
||||
}
|
||||
} else if (key === '\x00') {
|
||||
return this.nodes.keys();
|
||||
} else if (this.hasNode(key)) {
|
||||
return [];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
build(document, origin) {
|
||||
const createGroup = (name) => {
|
||||
const element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
element.setAttribute('id', name);
|
||||
element.setAttribute('class', name);
|
||||
origin.appendChild(element);
|
||||
return element;
|
||||
};
|
||||
|
||||
const clusterGroup = createGroup('clusters');
|
||||
const edgePathGroup = createGroup('edge-paths');
|
||||
const edgeLabelGroup = createGroup('edge-labels');
|
||||
const nodeGroup = createGroup('nodes');
|
||||
|
||||
const edgePathGroupDefs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
||||
edgePathGroup.appendChild(edgePathGroupDefs);
|
||||
const marker = (id) => {
|
||||
const element = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
|
||||
element.setAttribute('id', id);
|
||||
element.setAttribute('viewBox', '0 0 10 10');
|
||||
element.setAttribute('refX', 9);
|
||||
element.setAttribute('refY', 5);
|
||||
element.setAttribute('markerUnits', 'strokeWidth');
|
||||
element.setAttribute('markerWidth', 8);
|
||||
element.setAttribute('markerHeight', 6);
|
||||
element.setAttribute('orient', 'auto');
|
||||
const markerPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
markerPath.setAttribute('d', 'M 0 0 L 10 5 L 0 10 L 4 5 z');
|
||||
markerPath.style.setProperty('stroke-width', 1);
|
||||
element.appendChild(markerPath);
|
||||
return element;
|
||||
};
|
||||
edgePathGroupDefs.appendChild(marker("arrowhead"));
|
||||
edgePathGroupDefs.appendChild(marker("arrowhead-select"));
|
||||
edgePathGroupDefs.appendChild(marker("arrowhead-hover"));
|
||||
for (const nodeId of this.nodes.keys()) {
|
||||
const entry = this.node(nodeId);
|
||||
const node = entry.label;
|
||||
if (this.children(nodeId).length == 0) {
|
||||
node.build(document, nodeGroup);
|
||||
} else {
|
||||
// cluster
|
||||
node.rectangle = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
if (node.rx) {
|
||||
node.rectangle.setAttribute('rx', entry.rx);
|
||||
}
|
||||
if (node.ry) {
|
||||
node.rectangle.setAttribute('ry', entry.ry);
|
||||
}
|
||||
node.element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
node.element.setAttribute('class', 'cluster');
|
||||
node.element.appendChild(node.rectangle);
|
||||
clusterGroup.appendChild(node.element);
|
||||
}
|
||||
}
|
||||
|
||||
for (const edge of this.edges.values()) {
|
||||
edge.label.build(document, edgePathGroup, edgeLabelGroup);
|
||||
}
|
||||
}
|
||||
|
||||
measure() {
|
||||
for (const key of this.nodes.keys()) {
|
||||
const entry = this.node(key);
|
||||
if (this.children(key).length == 0) {
|
||||
const node = entry.label;
|
||||
node.measure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layout() {
|
||||
dagre.layout(this, this._layout);
|
||||
for (const key of this.nodes.keys()) {
|
||||
const entry = this.node(key);
|
||||
if (this.children(key).length == 0) {
|
||||
const node = entry.label;
|
||||
node.layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
for (const nodeId of this.nodes.keys()) {
|
||||
if (this.children(nodeId).length == 0) {
|
||||
// node
|
||||
const entry = this.node(nodeId);
|
||||
const node = entry.label;
|
||||
node.update();
|
||||
} else {
|
||||
// cluster
|
||||
const entry = this.node(nodeId);
|
||||
const node = entry.label;
|
||||
node.element.setAttribute('transform', 'translate(' + node.x + ',' + node.y + ')');
|
||||
node.rectangle.setAttribute('x', - node.width / 2);
|
||||
node.rectangle.setAttribute('y', - node.height / 2);
|
||||
node.rectangle.setAttribute('width', node.width);
|
||||
node.rectangle.setAttribute('height', node.height);
|
||||
}
|
||||
}
|
||||
for (const edge of this.edges.values()) {
|
||||
edge.label.update();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Node = class {
|
||||
|
||||
constructor() {
|
||||
this._blocks = [];
|
||||
}
|
||||
|
||||
header() {
|
||||
const block = new grapher.Node.Header();
|
||||
this._blocks.push(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
list() {
|
||||
const block = new grapher.Node.List();
|
||||
this._blocks.push(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
canvas() {
|
||||
const block = new grapher.Node.Canvas();
|
||||
this._blocks.push(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
build(document, parent) {
|
||||
this.element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
if (this.id) {
|
||||
this.element.setAttribute('id', this.id);
|
||||
}
|
||||
this.element.setAttribute('class', this.class ? 'node ' + this.class : 'node');
|
||||
this.element.style.opacity = 0;
|
||||
parent.appendChild(this.element);
|
||||
this.border = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
this.border.setAttribute('class', 'node node-border');
|
||||
for (let i = 0; i < this._blocks.length; i++) {
|
||||
const block = this._blocks[i];
|
||||
block.first = i === 0;
|
||||
block.last = i === this._blocks.length - 1;
|
||||
block.build(document, this.element);
|
||||
}
|
||||
this.element.appendChild(this.border);
|
||||
}
|
||||
|
||||
measure() {
|
||||
this.height = 0;
|
||||
for (const block of this._blocks) {
|
||||
block.measure();
|
||||
this.height = this.height + block.height;
|
||||
}
|
||||
this.width = Math.max(...this._blocks.map((block) => block.width));
|
||||
for (const block of this._blocks) {
|
||||
block.width = this.width;
|
||||
}
|
||||
}
|
||||
|
||||
layout() {
|
||||
let y = 0;
|
||||
for (const block of this._blocks) {
|
||||
block.x = 0;
|
||||
block.y = y;
|
||||
block.width = this.width;
|
||||
block.layout();
|
||||
y += block.height;
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
for (const block of this._blocks) {
|
||||
block.update();
|
||||
}
|
||||
this.border.setAttribute('d', grapher.Node.roundedRect(0, 0, this.width, this.height, true, true, true, true));
|
||||
this.element.setAttribute('transform', 'translate(' + (this.x - (this.width / 2)) + ',' + (this.y - (this.height / 2)) + ')');
|
||||
this.element.style.removeProperty('opacity');
|
||||
}
|
||||
|
||||
select() {
|
||||
if (this.element) {
|
||||
this.element.classList.add('select');
|
||||
return [ this.element ];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
deselect() {
|
||||
if (this.element) {
|
||||
this.element.classList.remove('select');
|
||||
}
|
||||
}
|
||||
|
||||
static roundedRect(x, y, width, height, r1, r2, r3, r4) {
|
||||
const radius = 5;
|
||||
r1 = r1 ? radius : 0;
|
||||
r2 = r2 ? radius : 0;
|
||||
r3 = r3 ? radius : 0;
|
||||
r4 = r4 ? radius : 0;
|
||||
return "M" + (x + r1) + "," + y +
|
||||
"h" + (width - r1 - r2) +
|
||||
"a" + r2 + "," + r2 + " 0 0 1 " + r2 + "," + r2 +
|
||||
"v" + (height - r2 - r3) +
|
||||
"a" + r3 + "," + r3 + " 0 0 1 " + -r3 + "," + r3 +
|
||||
"h" + (r3 + r4 - width) +
|
||||
"a" + r4 + "," + r4 + " 0 0 1 " + -r4 + "," + -r4 +
|
||||
'v' + (-height + r4 + r1) +
|
||||
"a" + r1 + "," + r1 + " 0 0 1 " + r1 + "," + -r1 +
|
||||
"z";
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Node.Header = class {
|
||||
|
||||
constructor() {
|
||||
this._entries = [];
|
||||
}
|
||||
|
||||
add(id, classList, content, tooltip, handler) {
|
||||
const entry = new grapher.Node.Header.Entry(id, classList, content, tooltip, handler);
|
||||
this._entries.push(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
build(document, parent) {
|
||||
this._document = document;
|
||||
for (const entry of this._entries) {
|
||||
entry.build(document, parent);
|
||||
}
|
||||
if (!this.first) {
|
||||
this.line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
parent.appendChild(this.line);
|
||||
}
|
||||
for (let i = 0; i < this._entries.length; i++) {
|
||||
const entry = this._entries[i];
|
||||
if (i != 0) {
|
||||
entry.line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
parent.appendChild(entry.line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
measure() {
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
for (const entry of this._entries) {
|
||||
entry.measure();
|
||||
this.height = Math.max(this.height, entry.height);
|
||||
this.width += entry.width;
|
||||
}
|
||||
}
|
||||
|
||||
layout() {
|
||||
let x = this.width;
|
||||
for (let i = this._entries.length - 1; i >= 0; i--) {
|
||||
const entry = this._entries[i];
|
||||
if (i > 0) {
|
||||
x -= entry.width;
|
||||
entry.x = x;
|
||||
} else {
|
||||
entry.x = 0;
|
||||
entry.width = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
for (let i = 0; i < this._entries.length; i++) {
|
||||
const entry = this._entries[i];
|
||||
entry.element.setAttribute('transform', 'translate(' + entry.x + ',' + this.y + ')');
|
||||
const r1 = i == 0 && this.first;
|
||||
const r2 = i == this._entries.length - 1 && this.first;
|
||||
const r3 = i == this._entries.length - 1 && this.last;
|
||||
const r4 = i == 0 && this.last;
|
||||
entry.path.setAttribute('d', grapher.Node.roundedRect(0, 0, entry.width, entry.height, r1, r2, r3, r4));
|
||||
entry.text.setAttribute('x', 6);
|
||||
entry.text.setAttribute('y', entry.ty);
|
||||
}
|
||||
for (let i = 1; i < this._entries.length; i++) {
|
||||
const entry = this._entries[i];
|
||||
const line = entry.line;
|
||||
line.setAttribute('class', 'node');
|
||||
line.setAttribute('x1', entry.x);
|
||||
line.setAttribute('x2', entry.x);
|
||||
line.setAttribute('y1', this.y);
|
||||
line.setAttribute('y2', this.y + this.height);
|
||||
}
|
||||
if (this.line) {
|
||||
this.line.setAttribute('class', 'node');
|
||||
this.line.setAttribute('x1', 0);
|
||||
this.line.setAttribute('x2', this.width);
|
||||
this.line.setAttribute('y1', this.y);
|
||||
this.line.setAttribute('y2', this.y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Node.Header.Entry = class {
|
||||
|
||||
constructor(id, classList, content, tooltip, handler) {
|
||||
this.id = id;
|
||||
this.classList = classList;
|
||||
this.content = content;
|
||||
this.tooltip = tooltip;
|
||||
this.handler = handler;
|
||||
this._events = {};
|
||||
}
|
||||
|
||||
on(event, callback) {
|
||||
this._events[event] = this._events[event] || [];
|
||||
this._events[event].push(callback);
|
||||
}
|
||||
|
||||
emit(event, data) {
|
||||
if (this._events && this._events[event]) {
|
||||
for (const callback of this._events[event]) {
|
||||
callback(this, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build(document, parent) {
|
||||
this.element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
parent.appendChild(this.element);
|
||||
this.path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
this.text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
this.element.appendChild(this.path);
|
||||
this.element.appendChild(this.text);
|
||||
const classList = [ 'node-item' ];
|
||||
if (this.classList) {
|
||||
classList.push(...this.classList);
|
||||
}
|
||||
this.element.setAttribute('class', classList.join(' '));
|
||||
if (this.id) {
|
||||
this.element.setAttribute('id', this.id);
|
||||
}
|
||||
if (this._events.click) {
|
||||
this.element.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
this.emit('click');
|
||||
});
|
||||
}
|
||||
if (this.tooltip) {
|
||||
const title = document.createElementNS('http://www.w3.org/2000/svg', 'title');
|
||||
title.textContent = this.tooltip;
|
||||
this.element.appendChild(title);
|
||||
}
|
||||
this.text.textContent = this.content || '\u00A0';
|
||||
}
|
||||
|
||||
measure() {
|
||||
const yPadding = 4;
|
||||
const xPadding = 7;
|
||||
const boundingBox = this.text.getBBox();
|
||||
this.width = boundingBox.width + xPadding + xPadding;
|
||||
this.height = boundingBox.height + yPadding + yPadding;
|
||||
this.tx = xPadding;
|
||||
this.ty = yPadding - boundingBox.y;
|
||||
}
|
||||
|
||||
layout() {
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Node.List = class {
|
||||
|
||||
constructor() {
|
||||
this._items = [];
|
||||
this._events = {};
|
||||
}
|
||||
|
||||
add(name, value, tooltip, separator) {
|
||||
const item = new grapher.Node.List.Item(name, value, tooltip, separator);
|
||||
this._items.push(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
on(event, callback) {
|
||||
this._events[event] = this._events[event] || [];
|
||||
this._events[event].push(callback);
|
||||
}
|
||||
|
||||
emit(event, data) {
|
||||
if (this._events && this._events[event]) {
|
||||
for (const callback of this._events[event]) {
|
||||
callback(this, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build(document, parent) {
|
||||
this._document = document;
|
||||
this.element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
this.element.setAttribute('class', 'node-attribute-list');
|
||||
if (this._events.click) {
|
||||
this.element.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
this.emit('click');
|
||||
});
|
||||
}
|
||||
this.background = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
this.element.appendChild(this.background);
|
||||
parent.appendChild(this.element);
|
||||
for (const item of this._items) {
|
||||
const group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
group.setAttribute('class', 'node-attribute');
|
||||
const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||
text.setAttribute('xml:space', 'preserve');
|
||||
if (item.tooltip) {
|
||||
const title = document.createElementNS('http://www.w3.org/2000/svg', 'title');
|
||||
title.textContent = item.tooltip;
|
||||
text.appendChild(title);
|
||||
}
|
||||
const colon = item.type === 'node' || item.type === 'node[]';
|
||||
const name = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
name.textContent = colon ? item.name + ':' : item.name;
|
||||
if (item.separator.trim() !== '=' && !colon) {
|
||||
name.style.fontWeight = 'bold';
|
||||
}
|
||||
text.appendChild(name);
|
||||
group.appendChild(text);
|
||||
this.element.appendChild(group);
|
||||
item.group = group;
|
||||
item.text = text;
|
||||
if (item.type === 'node') {
|
||||
const node = item.value;
|
||||
node.build(document, item.group);
|
||||
} else if (item.type === 'node[]') {
|
||||
for (const node of item.value) {
|
||||
node.build(document, item.group);
|
||||
}
|
||||
} else {
|
||||
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||
tspan.textContent = item.separator + item.value;
|
||||
item.text.appendChild(tspan);
|
||||
}
|
||||
}
|
||||
if (!this.first) {
|
||||
this.line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
|
||||
this.line.setAttribute('class', 'node');
|
||||
this.element.appendChild(this.line);
|
||||
}
|
||||
}
|
||||
|
||||
measure() {
|
||||
this.width = 75;
|
||||
this.height = 3;
|
||||
const yPadding = 1;
|
||||
const xPadding = 6;
|
||||
for (let i = 0; i < this._items.length; i++) {
|
||||
const item = this._items[i];
|
||||
const size = item.text.getBBox();
|
||||
item.width = xPadding + size.width + xPadding;
|
||||
item.height = yPadding + size.height + yPadding;
|
||||
item.offset = size.y;
|
||||
this.height += item.height;
|
||||
if (item.type === 'node') {
|
||||
const node = item.value;
|
||||
node.measure();
|
||||
this.width = Math.max(150, this.width, node.width + (2 * xPadding));
|
||||
this.height += node.height + yPadding + yPadding + yPadding + yPadding;
|
||||
if (i === this._items.length - 1) {
|
||||
this.height += 3;
|
||||
}
|
||||
} else if (item.type === 'node[]') {
|
||||
for (const node of item.value) {
|
||||
node.measure();
|
||||
this.width = Math.max(150, this.width, node.width + (2 * xPadding));
|
||||
this.height += node.height + yPadding + yPadding + yPadding + yPadding;
|
||||
}
|
||||
if (i === this._items.length - 1) {
|
||||
this.height += 3;
|
||||
}
|
||||
}
|
||||
this.width = Math.max(this.width, item.width);
|
||||
}
|
||||
this.height += 3;
|
||||
}
|
||||
|
||||
layout() {
|
||||
const yPadding = 1;
|
||||
const xPadding = 6;
|
||||
let y = 3;
|
||||
for (const item of this._items) {
|
||||
item.x = this.x + xPadding;
|
||||
item.y = y + yPadding - item.offset;
|
||||
y += item.height;
|
||||
if (item.type === 'node') {
|
||||
const node = item.value;
|
||||
node.width = this.width - xPadding - xPadding;
|
||||
node.layout();
|
||||
node.x = this.x + xPadding + (node.width / 2);
|
||||
node.y = y + (node.height / 2) + yPadding + yPadding;
|
||||
y += node.height + yPadding + yPadding + yPadding + yPadding;
|
||||
} else if (item.type === 'node[]') {
|
||||
for (const node of item.value) {
|
||||
node.width = this.width - xPadding - xPadding;
|
||||
node.layout();
|
||||
node.x = this.x + xPadding + (node.width / 2);
|
||||
node.y = y + (node.height / 2) + yPadding + yPadding;
|
||||
y += node.height + yPadding + yPadding + yPadding + yPadding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
this.element.setAttribute('transform', 'translate(' + this.x + ',' + this.y + ')');
|
||||
this.background.setAttribute('d', grapher.Node.roundedRect(0, 0, this.width, this.height, this.first, this.first, this.last, this.last));
|
||||
for (const item of this._items) {
|
||||
const text = item.text;
|
||||
text.setAttribute('x', item.x);
|
||||
text.setAttribute('y', item.y);
|
||||
if (item.type === 'node') {
|
||||
const node = item.value;
|
||||
node.update();
|
||||
} else if (item.type === 'node[]') {
|
||||
for (const node of item.value) {
|
||||
node.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.line) {
|
||||
this.line.setAttribute('x1', 0);
|
||||
this.line.setAttribute('x2', this.width);
|
||||
this.line.setAttribute('y1', 0);
|
||||
this.line.setAttribute('y2', 0);
|
||||
}
|
||||
for (const item of this._items) {
|
||||
if (item.value instanceof grapher.Node) {
|
||||
const node = item.value;
|
||||
node.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Node.List.Item = class {
|
||||
|
||||
constructor(name, value, tooltip, separator) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.tooltip = tooltip;
|
||||
this.separator = separator;
|
||||
if (value instanceof grapher.Node) {
|
||||
this.type = 'node';
|
||||
} else if (Array.isArray(value) && value.every((value) => value instanceof grapher.Node)) {
|
||||
this.type = 'node[]';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Node.Canvas = class {
|
||||
|
||||
constructor() {
|
||||
this.width = 0;
|
||||
this.height = 80;
|
||||
}
|
||||
|
||||
build(/* document, parent */) {
|
||||
}
|
||||
|
||||
update(/* parent, top, width , first, last */) {
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Edge = class {
|
||||
|
||||
constructor(from, to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
build(document, edgePathGroupElement, edgeLabelGroupElement) {
|
||||
const createElement = (name) => {
|
||||
return document.createElementNS('http://www.w3.org/2000/svg', name);
|
||||
};
|
||||
this.element = createElement('path');
|
||||
if (this.id) {
|
||||
this.element.setAttribute('id', this.id);
|
||||
}
|
||||
this.element.setAttribute('class', this.class ? 'edge-path ' + this.class : 'edge-path');
|
||||
edgePathGroupElement.appendChild(this.element);
|
||||
this.hitTest = createElement('path');
|
||||
this.hitTest.setAttribute('class', 'edge-path-hit-test');
|
||||
this.hitTest.addEventListener('pointerover', () => this.emit('pointerover'));
|
||||
this.hitTest.addEventListener('pointerleave', () => this.emit('pointerleave'));
|
||||
this.hitTest.addEventListener('click', () => this.emit('click'));
|
||||
edgePathGroupElement.appendChild(this.hitTest);
|
||||
if (this.label) {
|
||||
const tspan = createElement('tspan');
|
||||
tspan.setAttribute('xml:space', 'preserve');
|
||||
tspan.setAttribute('dy', '1em');
|
||||
tspan.setAttribute('x', '1');
|
||||
tspan.appendChild(document.createTextNode(this.label));
|
||||
this.labelElement = createElement('text');
|
||||
this.labelElement.appendChild(tspan);
|
||||
this.labelElement.style.opacity = 0;
|
||||
this.labelElement.setAttribute('class', 'edge-label');
|
||||
if (this.id) {
|
||||
this.labelElement.setAttribute('id', 'edge-label-' + this.id);
|
||||
}
|
||||
edgeLabelGroupElement.appendChild(this.labelElement);
|
||||
const edgeBox = this.labelElement.getBBox();
|
||||
this.width = edgeBox.width;
|
||||
this.height = edgeBox.height;
|
||||
}
|
||||
}
|
||||
|
||||
update() {
|
||||
const intersectRect = (node, point) => {
|
||||
const x = node.x;
|
||||
const y = node.y;
|
||||
const dx = point.x - x;
|
||||
const dy = point.y - y;
|
||||
let h = node.height / 2;
|
||||
let w = node.width / 2;
|
||||
if (Math.abs(dy) * w > Math.abs(dx) * h) {
|
||||
if (dy < 0) {
|
||||
h = -h;
|
||||
}
|
||||
return { x: x + (dy === 0 ? 0 : h * dx / dy), y: y + h };
|
||||
}
|
||||
if (dx < 0) {
|
||||
w = -w;
|
||||
}
|
||||
return { x: x + w, y: y + (dx === 0 ? 0 : w * dy / dx) };
|
||||
};
|
||||
const curvePath = (edge, tail, head) => {
|
||||
const points = edge.points.slice(1, edge.points.length - 1);
|
||||
points.unshift(intersectRect(tail, points[0]));
|
||||
points.push(intersectRect(head, points[points.length - 1]));
|
||||
return new grapher.Edge.Curve(points).path.data;
|
||||
};
|
||||
const edgePath = curvePath(this, this.from, this.to);
|
||||
this.element.setAttribute('d', edgePath);
|
||||
this.hitTest.setAttribute('d', edgePath);
|
||||
if (this.labelElement) {
|
||||
this.labelElement.setAttribute('transform', 'translate(' + (this.x - (this.width / 2)) + ',' + (this.y - (this.height / 2)) + ')');
|
||||
this.labelElement.style.opacity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
select() {
|
||||
if (this.element) {
|
||||
if (!this.element.classList.contains('select')) {
|
||||
const path = this.element;
|
||||
path.classList.add('select');
|
||||
this.element = path.cloneNode(true);
|
||||
path.parentNode.replaceChild(this.element, path);
|
||||
}
|
||||
return [ this.element ];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
deselect() {
|
||||
if (this.element && this.element.classList.contains('select')) {
|
||||
const path = this.element;
|
||||
path.classList.remove('select');
|
||||
this.element = path.cloneNode(true);
|
||||
path.parentNode.replaceChild(this.element, path);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Edge.Curve = class {
|
||||
|
||||
constructor(points) {
|
||||
this._path = new grapher.Edge.Path();
|
||||
this._x0 = NaN;
|
||||
this._x1 = NaN;
|
||||
this._y0 = NaN;
|
||||
this._y1 = NaN;
|
||||
this._state = 0;
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const point = points[i];
|
||||
this.point(point.x, point.y);
|
||||
if (i === points.length - 1) {
|
||||
switch (this._state) {
|
||||
case 3:
|
||||
this.curve(this._x1, this._y1);
|
||||
this._path.lineTo(this._x1, this._y1);
|
||||
break;
|
||||
case 2:
|
||||
this._path.lineTo(this._x1, this._y1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (this._line || (this._line !== 0 && this._point === 1)) {
|
||||
this._path.closePath();
|
||||
}
|
||||
this._line = 1 - this._line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get path() {
|
||||
return this._path;
|
||||
}
|
||||
|
||||
point(x, y) {
|
||||
x = +x;
|
||||
y = +y;
|
||||
switch (this._state) {
|
||||
case 0:
|
||||
this._state = 1;
|
||||
if (this._line) {
|
||||
this._path.lineTo(x, y);
|
||||
} else {
|
||||
this._path.moveTo(x, y);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this._state = 2;
|
||||
break;
|
||||
case 2:
|
||||
this._state = 3;
|
||||
this._path.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6);
|
||||
this.curve(x, y);
|
||||
break;
|
||||
default:
|
||||
this.curve(x, y);
|
||||
break;
|
||||
}
|
||||
this._x0 = this._x1;
|
||||
this._x1 = x;
|
||||
this._y0 = this._y1;
|
||||
this._y1 = y;
|
||||
}
|
||||
|
||||
curve(x, y) {
|
||||
this._path.bezierCurveTo(
|
||||
(2 * this._x0 + this._x1) / 3,
|
||||
(2 * this._y0 + this._y1) / 3,
|
||||
(this._x0 + 2 * this._x1) / 3,
|
||||
(this._y0 + 2 * this._y1) / 3,
|
||||
(this._x0 + 4 * this._x1 + x) / 6,
|
||||
(this._y0 + 4 * this._y1 + y) / 6
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
grapher.Edge.Path = class {
|
||||
|
||||
constructor() {
|
||||
this._x0 = null;
|
||||
this._y0 = null;
|
||||
this._x1 = null;
|
||||
this._y1 = null;
|
||||
this._data = '';
|
||||
}
|
||||
|
||||
moveTo(x, y) {
|
||||
this._data += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
|
||||
}
|
||||
|
||||
lineTo(x, y) {
|
||||
this._data += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
|
||||
}
|
||||
|
||||
bezierCurveTo(x1, y1, x2, y2, x, y) {
|
||||
this._data += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
|
||||
}
|
||||
|
||||
closePath() {
|
||||
if (this._x1 !== null) {
|
||||
this._x1 = this._x0;
|
||||
this._y1 = this._y0;
|
||||
this._data += "Z";
|
||||
}
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this._data;
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof window !== 'undefined' && typeof window === 'object') {
|
||||
window.grapher = grapher;
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
|
||||
var host = host || {};
|
||||
|
||||
host.BrowserHost = class {
|
||||
|
||||
constructor(vscode) {
|
||||
this._vscode = vscode;
|
||||
this._window = window;
|
||||
this._document = window.document;
|
||||
|
||||
this._environment = {
|
||||
name: this._document.title,
|
||||
menu: true
|
||||
};
|
||||
}
|
||||
|
||||
get window() {
|
||||
return this._window;
|
||||
}
|
||||
|
||||
get document() {
|
||||
return this._document;
|
||||
}
|
||||
|
||||
async view(view) {
|
||||
this._view = view;
|
||||
}
|
||||
|
||||
async start() {
|
||||
this.document.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
this.document.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
this.document.body.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
this._view.show('welcome');
|
||||
}
|
||||
|
||||
environment(name) {
|
||||
return this._environment[name];
|
||||
}
|
||||
|
||||
error(message, detail) {
|
||||
this._vscode.postMessage({ type: 'error', message: detail });
|
||||
}
|
||||
|
||||
/**
|
||||
* save numpy tensor
|
||||
* @param {*} name
|
||||
* @param {*} extension
|
||||
* @param {*} defaultPath
|
||||
* @param {*} callback
|
||||
*/
|
||||
save(name, extension, defaultPath, callback) {
|
||||
callback(defaultPath + '.' + extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* export png and svg images
|
||||
* @param {string} file the file name
|
||||
* @param {Blob} blob data blob
|
||||
*/
|
||||
export(file, blob) {
|
||||
// const element = this.document.createElement('a');
|
||||
// element.download = file;
|
||||
// element.href = URL.createObjectURL(blob);
|
||||
// this.document.body.appendChild(element);
|
||||
// element.click();
|
||||
// this.document.body.removeChild(element);
|
||||
|
||||
blob.arrayBuffer().then((arrayBuf)=>{
|
||||
let data = new Uint8Array(arrayBuf);
|
||||
this._vscode.postMessage({ type: 'export', fileName: file, data: data });
|
||||
})
|
||||
}
|
||||
|
||||
exception(error, fatal) {
|
||||
//send telemetry, do nothing
|
||||
}
|
||||
|
||||
event(name, params) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
_element(id) {
|
||||
return this.document.getElementById(id);
|
||||
}
|
||||
};
|
||||
|
||||
if (!('scrollBehavior' in window.document.documentElement.style)) {
|
||||
const __scrollTo__ = Element.prototype.scrollTo;
|
||||
Element.prototype.scrollTo = function(options) {
|
||||
if (options !== undefined) {
|
||||
if (options === null || typeof options !== 'object' || options.behavior === undefined || arguments[0].behavior === 'auto' || options.behavior === 'instant') {
|
||||
if (__scrollTo__) {
|
||||
__scrollTo__.apply(this, arguments);
|
||||
}
|
||||
} else {
|
||||
const now = () => window.performance && window.performance.now ? window.performance.now() : Date.now();
|
||||
const ease = (k) => 0.5 * (1 - Math.cos(Math.PI * k));
|
||||
const step = (context) => {
|
||||
const value = ease(Math.min((now() - context.startTime) / 468, 1));
|
||||
const x = context.startX + (context.x - context.startX) * value;
|
||||
const y = context.startY + (context.y - context.startY) * value;
|
||||
context.element.scrollLeft = x;
|
||||
context.element.scrollTop = y;
|
||||
if (x !== context.x || y !== context.y) {
|
||||
window.requestAnimationFrame(step.bind(window, context));
|
||||
}
|
||||
};
|
||||
const context = {
|
||||
element: this,
|
||||
x: typeof options.left === 'undefined' ? this.scrollLeft : ~~options.left,
|
||||
y: typeof options.top === 'undefined' ? this.scrollTop : ~~options.top,
|
||||
startX: this.scrollLeft,
|
||||
startY: this.scrollTop,
|
||||
startTime: now()
|
||||
};
|
||||
step(context);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined' && typeof window === 'object') {
|
||||
window.host = host;
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined' && typeof module.exports === 'object') {
|
||||
module.exports = host;
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
// This script is run within the webview itself
|
||||
(function () {
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
//the onnx proto model
|
||||
let onnxProtoModel = null;
|
||||
//the onnx proto graphs
|
||||
let onnxProtoGraphs = null;
|
||||
//the onnx model name
|
||||
let onnxModelName = '';
|
||||
//the tensor external data map. key: location, value: Uint8Array
|
||||
let externalTensorMap = new Map();
|
||||
//the tensor external locations
|
||||
let externalTensorLocations = [];
|
||||
|
||||
// Handle messages from the extension
|
||||
window.addEventListener('message', e => {
|
||||
const { type, body } = e.data;
|
||||
switch (type) {
|
||||
case 'init':
|
||||
{
|
||||
//the onnx file content, Uint8Array
|
||||
let onnxValue = body.modelData;
|
||||
//the onnx file name
|
||||
onnxModelName = body.modelName;
|
||||
|
||||
onnxProtoModel = window.proto.onnx.ModelProto.decode(onnxValue);
|
||||
let { locations, graphs } = window.getExternalLocations(onnxProtoModel);
|
||||
|
||||
//refer to https://github.com/onnx/onnx/blob/main/docs/ExternalData.md
|
||||
if (locations.length > 0) {
|
||||
onnxProtoGraphs = graphs;
|
||||
externalTensorMap.clear();
|
||||
externalTensorLocations = locations;
|
||||
//load tensor external data
|
||||
vscode.postMessage({ type: 'external_tensor', external_locations: locations });
|
||||
} else {
|
||||
let model = new window.onnx.Model(onnxProtoModel, graphs, new Map());
|
||||
|
||||
let host = new window.host.BrowserHost(vscode);
|
||||
let view = new window.View(host);
|
||||
view.start().then((data) => {
|
||||
view.open(model, onnxModelName);
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'external_tensor': {
|
||||
//the external tensor data, Uint8Array
|
||||
let tensorData = body.tensorData;
|
||||
let loc = body.location;
|
||||
|
||||
externalTensorMap.set(loc, tensorData);
|
||||
if (externalTensorMap.size == externalTensorLocations.length) {
|
||||
let model = new window.onnx.Model(onnxProtoModel, onnxProtoGraphs, externalTensorMap);
|
||||
|
||||
let host = new window.host.BrowserHost(vscode);
|
||||
let view = new window.View(host);
|
||||
view.start().then((data) => {
|
||||
view.open(model, onnxModelName);
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Signal to VS Code that the webview is initialized.
|
||||
vscode.postMessage({ type: 'ready' });
|
||||
}());
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -50,10 +50,10 @@ class MenuAPI {
|
|||
],
|
||||
},
|
||||
{
|
||||
path: "/internetProtocol",
|
||||
path: "/flow",
|
||||
component: "Layout",
|
||||
redirect: "/internetProtocol/index",
|
||||
name: "/internetProtocol",
|
||||
redirect: "/flow/demo",
|
||||
name: "/flow",
|
||||
meta: {
|
||||
title: "互联协议",
|
||||
icon: "web",
|
||||
|
@ -63,9 +63,9 @@ class MenuAPI {
|
|||
},
|
||||
children: [
|
||||
{
|
||||
path: "user",
|
||||
component: "system/user/index",
|
||||
name: "User",
|
||||
path: "demo",
|
||||
component: "flow/demo/index",
|
||||
name: "demo",
|
||||
meta: {
|
||||
title: "互联协议1",
|
||||
icon: "user",
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
|
||||
|
||||
class FlowLinkModel extends PolylineEdgeModel {
|
||||
getEdgeStyle() {
|
||||
const style = super.getEdgeStyle();
|
||||
style.strokeWidth = 1;
|
||||
style.stroke = this.isSelected ? '#ff7f0e' : '#999';
|
||||
return style;
|
||||
}
|
||||
}
|
||||
class FlowLink extends PolylineEdge {}
|
||||
|
||||
export default {
|
||||
type: 'ai-link',
|
||||
view: FlowLink,
|
||||
model: FlowLinkModel
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import BaseNode from './nodes/BaseNode.js'
|
||||
import FlowLink from './FlowLink.js'
|
||||
class NodeRedExtension{
|
||||
static pluginName = 'NodeAiExtension'
|
||||
constructor ({ lf }) {
|
||||
lf.register(BaseNode)
|
||||
lf.register(FlowLink)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default NodeRedExtension
|
|
@ -0,0 +1,11 @@
|
|||
import "@logicflow/extension/lib/style/index.css";
|
||||
|
||||
export default function(lf) {
|
||||
const menuConfig = {
|
||||
|
||||
};
|
||||
|
||||
lf.extension.menu.menuTypeMap.get("lf:defaultNodeMenu").splice(1,2)
|
||||
lf.extension.menu.menuTypeMap.get("lf:defaultEdgeMenu").splice(1,1)
|
||||
lf.extension.menu.addMenuConfig(menuConfig);
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
import { RectNode, RectNodeModel, h } from "@logicflow/core"
|
||||
import { getBytesLength } from '../util'
|
||||
|
||||
|
||||
class RedNodeModel extends RectNodeModel {
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
initNodeData(data) {
|
||||
super.initNodeData(data)
|
||||
this.width = 200;
|
||||
this.height = 30;
|
||||
this.radius = 5;
|
||||
this.text.x = this.x + 10;
|
||||
this.defaultFill = data.fill||'rgb(253, 208, 162)'
|
||||
}
|
||||
getData () {
|
||||
const data = super.getData()
|
||||
data.properties.ui = 'node-ai'
|
||||
return data
|
||||
}
|
||||
|
||||
updateText(val) {
|
||||
super.updateText(val)
|
||||
this.setAttributes();
|
||||
}
|
||||
/**
|
||||
* 重写节点样式
|
||||
*/
|
||||
getNodeStyle() {
|
||||
const style = super.getNodeStyle();
|
||||
const dataStyle = this.properties.style || {};
|
||||
if (this.isSelected) {
|
||||
style.strokeWidth = Number(dataStyle.borderWidth) || 2;
|
||||
style.stroke = dataStyle.borderColor || '#ff7f0e';
|
||||
} else {
|
||||
style.strokeWidth = Number(dataStyle.borderWidth) || 1;
|
||||
style.stroke = dataStyle.borderColor || '#999';
|
||||
}
|
||||
style.fill = dataStyle.backgroundColor || this.defaultFill;
|
||||
return style;
|
||||
}
|
||||
/**
|
||||
* 重写定义锚点
|
||||
*/
|
||||
getDefaultAnchor() {
|
||||
const { x, y, id, width, height } = this;
|
||||
const anchors = [
|
||||
{
|
||||
x: x ,
|
||||
y: y+ height / 2,
|
||||
id: `${id}_right`,
|
||||
type: "right"
|
||||
},
|
||||
{
|
||||
x: x ,
|
||||
y: y- height / 2,
|
||||
id: `${id}_left`,
|
||||
type: "left"
|
||||
}
|
||||
];
|
||||
return anchors;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getOutlineStyle() {
|
||||
const style = super.getOutlineStyle();
|
||||
style.stroke = 'transparent';
|
||||
style.hover.stroke = 'transparent';
|
||||
return style;
|
||||
}
|
||||
handleContextMenu(ev){
|
||||
debugger
|
||||
}
|
||||
}
|
||||
class RedNode extends RectNode {
|
||||
|
||||
/**
|
||||
* 1.1.7版本后支持在view中重写锚点形状。
|
||||
* 重写锚点新增
|
||||
*/
|
||||
getAnchorShape(anchorData) {
|
||||
const { x, y, type } = anchorData;
|
||||
return h("rect", {
|
||||
x: x - 5,
|
||||
y: y - 5,
|
||||
width: 10,
|
||||
height: 10,
|
||||
className: 'custom-anchor'
|
||||
});
|
||||
}
|
||||
getShape() {
|
||||
const {
|
||||
text,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
radius
|
||||
} = this.props.model;
|
||||
const style = this.props.model.getNodeStyle()
|
||||
return h(
|
||||
'g',
|
||||
{
|
||||
className: 'lf-ai-node'
|
||||
},
|
||||
[
|
||||
h('rect', {
|
||||
...style,
|
||||
x: x - width / 2,
|
||||
y: y - height / 2,
|
||||
width,
|
||||
height,
|
||||
rx: radius,
|
||||
ry: radius
|
||||
})
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
type: 'ai-node',
|
||||
model: RedNodeModel,
|
||||
view: RedNode
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* 求字符串的字节长度 */
|
||||
export const getBytesLength = (word) => {
|
||||
if (!word) {
|
||||
return 0;
|
||||
}
|
||||
let totalLength = 0;
|
||||
for (let i = 0; i < word.length; i++) {
|
||||
const c = word.charCodeAt(i);
|
||||
if ((word.match(/[A-Z]/))) {
|
||||
totalLength += 1.5;
|
||||
} else if ((c >= 0x0001 && c <= 0x007e) || (c >= 0xff60 && c <= 0xff9f)) {
|
||||
totalLength += 1;
|
||||
} else {
|
||||
totalLength += 1.8;
|
||||
}
|
||||
}
|
||||
return totalLength;
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<section class="app-main">
|
||||
<el-scrollbar max-height="calc(100vh - 76px)">
|
||||
<el-scrollbar height="calc(100vh - 76px)">
|
||||
<router-view>
|
||||
<template #default="{ Component, route }">
|
||||
<transition
|
||||
|
@ -29,6 +29,9 @@ const cachedViews = computed(() => useTagsViewStore().cachedViews); // 缓存页
|
|||
width: 100%;
|
||||
min-height: calc(100vh - 100px);
|
||||
overflow: hidden;
|
||||
:deep(.el-scrollbar__view){
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.hasTagsView .app-main {
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
<template>
|
||||
<div class="flow-demo1">
|
||||
<el-row :gutter="20" style="height: 100%;">
|
||||
<el-col :span="4">
|
||||
<NodePanel :lf="lf" ref="nodePanel"/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card class="flow-card">
|
||||
<div ref="flow" class="viewport" id="flowMain" @click="hideProp"/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-card v-if="showProp" :key="nodePropKey">
|
||||
<template #header>节点属性</template>
|
||||
<div>
|
||||
节点ID:{{nodeData.properties.node }}
|
||||
</div>
|
||||
<div>
|
||||
节点名称:{{nodeData.text.value }}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import LogicFlow from '@logicflow/core';
|
||||
// 引入整体背景的样式
|
||||
import '@logicflow/core/dist/style/index.css';
|
||||
import { Menu } from "@logicflow/extension";
|
||||
import AiNodeExtension from '@/components/flow/index'
|
||||
import RegisteMenu from '@/components/flow/menu.js'
|
||||
import NodePanel from './nodePanel.vue'
|
||||
const themeApprove = {
|
||||
rect: { // 矩形样式
|
||||
radius: 8,
|
||||
stroke: '#3CB371'
|
||||
},
|
||||
circle: {
|
||||
r: 25,
|
||||
stroke: '#FF6347'
|
||||
},
|
||||
polygon: {
|
||||
stroke: '#6495ED',
|
||||
},
|
||||
polyline: {
|
||||
strokeWidth: 1,
|
||||
stroke: '#3CB371'
|
||||
},
|
||||
edgeText: {
|
||||
background: {
|
||||
fill: 'white',
|
||||
},
|
||||
},
|
||||
}
|
||||
let showProp=ref(false)
|
||||
let nodeData=reactive(null)
|
||||
const nodePanel=ref()
|
||||
const config = {
|
||||
stopScrollGraph: true,
|
||||
stopZoomGraph: true,
|
||||
grid: {
|
||||
size: 10,
|
||||
visible: true,
|
||||
type: 'mesh',
|
||||
config: {
|
||||
color: '#DCDCDC',
|
||||
}
|
||||
},
|
||||
keyboard: { enabled: true },
|
||||
style: themeApprove,
|
||||
plugins: [AiNodeExtension,Menu]
|
||||
};
|
||||
const flow = ref()
|
||||
let lf = ref(null)
|
||||
let nodePropKey=ref(1)
|
||||
const hideProp=(e)=>{
|
||||
if(e.target.classList.contains("lf-drag-able")){
|
||||
showProp.value=false
|
||||
}
|
||||
}
|
||||
const initEvent=(lf)=>{
|
||||
lf.on("element:click",node=>{
|
||||
nodeData=node.data
|
||||
showProp.value=true
|
||||
nodePropKey.value++
|
||||
console.log("-->",nodeData)
|
||||
});
|
||||
lf.on("node:dnd-add",data=>{
|
||||
nodeData=data.data;
|
||||
showProp.value=true
|
||||
nodePropKey.value++
|
||||
doUpdateState()
|
||||
});
|
||||
lf.on("node:delete",data=>{
|
||||
if(data.data.text.value=="目标绘图"){
|
||||
ElMessage.error("目标绘图节点不能删除");
|
||||
setTimeout(() => {
|
||||
lf.undo();
|
||||
}, 400);
|
||||
return;
|
||||
}
|
||||
doUpdateState()
|
||||
});
|
||||
lf.on("node:contextmenu",(d,e,p)=>{
|
||||
if(d.data.text.value=="目标绘图"){
|
||||
setTimeout(()=>{
|
||||
document.querySelector(".lf-menu").style.display="none";
|
||||
},0)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const doUpdateState=()=>{
|
||||
nodePanel.value.updateNode(lf.value.getGraphData());
|
||||
}
|
||||
onMounted(() => {
|
||||
const logicFlow = new LogicFlow({
|
||||
...config,
|
||||
container: flow.value
|
||||
})
|
||||
lf.value = logicFlow
|
||||
RegisteMenu(logicFlow)
|
||||
initEvent(logicFlow);
|
||||
window.lf=lf
|
||||
logicFlow.render({
|
||||
nodes: [
|
||||
{
|
||||
id: 'node_1',
|
||||
type: 'ai-node',
|
||||
x: 150,
|
||||
y: 20,
|
||||
fill:'#409effaa',
|
||||
text: '图像缩放',
|
||||
properties:{
|
||||
node:201
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'node_2',
|
||||
type: 'ai-node',
|
||||
x: 150,
|
||||
y: 80,
|
||||
fill:'#50e904',
|
||||
text: '目标绘图',
|
||||
properties:{
|
||||
node:900
|
||||
}
|
||||
}
|
||||
],
|
||||
edges: [
|
||||
|
||||
]
|
||||
})
|
||||
doUpdateState();
|
||||
});
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.flow-demo1 {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.viewport {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.custom-anchor {
|
||||
stroke: #999;
|
||||
stroke-width: 1;
|
||||
fill: #d9d9d9;
|
||||
cursor: crosshair;
|
||||
rx: 3;
|
||||
ry: 3;
|
||||
}
|
||||
|
||||
.custom-anchor:hover {
|
||||
fill: #ff7f0e;
|
||||
stroke: #ff7f0e;
|
||||
}
|
||||
.flow-card{
|
||||
height: 80%;
|
||||
.el-card__body{
|
||||
height:100%;
|
||||
padding:4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,87 @@
|
|||
<template>
|
||||
<div class="node-panel">
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="前处理算子">
|
||||
<div v-for="(it1, idx1) in list1" :key="idx1" class="div-item" @mousedown="dragNode(it1, 1)" v-show="it1.show">
|
||||
{{ it1.text }}
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="后处理算子">
|
||||
<div v-for="(it2, idx2) in list2" :key="idx2" class="div-item item2" @mousedown="dragNode(it2, 2)" v-show="it2.show">
|
||||
{{ it2.text }}
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
lf: {
|
||||
type: Object,
|
||||
require: true,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
const dragNode = (it, t) => {
|
||||
props.lf.dnd.startDrag({
|
||||
type: 'ai-node',
|
||||
text: it.text,
|
||||
fill: t == 1 ? '#409effaa' : '#ccccccaa',
|
||||
properties:{
|
||||
node:it.id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const list1 = reactive([
|
||||
{ text: "图像缩放", id: 201,show:true },
|
||||
{ text: "RGB12图像格式转换", id: 202,show:true },
|
||||
{ text: "RGB24图像格式转换", id: 203,show:true },
|
||||
{ text: "RGB36图像格式转换", id: 204,show:true },
|
||||
{ text: "RGB48图像格式转换", id: 205,show:true },
|
||||
{ text: "RGB72图像格式转换", id: 206,show:true }
|
||||
])
|
||||
|
||||
const list2 = reactive([
|
||||
{ text: "VIT推理算子1", id: 301,show:true },
|
||||
{ text: "VIT推理算子2", id: 301,show:true },
|
||||
{ text: "VIT后处理算子1", id: 301,show:true },
|
||||
{ text: "VIT后处理算子2", id: 301,show:true },
|
||||
{ text: "VIT后处理算子3", id: 301,show:true },
|
||||
]);
|
||||
|
||||
const updateNode=(nodes)=>{
|
||||
let nds=nodes.nodes.map(d=>d.properties.node);
|
||||
list2.forEach(d=>{
|
||||
d.show=nds.indexOf(d.id)==-1
|
||||
})
|
||||
list1.forEach(d=>{
|
||||
d.show=nds.indexOf(d.id)==-1
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
updateNode
|
||||
})
|
||||
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.node-panel {
|
||||
.div-item {
|
||||
font-size: 12px;
|
||||
border: solid 1px #888;
|
||||
margin-bottom: 10px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
background: #409effaa;
|
||||
user-select: none;
|
||||
cursor: move;
|
||||
|
||||
&.item2 {
|
||||
background: #ccccccaa;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -5,16 +5,21 @@
|
|||
</div>
|
||||
<div style="text-align: center;">
|
||||
建设中。。。。。
|
||||
</div>
|
||||
</div>
|
||||
<iframe :src="url" style="width:100%;height:100%;position: absolute;top:0px;"></iframe>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts' setup>
|
||||
<script setup>
|
||||
let url=ref("")
|
||||
onMounted(()=>{
|
||||
url.value="./onnx/onnx.html?url=/ai/siamRPN_192.onnx"
|
||||
});
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
.split-split1-index{
|
||||
position: relative;
|
||||
padding: 12px 24px;
|
||||
|
||||
height:100%;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue