mirror of
https://github.com/enso-org/enso.git
synced 2024-12-19 15:12:26 +03:00
Style manager (https://github.com/enso-org/ide/pull/382)
Original commit: 03bac5867a
This commit is contained in:
parent
e1973c3ae9
commit
23cb61d611
@ -7,14 +7,14 @@ class Logo {
|
||||
this.size = 64
|
||||
this.compatibleMode = compatibleMode
|
||||
this.borderMax = 10
|
||||
this.borderSpread = 0
|
||||
this.borderSpread = 2
|
||||
this.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
var scaleStop = 128
|
||||
var scaleLog = Math.log2(scaleStop)
|
||||
this.borderWidth = 6
|
||||
this.borderWidth = 7
|
||||
this.topRadius = 32
|
||||
this.borderOffset = this.borderWidth - this.borderSpread
|
||||
this.innerRadius = this.topRadius - this.borderWidth - this.borderOffset
|
||||
@ -84,24 +84,26 @@ class Logo {
|
||||
${this.defs}
|
||||
|
||||
</defs>
|
||||
<g transform="scale(${this.scale})"> <use ${this.ref}="#final"/> </g>
|
||||
${this.main()}
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
|
||||
main() {
|
||||
return `<g transform="scale(${this.scale})"> <use ${this.ref}="#final"/> </g>`
|
||||
}
|
||||
}
|
||||
|
||||
class MinimalWhiteLogo extends Logo {
|
||||
class AppLogo extends Logo {
|
||||
constructor(size, compatibleMode) {
|
||||
super(size, compatibleMode)
|
||||
this.borderMax = 10
|
||||
this.borderSpread = 0
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
|
||||
fastGenerate = (cons) => (...args) => new cons(...args).generate()
|
||||
|
||||
exports.generateMinimalWhiteLogo = fastGenerate(MinimalWhiteLogo)
|
||||
exports.generateMinimalWhiteLogo = fastGenerate(AppLogo)
|
||||
|
||||
|
||||
const fss = require('fs')
|
||||
|
549
gui/src/js/package-lock.json
generated
549
gui/src/js/package-lock.json
generated
@ -10,12 +10,12 @@
|
||||
"integrity": "sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA=="
|
||||
},
|
||||
"@develar/schema-utils": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.1.0.tgz",
|
||||
"integrity": "sha512-qjCqB4ctMig9Gz5bd6lkdFr3bO6arOdQqptdBSpF1ZpCnjofieCciEzkoS9ujY9cMGyllYSCSmBJ3x9OKHXzoA==",
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
|
||||
"integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==",
|
||||
"requires": {
|
||||
"ajv": "^6.1.0",
|
||||
"ajv-keywords": "^3.1.0"
|
||||
"ajv": "^6.12.0",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"@electron/get": {
|
||||
@ -1046,12 +1046,12 @@
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.0.tgz",
|
||||
"integrity": "sha512-3nx+MEYoZeD0uJ+7F/gvELLvQJzLXhep2Az0bBSXagbApDvDW0LWwpnAIY/hb0Jwe17A0fJdz0O12dPh05cj7A==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz",
|
||||
"integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/types": "^2.0.0",
|
||||
"@octokit/types": "^2.11.1",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"universal-user-agent": "^5.0.0"
|
||||
},
|
||||
@ -1114,14 +1114,14 @@
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.0.tgz",
|
||||
"integrity": "sha512-uAJO6GI8z8VHBqtY7VTL9iFy1Y+UTp5ShpI97tY5z0qBfYKE9rZCRsCm23VmF00x+IoNJ7a0nuVITs/+wS9/mg==",
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz",
|
||||
"integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.0",
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.0.0",
|
||||
"@octokit/types": "^2.8.2",
|
||||
"@octokit/types": "^2.11.1",
|
||||
"deprecation": "^2.0.0",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"node-fetch": "^2.3.0",
|
||||
@ -1202,9 +1202,9 @@
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.9.0.tgz",
|
||||
"integrity": "sha512-IzptUpoDsFlXF+AOys+KnfItIVY3EK+eH9Akv+lJYELnMSGkJnIcClt6Cm0QRR4ecsUTsmFJWn10iFgJ9BQqIQ==",
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.12.1.tgz",
|
||||
"integrity": "sha512-LRLR1tjbcCfAmUElvTmMvLEzstpx6Xt/aQVTg2xvd+kHA2Ekp1eWl5t+gU7bcwjXHYEAzh4hH4WH+kS3vh+wRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": ">= 8"
|
||||
@ -1283,178 +1283,177 @@
|
||||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
"integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
|
||||
"integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5"
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/wast-parser": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/floating-point-hex-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-api-error": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
|
||||
"integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
|
||||
"integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-buffer": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
|
||||
"integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
|
||||
"integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-code-frame": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
|
||||
"integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
|
||||
"integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
"@webassemblyjs/wast-printer": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-fsm": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
|
||||
"integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
|
||||
"integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-module-context": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
|
||||
"integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
|
||||
"integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"mamacro": "^0.0.3"
|
||||
"@webassemblyjs/ast": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-bytecode": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
|
||||
"integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
|
||||
"integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
|
||||
"integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
|
||||
"integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ieee754": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
|
||||
"integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
|
||||
"integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xtuc/ieee754": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/leb128": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
|
||||
"integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
|
||||
"integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/utf8": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
|
||||
"integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
|
||||
"integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/wasm-edit": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
|
||||
"integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
|
||||
"integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-section": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-opt": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-section": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0",
|
||||
"@webassemblyjs/wasm-opt": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"@webassemblyjs/wast-printer": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-gen": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
|
||||
"integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
|
||||
"integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/ieee754": "1.9.0",
|
||||
"@webassemblyjs/leb128": "1.9.0",
|
||||
"@webassemblyjs/utf8": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-opt": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
|
||||
"integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
|
||||
"integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-api-error": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/ieee754": "1.9.0",
|
||||
"@webassemblyjs/leb128": "1.9.0",
|
||||
"@webassemblyjs/utf8": "1.9.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-parser": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-code-frame": "1.8.5",
|
||||
"@webassemblyjs/helper-fsm": "1.8.5",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.9.0",
|
||||
"@webassemblyjs/helper-api-error": "1.9.0",
|
||||
"@webassemblyjs/helper-code-frame": "1.9.0",
|
||||
"@webassemblyjs/helper-fsm": "1.9.0",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-printer": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
|
||||
"integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
|
||||
"integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/wast-parser": "1.9.0",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
@ -1670,34 +1669,34 @@
|
||||
}
|
||||
},
|
||||
"app-builder-bin": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.5.tgz",
|
||||
"integrity": "sha512-ZcHzJ9Xl+azPqdKzXZKdRZmkNmbxHHZyl4cbobNf8qMQpoPChpcov8riVrZSbu/0cT/JqJ8LOwJjy1OAwbChaQ=="
|
||||
"version": "3.5.6",
|
||||
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.6.tgz",
|
||||
"integrity": "sha512-gY9ABoV5jh67IrPEwF81R8l9LwE3RqHUyU3rIKitwqMpKhplN5OZC6WEHOXO3XhwiLCIlr9LLI6OPhr3bmtQIg=="
|
||||
},
|
||||
"app-builder-lib": {
|
||||
"version": "22.4.1",
|
||||
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.4.1.tgz",
|
||||
"integrity": "sha512-epwUzIM+2pcdy/If9koTP74CKx4v7xGPj75a2Z5cM4rrGN9yVZ3eDUBbfF0e0qE4Qmcv5pd0BAZJ26bGm8NWsQ==",
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.5.1.tgz",
|
||||
"integrity": "sha512-VtB/PD8actR1317D/0uGzuJIYbpw4pRrfMB6IyTLwGynUd3ihqiCFjejVWHjCwopgCct2kE0MvLwo8P49xHIeQ==",
|
||||
"requires": {
|
||||
"7zip-bin": "~5.0.3",
|
||||
"@develar/schema-utils": "~2.1.0",
|
||||
"@develar/schema-utils": "~2.6.5",
|
||||
"async-exit-hook": "^2.0.1",
|
||||
"bluebird-lst": "^1.0.9",
|
||||
"builder-util": "22.4.1",
|
||||
"builder-util-runtime": "8.6.2",
|
||||
"builder-util": "22.5.1",
|
||||
"builder-util-runtime": "8.7.0",
|
||||
"chromium-pickle-js": "^0.2.0",
|
||||
"debug": "^4.1.1",
|
||||
"ejs": "^3.0.1",
|
||||
"electron-publish": "22.4.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"ejs": "^3.0.2",
|
||||
"electron-publish": "22.5.1",
|
||||
"fs-extra": "^9.0.0",
|
||||
"hosted-git-info": "^3.0.4",
|
||||
"is-ci": "^2.0.0",
|
||||
"isbinaryfile": "^4.0.4",
|
||||
"isbinaryfile": "^4.0.5",
|
||||
"js-yaml": "^3.13.1",
|
||||
"lazy-val": "^1.0.4",
|
||||
"minimatch": "^3.0.4",
|
||||
"normalize-package-data": "^2.5.0",
|
||||
"read-config-file": "5.0.2",
|
||||
"read-config-file": "6.0.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"semver": "^7.1.3",
|
||||
"temp-file": "^3.3.7"
|
||||
@ -1711,6 +1710,17 @@
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
|
||||
"integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz",
|
||||
@ -1719,10 +1729,24 @@
|
||||
"lru-cache": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
|
||||
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1908,6 +1932,11 @@
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
@ -2430,19 +2459,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"builder-util": {
|
||||
"version": "22.4.1",
|
||||
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.4.1.tgz",
|
||||
"integrity": "sha512-+ysLc7cC4w6P7rBxmZ5X2aU3QvcwFoWCl1us+mcUKdsGmJAtFUMPJqueeptdxjyPrPShIUOKHzA8uk5A3d1fHg==",
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.5.1.tgz",
|
||||
"integrity": "sha512-CelDTP3+fvDfZfbwy3PXif7mudPaWankJ8vrRg/NtCGvL+hXnwycnJZr46d5EQL7AgQcpJ27o9LTdfu61cxTFw==",
|
||||
"requires": {
|
||||
"7zip-bin": "~5.0.3",
|
||||
"@types/debug": "^4.1.5",
|
||||
"@types/fs-extra": "^8.1.0",
|
||||
"app-builder-bin": "3.5.5",
|
||||
"app-builder-bin": "3.5.6",
|
||||
"bluebird-lst": "^1.0.9",
|
||||
"builder-util-runtime": "8.6.2",
|
||||
"builder-util-runtime": "8.7.0",
|
||||
"chalk": "^3.0.0",
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"is-ci": "^2.0.0",
|
||||
"js-yaml": "^3.13.1",
|
||||
"source-map-support": "^0.5.16",
|
||||
@ -2489,11 +2518,31 @@
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
|
||||
"integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
|
||||
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
@ -2501,13 +2550,18 @@
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"builder-util-runtime": {
|
||||
"version": "8.6.2",
|
||||
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.6.2.tgz",
|
||||
"integrity": "sha512-9QnIBISfhgQ2BxtRLidVqf/v5HD73vSKZDllpUmGd2L6VORGQk7cZAPmPtw4HQM3gPBelyVJ5yIjMNZ8xjmd1A==",
|
||||
"version": "8.7.0",
|
||||
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.0.tgz",
|
||||
"integrity": "sha512-G1AqqVM2vYTrSFR982c1NNzwXKrGLQjVjaZaWQdn4O6Z3YKjdMDofw88aD9jpyK9ZXkrCxR0tI3Qe9wNbyTlXg==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"sax": "^1.2.4"
|
||||
@ -3114,9 +3168,9 @@
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
|
||||
"integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==",
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.6.tgz",
|
||||
"integrity": "sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA==",
|
||||
"requires": {
|
||||
"ajv": "^6.12.0",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
@ -3190,9 +3244,9 @@
|
||||
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
|
||||
"integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"requires": {
|
||||
"semver": "^6.0.0"
|
||||
}
|
||||
@ -4005,19 +4059,29 @@
|
||||
}
|
||||
},
|
||||
"dmg-builder": {
|
||||
"version": "22.4.1",
|
||||
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.4.1.tgz",
|
||||
"integrity": "sha512-hEemh7n0zoVt7zPPwvn7iOttP03oENjJ4ApttPmt8oDnX8T4q42MjGWyDlLkPMplMJfoTxkkNqmm296f0OYM8Q==",
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.5.1.tgz",
|
||||
"integrity": "sha512-AwIiyGwgqhA8Ty/YnEU20aSzfrWZns6suOBTqddD+rLDI4jEASKGQadfvcXRSWgaK/VQW0GrhheXrhJpzZzt3g==",
|
||||
"requires": {
|
||||
"app-builder-lib": "~22.4.1",
|
||||
"bluebird-lst": "^1.0.9",
|
||||
"builder-util": "~22.4.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"app-builder-lib": "22.5.1",
|
||||
"builder-util": "22.5.1",
|
||||
"fs-extra": "^9.0.0",
|
||||
"iconv-lite": "^0.5.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"sanitize-filename": "^1.6.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
|
||||
"integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz",
|
||||
@ -4025,6 +4089,20 @@
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
|
||||
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4136,31 +4214,31 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "12.12.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.35.tgz",
|
||||
"integrity": "sha512-ASYsaKecA7TUsDrqIGPNk3JeEox0z/0XR/WsJJ8BIX/9+SkMSImQXKWfU/yBrSyc7ZSE/NPqLu36Nur0miCFfQ=="
|
||||
"version": "12.12.37",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.37.tgz",
|
||||
"integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"electron-builder": {
|
||||
"version": "22.4.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.4.1.tgz",
|
||||
"integrity": "sha512-13CjZcGeJS+c3EKRwFT/Oty5Niif5g1FwDioBLEbjkPCPQgxdtDsr+rJtCu9qxkiKDYpAoPS+t/clNk0efONvQ==",
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.5.1.tgz",
|
||||
"integrity": "sha512-7gnHN8Ml5zecDerN8/ljAwUKtE+hhGLuT/X2/zO0FJM2q2hlLx/6ZgzESFILKqnPQFEBRxQ8SL1OxjdIY0HIrw==",
|
||||
"requires": {
|
||||
"@types/yargs": "^15.0.4",
|
||||
"app-builder-lib": "22.4.1",
|
||||
"app-builder-lib": "22.5.1",
|
||||
"bluebird-lst": "^1.0.9",
|
||||
"builder-util": "22.4.1",
|
||||
"builder-util-runtime": "8.6.2",
|
||||
"builder-util": "22.5.1",
|
||||
"builder-util-runtime": "8.7.0",
|
||||
"chalk": "^3.0.0",
|
||||
"dmg-builder": "22.4.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"dmg-builder": "22.5.1",
|
||||
"fs-extra": "^9.0.0",
|
||||
"is-ci": "^2.0.0",
|
||||
"lazy-val": "^1.0.4",
|
||||
"read-config-file": "5.0.2",
|
||||
"read-config-file": "6.0.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"update-notifier": "^4.1.0",
|
||||
"yargs": "^15.1.0"
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
@ -4194,11 +4272,31 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
|
||||
"integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
|
||||
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
@ -4206,6 +4304,11 @@
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4215,16 +4318,16 @@
|
||||
"integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw=="
|
||||
},
|
||||
"electron-publish": {
|
||||
"version": "22.4.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.4.1.tgz",
|
||||
"integrity": "sha512-nwKNum3KXm+01rtWX2pc1jhazdzDy2zYnQx+zmXphZchjd6UOMX3ZN0xyZUCKugw5ZliflT6LkgbrcBXBtYD3A==",
|
||||
"version": "22.5.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.5.1.tgz",
|
||||
"integrity": "sha512-g5bwLAHZT6A++yU1+Et+fncnFAdXXgkRao9rzTFAvhQ0QJBsmLiyOd0Ta2RI/EQcVoy6jyHtxFs7CWIXE5aZOA==",
|
||||
"requires": {
|
||||
"@types/fs-extra": "^8.1.0",
|
||||
"bluebird-lst": "^1.0.9",
|
||||
"builder-util": "~22.4.1",
|
||||
"builder-util-runtime": "8.6.2",
|
||||
"builder-util": "22.5.1",
|
||||
"builder-util-runtime": "8.7.0",
|
||||
"chalk": "^3.0.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"lazy-val": "^1.0.4",
|
||||
"mime": "^2.4.4"
|
||||
},
|
||||
@ -4260,11 +4363,31 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
|
||||
"integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==",
|
||||
"requires": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
|
||||
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
||||
@ -4277,6 +4400,11 @@
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
|
||||
"integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4988,9 +5116,9 @@
|
||||
}
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
|
||||
"integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"requires": {
|
||||
"semver": "^6.0.0"
|
||||
}
|
||||
@ -6903,9 +7031,9 @@
|
||||
}
|
||||
},
|
||||
"is-function": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
|
||||
"integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
|
||||
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.1",
|
||||
@ -7506,12 +7634,6 @@
|
||||
"ssri": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"mamacro": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
|
||||
"integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==",
|
||||
"dev": true
|
||||
},
|
||||
"map-age-cleaner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
@ -7887,9 +8009,9 @@
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
|
||||
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
@ -8024,9 +8146,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz",
|
||||
"integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==",
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz",
|
||||
"integrity": "sha512-+sa0XNlWDA6T+bDLmkCUYn6W5k5W6BPRL6mqzSCs6H/xUgtl4D5x2fORKDzopKiU6wsyn/+wXlRXwXeSp+mtoA==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
},
|
||||
@ -9198,15 +9320,14 @@
|
||||
}
|
||||
},
|
||||
"read-config-file": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-5.0.2.tgz",
|
||||
"integrity": "sha512-tVt1lsiSjs+FtL/vtfCivqtKR1UNk3BB3uPJQvJqkgtAYDvZjo0xyXFYSVmzaTcO+Jdi5G7O2K2vDV+p1M/oug==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.0.0.tgz",
|
||||
"integrity": "sha512-PHjROSdpceKUmqS06wqwP92VrM46PZSTubmNIMJ5DrMwg1OgenSTSEHIkCa6TiOJ+y/J0xnG1fFwG3M+Oi1aNA==",
|
||||
"requires": {
|
||||
"dotenv": "^8.2.0",
|
||||
"dotenv-expand": "^5.1.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"js-yaml": "^3.13.1",
|
||||
"json5": "^2.1.1",
|
||||
"json5": "^2.1.2",
|
||||
"lazy-val": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -9515,9 +9636,9 @@
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.15.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
|
||||
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
@ -10326,9 +10447,9 @@
|
||||
}
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
|
||||
"integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
|
||||
"version": "0.5.18",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.18.tgz",
|
||||
"integrity": "sha512-9luZr/BZ2QeU6tO2uG8N2aZpVSli4TSAOAqFOyTO51AJcD9P99c0K1h6dD6r6qo5dyT44BR5exweOaLLeldTkQ==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
@ -10357,9 +10478,9 @@
|
||||
}
|
||||
},
|
||||
"spdx-exceptions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
|
||||
"integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
|
||||
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
|
||||
},
|
||||
"spdx-expression-parse": {
|
||||
"version": "3.0.0",
|
||||
@ -11094,9 +11215,9 @@
|
||||
}
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.0.tgz",
|
||||
"integrity": "sha512-j5wNQBWaql8gr06dOUrfaohHlscboQZ9B8sNsoK5o4sBjm7Ht9dxSbrMXyktQpA16Acaij8AcoozteaPYZON0g==",
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.1.tgz",
|
||||
"integrity": "sha512-JUPoL1jHsc9fOjVFHdQIhqEEJsQvfKDjlubcCilu8U26uZ73qOg8VsN8O1jbuei44ZPlwL7kmbAdM4tzaUvqnA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@ -11483,16 +11604,16 @@
|
||||
"dev": true
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.42.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz",
|
||||
"integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==",
|
||||
"version": "4.43.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz",
|
||||
"integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/wasm-edit": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"acorn": "^6.2.1",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/wasm-edit": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"acorn": "^6.4.1",
|
||||
"ajv": "^6.10.2",
|
||||
"ajv-keywords": "^3.4.1",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
@ -11503,13 +11624,13 @@
|
||||
"loader-utils": "^1.2.3",
|
||||
"memory-fs": "^0.4.1",
|
||||
"micromatch": "^3.1.10",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mkdirp": "^0.5.3",
|
||||
"neo-async": "^2.6.1",
|
||||
"node-libs-browser": "^2.2.1",
|
||||
"schema-utils": "^1.0.0",
|
||||
"tapable": "^1.1.3",
|
||||
"terser-webpack-plugin": "^1.4.3",
|
||||
"watchpack": "^1.6.0",
|
||||
"watchpack": "^1.6.1",
|
||||
"webpack-sources": "^1.4.1"
|
||||
}
|
||||
},
|
||||
@ -12309,9 +12430,9 @@
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz",
|
||||
"integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==",
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
|
@ -7,4 +7,6 @@ pub mod function;
|
||||
pub mod seq;
|
||||
pub mod theme;
|
||||
|
||||
pub use data::hash_map_tree::HashMapTree;
|
||||
pub use data::index::Index;
|
||||
pub use data::opt_vec::OptVec;
|
||||
|
@ -9,6 +9,7 @@ pub mod render;
|
||||
pub mod scene;
|
||||
pub mod shape;
|
||||
pub mod symbol;
|
||||
pub mod style;
|
||||
pub mod world;
|
||||
|
||||
|
||||
|
583
gui/src/rust/ensogl/src/display/style.rs
Normal file
583
gui/src/rust/ensogl/src/display/style.rs
Normal file
@ -0,0 +1,583 @@
|
||||
//! This module defines a cascading style sheet registry and related style management utilities.
|
||||
|
||||
pub mod data;
|
||||
pub mod path;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::data::HashMapTree;
|
||||
use crate::data::Index;
|
||||
use crate::data::OptVec;
|
||||
|
||||
pub use self::data::Data;
|
||||
pub use self::data::data;
|
||||
pub use self::path::Path;
|
||||
|
||||
|
||||
|
||||
// ===========
|
||||
// === Var ===
|
||||
// ===========
|
||||
|
||||
/// Data of a style variable. Variables are associated with a style path like 'panel.button.size'
|
||||
/// and are automatically bound to the most specific style sheet as soon as it gets defined. By
|
||||
/// most specific, we mean the one with the longest path. For example, the 'panel.button.size' var
|
||||
/// will be bound to one of 'panel.button.size', 'button.size', or 'size' if defined, in that order.
|
||||
#[derive(Debug)]
|
||||
pub struct Var {
|
||||
/// Index of the var in the style var map.
|
||||
index : Index<Var>,
|
||||
/// Set of all `Sheet` indexes which are potential matches of this var. For example, for a var
|
||||
/// 'panel.button.size', all of the following sheets will be included here: 'panel.button.size',
|
||||
/// 'button.size', and 'size'.
|
||||
matches : Vec<Index<Sheet>>,
|
||||
/// Index of the most specific `Sheet` from `matches` which has a defined value if any.
|
||||
binding : Option<Index<Sheet>>,
|
||||
/// List of all `Sheet`s which use this var in their expressions.
|
||||
usages : HashSet<Index<Sheet>>,
|
||||
}
|
||||
|
||||
impl Var {
|
||||
/// Constructor.
|
||||
pub fn new(index:Index<Var>) -> Self {
|
||||
let matches = default();
|
||||
let binding = default();
|
||||
let usages = default();
|
||||
Self {index,matches,binding,usages}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Sheet ===
|
||||
// =============
|
||||
|
||||
/// A node in the style sheet tree. Style sheets are associated with a style path like
|
||||
/// 'panel.button.size' and each node keeps a `Data` value. The value can either be set explicitly,
|
||||
/// or computed automatically if the style sheet is defined with en `Expression`. Please note that
|
||||
/// although `Sheet` contains a single value, it is in fact a node in a tree defined in `Registry`,
|
||||
/// so it can be interpreted as a set of hierarchical values instead.
|
||||
#[derive(Debug)]
|
||||
pub struct Sheet {
|
||||
/// Index of the style sheet in the style sheet map.
|
||||
index : Index<Sheet>,
|
||||
/// Value of this style sheet node. Style sheets without value behave like if they do not exist.
|
||||
value : Option<Data>,
|
||||
/// Expression used to update the value.
|
||||
expr : Option<Expression>,
|
||||
/// Indexes of all `Var`s that are potential matches with this style sheet.
|
||||
matches : HashSet<Index<Var>>,
|
||||
/// Indexes of all `Var`s that are bound (best matches) with this style sheet.
|
||||
bindings : HashSet<Index<Var>>,
|
||||
}
|
||||
|
||||
impl Sheet {
|
||||
/// Constructor.
|
||||
pub fn new(index:Index<Sheet>) -> Self {
|
||||
let value = default();
|
||||
let expr = default();
|
||||
let matches = default();
|
||||
let bindings = default();
|
||||
Self {index,value,expr,matches,bindings}
|
||||
}
|
||||
|
||||
/// Checks whether the style sheet exist. Style sheets without value are considered templates
|
||||
/// and are kept in the graph for optimization purposes only.
|
||||
pub fn exists(&self) -> bool {
|
||||
self.value.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================
|
||||
// === Expression ===
|
||||
// ==================
|
||||
|
||||
/// Expression of a style sheet.
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct Expression {
|
||||
/// Indexes of all vars which are used as sources to the function of this expression.
|
||||
sources : Vec<Index<Var>>,
|
||||
/// Function used to compute the new value of the style sheet.
|
||||
#[derivative(Debug="ignore")]
|
||||
function : Box<dyn Fn(&[&Data])->Data>
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Types ===
|
||||
// =============
|
||||
|
||||
// === Types ===
|
||||
|
||||
#[allow(missing_docs)]
|
||||
mod types {
|
||||
use super::*;
|
||||
pub type VarVec = OptVec<Var,Index<Var>>;
|
||||
pub type SheetVec = OptVec<Sheet,Index<Sheet>>;
|
||||
pub type VarMap = HashMapTree<String,Option<Index<Var>>>;
|
||||
pub type SheetMap = HashMapTree<String,Index<Sheet>>;
|
||||
}
|
||||
use types::*;
|
||||
|
||||
trait NewInstance<K> {
|
||||
fn new_instance(&mut self) -> K;
|
||||
}
|
||||
|
||||
impl NewInstance<Index<Var>> for VarVec {
|
||||
fn new_instance(&mut self) -> Index<Var> {
|
||||
self.insert_with_ix(Var::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl NewInstance<Index<Sheet>> for SheetVec {
|
||||
fn new_instance(&mut self) -> Index<Sheet> {
|
||||
self.insert_with_ix(Sheet::new)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Registry ===
|
||||
// ================
|
||||
|
||||
/// Style sheet registry. Could be named "Cascading Style Sheets" but then the name will be
|
||||
/// confusing with CSS used in web development. Defines a set of cascading style sheets. Each
|
||||
/// style sheet can be assigned with a value of type `Data` or an expression to compute one. It
|
||||
/// also allows creating variables which are automatically bound to the most specific style sheet.
|
||||
/// See `Var` and `Sheet` to learn more.
|
||||
#[derive(Debug)]
|
||||
pub struct Registry {
|
||||
/// Set of all variables.
|
||||
pub vars : VarVec,
|
||||
/// Set of all style sheets.
|
||||
pub sheets : SheetVec,
|
||||
/// Association of a path like 'button' -> 'size' to a variable.
|
||||
pub var_map : VarMap,
|
||||
/// Association of a path like 'button' -> 'size' to a style sheet.
|
||||
pub sheet_map : SheetMap,
|
||||
}
|
||||
|
||||
|
||||
// === Constructors ===
|
||||
|
||||
impl Registry {
|
||||
/// Constructor.
|
||||
pub fn new() -> Self {
|
||||
let vars = default();
|
||||
let mut sheets = OptVec::<Sheet,Index<Sheet>>::new();
|
||||
let var_map = default();
|
||||
let root_sheet_id = sheets.new_instance();
|
||||
let sheet_map = SheetMap::from_value(root_sheet_id);
|
||||
Self {vars,sheets,var_map,sheet_map}
|
||||
}
|
||||
|
||||
/// Access variable by the given path or create new one if missing.
|
||||
///
|
||||
/// Implementation note: under the hood, a `Sheet` for each sub-path will be created. For
|
||||
/// example, when creating "panel.button.size" variable, three sheets will be created as well:
|
||||
/// "panel.button.size", "button.size", and "size". This way we keep track of all possible
|
||||
/// matches and we can create high-performance value binding algorithms.
|
||||
pub fn var<P:Into<Path>>(&mut self, path:P) -> Index<Var> {
|
||||
let path = path.into();
|
||||
let vars = &mut self.vars;
|
||||
let sheets = &mut self.sheets;
|
||||
let var_map_node = self.var_map.get_node(&path.rev_segments);
|
||||
let var_id = *var_map_node.value_or_set_with(||vars.new_instance());
|
||||
|
||||
let mut var_matches = Vec::new();
|
||||
self.sheet_map.get_node_traversing_with(&path.rev_segments,||{sheets.new_instance()}, |t| {
|
||||
var_matches.push(t.value)
|
||||
});
|
||||
var_matches.reverse();
|
||||
|
||||
for sheet_id in &var_matches {
|
||||
self.sheets[*sheet_id].matches.insert(var_id);
|
||||
}
|
||||
|
||||
self.vars[var_id].matches = var_matches;
|
||||
self.rebind_var(var_id);
|
||||
var_id
|
||||
}
|
||||
|
||||
/// Access style sheet by the given path or create new one if missing.
|
||||
fn sheet<P:Into<Path>>(&mut self, path:P) -> Index<Sheet> {
|
||||
let path = path.into();
|
||||
let sheets = &mut self.sheets;
|
||||
let node = self.sheet_map.get_node_with(&path.rev_segments,|| sheets.new_instance());
|
||||
node.value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Getters ===
|
||||
|
||||
impl Registry {
|
||||
/// Reads the value of the variable.
|
||||
pub fn value(&self, var_id:Index<Var>) -> Option<&Data> {
|
||||
self.vars.safe_index(var_id).as_ref().and_then(|var| {
|
||||
var.binding.and_then(|sheet_id| {
|
||||
self.sheets[sheet_id].value.as_ref()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Setters ===
|
||||
|
||||
impl Registry {
|
||||
/// Set a style sheet value. Please note that it will remove expression assigned to the target
|
||||
/// style sheet if any.
|
||||
pub fn set_value<P:Into<Path>>(&mut self, path:P, data:Data) {
|
||||
self.set_value_to(path,Some(data))
|
||||
}
|
||||
|
||||
/// Removes a style sheet value. Please note that it will remove expression assigned to the
|
||||
/// target style sheet if any.
|
||||
pub fn remove_value<P:Into<Path>>(&mut self, path:P) {
|
||||
self.set_value_to(path,None)
|
||||
}
|
||||
|
||||
/// Set or unset a style sheet value. Please note that it will remove expression assigned to the
|
||||
/// target style sheet if any.
|
||||
pub fn set_value_to<P:Into<Path>>(&mut self, path:P, data:Option<Data>) {
|
||||
let path = path.into();
|
||||
self.remove_expression(&path);
|
||||
let sheet_id = self.sheet(&path);
|
||||
let sheet = &mut self.sheets[sheet_id];
|
||||
sheet.value = data;
|
||||
for var_id in sheet.matches.clone() {
|
||||
self.rebind_var(var_id)
|
||||
}
|
||||
for sheet_id in self.sheet_topo_sort(sheet_id) {
|
||||
self.recompute(sheet_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a style sheet expression which will be used to automatically compute values whenever any
|
||||
/// of the provided dependencies will change.
|
||||
pub fn set_expression<P,F>(&mut self, path:P, args:&[Index<Var>], function:F)
|
||||
where P:Into<Path>, F:'static+Fn(&[&Data])->Data {
|
||||
let sheet_id = self.sheet(path);
|
||||
let sheet = &mut self.sheets[sheet_id];
|
||||
let sources = args.to_vec();
|
||||
let function = Box::new(function);
|
||||
sheet.expr = Some(Expression {sources,function});
|
||||
for var_id in args {
|
||||
self.vars[*var_id].usages.insert(sheet_id);
|
||||
}
|
||||
self.rebind_and_recompute(sheet_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Utils ===
|
||||
|
||||
impl Registry {
|
||||
/// Check all potential candidates (sheets) this variable matches to and choose the most
|
||||
/// specific one from those which exist (have a value).
|
||||
fn rebind_var(&mut self, var_id:Index<Var>) {
|
||||
let mut found = false;
|
||||
let var = &self.vars[var_id];
|
||||
for sheet_id in var.matches.clone() {
|
||||
let sheet = &self.sheets[sheet_id];
|
||||
if sheet.exists() {
|
||||
if let Some(sheet_id) = var.binding {
|
||||
self.sheets[sheet_id].bindings.remove(&var_id);
|
||||
}
|
||||
let var = &mut self.vars[var_id];
|
||||
let sheet = &mut self.sheets[sheet_id];
|
||||
var.binding = Some(sheet_id);
|
||||
sheet.bindings.insert(var_id);
|
||||
found = true;
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found { self.unbind_var(var_id) }
|
||||
}
|
||||
|
||||
/// Removes all binding information from var and related style sheets.
|
||||
fn unbind_var(&mut self, var_id:Index<Var>) {
|
||||
let var = &self.vars[var_id];
|
||||
var.binding.for_each(|sheet_id| {
|
||||
self.sheets[sheet_id].bindings.remove(&var_id);
|
||||
});
|
||||
let var = &mut self.vars[var_id];
|
||||
var.binding = None;
|
||||
}
|
||||
|
||||
/// Internal utility for removing style sheet expression.
|
||||
fn remove_expression<P>(&mut self, path:P)
|
||||
where P:Into<Path> {
|
||||
let sheet_id = self.sheet(path);
|
||||
let sheet = &mut self.sheets[sheet_id];
|
||||
if sheet.expr.is_some() {
|
||||
sheet.value = None;
|
||||
let opt_expr = mem::take(&mut sheet.expr);
|
||||
if let Some(expr) = opt_expr {
|
||||
for var_id in expr.sources {
|
||||
self.vars[var_id].usages.remove(&sheet_id);
|
||||
}
|
||||
}
|
||||
self.rebind_and_recompute(sheet_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal utility which recomputes the provided style sheet, rebinds related variables, and
|
||||
/// recomputes all dependent style sheets.
|
||||
fn rebind_and_recompute(&mut self, sheet_id:Index<Sheet>) {
|
||||
self.recompute(sheet_id);
|
||||
let sheet = &mut self.sheets[sheet_id];
|
||||
for var_id in sheet.matches.clone() {
|
||||
self.rebind_var(var_id)
|
||||
}
|
||||
for sheet_id in self.sheet_topo_sort(sheet_id) {
|
||||
self.recompute(sheet_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Recomputes the value of the provided sheet if the sheet was assigned with an expression.
|
||||
fn recompute(&mut self, sheet_id:Index<Sheet>) {
|
||||
let sheet = &self.sheets[sheet_id];
|
||||
let value = sheet.expr.as_ref().and_then(|expr| {
|
||||
let mut opt_values : Vec<Option<&Data>> = Vec::new();
|
||||
for var_id in &expr.sources {
|
||||
opt_values.push(self.value(*var_id));
|
||||
}
|
||||
let values : Option<Vec<&Data>> = opt_values.into_iter().collect();
|
||||
values.map(|v| (expr.function)(&v) )
|
||||
});
|
||||
let sheet_mut = &mut self.sheets[sheet_id];
|
||||
value.for_each(|v| sheet_mut.value = Some(v));
|
||||
}
|
||||
|
||||
/// Traverses all sheets whose value depend on the value of the provided sheet and sorts them
|
||||
/// in a topological order. This is used mainly for efficient implementation of sheet
|
||||
/// recomputation mechanism.
|
||||
fn sheet_topo_sort(&self, changed_sheet_id:Index<Sheet>) -> Vec<Index<Sheet>> {
|
||||
let mut sheet_ref_count = HashMap::<Index<Sheet>,usize>::new();
|
||||
let mut sorted_sheets = vec![changed_sheet_id];
|
||||
self.with_all_sheet_deps(changed_sheet_id, |sheet_id| {
|
||||
*sheet_ref_count.entry(sheet_id).or_default() += 1;
|
||||
});
|
||||
self.with_all_sheet_deps(changed_sheet_id, |sheet_id| {
|
||||
let ref_count = sheet_ref_count.entry(sheet_id).or_default();
|
||||
*ref_count -= 1;
|
||||
if *ref_count == 0 {
|
||||
sorted_sheets.push(sheet_id);
|
||||
}
|
||||
});
|
||||
sorted_sheets
|
||||
}
|
||||
|
||||
/// Runs the provided callback with all sheet indexes whose value depend on the value of the
|
||||
/// provided sheet.
|
||||
fn with_all_sheet_deps<F>(&self, target:Index<Sheet>, mut callback:F)
|
||||
where F:FnMut(Index<Sheet>) {
|
||||
let mut sheets_to_visit = vec![target];
|
||||
while !sheets_to_visit.is_empty() {
|
||||
if let Some(current_sheet_id) = sheets_to_visit.pop() {
|
||||
let sheet = &self.sheets[current_sheet_id];
|
||||
for var_id in &sheet.bindings {
|
||||
let var = &self.vars[*var_id];
|
||||
for sheet_id in &var.usages {
|
||||
callback(*sheet_id);
|
||||
sheets_to_visit.push(*sheet_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Debug ===
|
||||
|
||||
impl Registry {
|
||||
/// Visualizes the network in the GraphViz Dot language. Use `visualize` to automatically
|
||||
/// display it in a new browser tab.
|
||||
pub fn to_graphviz(&self) -> String {
|
||||
let mut dot = String::new();
|
||||
Self::sheet_map_to_graphviz(&mut dot,&self.sheet_map);
|
||||
Self::var_map_to_graphviz(&mut dot,&mut vec![],&self.var_map);
|
||||
let s = &mut dot;
|
||||
for var in &self.vars {
|
||||
for sheet in &var.matches {Self::var_sheet_link(s,var.index,*sheet,"[style=dashed]")}
|
||||
for sheet in &var.binding {Self::var_sheet_link(s,var.index,*sheet,"[color=red]")}
|
||||
for sheet in &var.usages {Self::var_sheet_link(s,var.index,*sheet,"[color=blue]")}
|
||||
}
|
||||
for sheet in &self.sheets {
|
||||
for var in &sheet.matches {Self::sheet_var_link(s,sheet.index,*var,"[style=dashed]")}
|
||||
for var in &sheet.bindings {Self::sheet_var_link(s,sheet.index,*var,"[color=red]")}
|
||||
for expr in &sheet.expr {
|
||||
for var in &expr.sources {Self::sheet_var_link(s,sheet.index,*var,"[color=blue]")}
|
||||
}
|
||||
}
|
||||
format!("digraph G {{\nnode [shape=box style=rounded]\n{}\n}}",dot)
|
||||
}
|
||||
|
||||
fn sheet_map_to_graphviz(dot:&mut String, sheet_map:&SheetMap) {
|
||||
let sheet_id = sheet_map.value;
|
||||
dot.push_str(&iformat!("sheet_{sheet_id}\n"));
|
||||
for (path,child) in sheet_map {
|
||||
Self::sheet_sheet_link(dot,sheet_id,child.value,iformat!("[label=\"{path}\"]"));
|
||||
Self::sheet_map_to_graphviz(dot,child);
|
||||
}
|
||||
}
|
||||
|
||||
fn var_map_to_graphviz(dot:&mut String, path:&mut Vec<String>, var_map:&VarMap) {
|
||||
var_map.value.for_each(|var_id| {
|
||||
let real_path = path.iter().rev().join(".");
|
||||
dot.push_str(&iformat!("var_{var_id} [label=\"Var({real_path})\"]\n"));
|
||||
});
|
||||
for (segment,child) in var_map {
|
||||
path.push(segment.into());
|
||||
Self::var_map_to_graphviz(dot,path,child);
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn var_sheet_link<S>(dot:&mut String, var_id:Index<Var>, sheet_id:Index<Sheet>, s:S)
|
||||
where S:Into<String> {
|
||||
Self::link(dot,"var","sheet",var_id,sheet_id,s)
|
||||
}
|
||||
|
||||
fn sheet_var_link<S>(dot:&mut String, sheet_id:Index<Sheet>, var_id:Index<Var>, s:S)
|
||||
where S:Into<String> {
|
||||
Self::link(dot,"sheet","var",sheet_id,var_id,s)
|
||||
}
|
||||
|
||||
fn sheet_sheet_link<S>(dot:&mut String, sheet_id_1:Index<Sheet>, sheet_id_2:Index<Sheet>, s:S)
|
||||
where S:Into<String> {
|
||||
Self::link(dot,"sheet","sheet",sheet_id_1,sheet_id_2,s)
|
||||
}
|
||||
|
||||
fn link<Src,Tgt,S>(dot:&mut String, src_pfx:&str, tgt_pfx:&str, src:Src, tgt:Tgt, s:S)
|
||||
where Src:Display, Tgt:Display, S:Into<String> {
|
||||
dot.push_str(&format!("{}_{} -> {}_{} {}\n",src_pfx,src,tgt_pfx,tgt,s.into()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Impls ===
|
||||
|
||||
impl Default for Registry {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Tests ===
|
||||
// =============
|
||||
|
||||
/// Interactive testing utility. To be removed in the future.
|
||||
pub fn test() {
|
||||
let mut style = Registry::new();
|
||||
|
||||
let var_size = style.var("size");
|
||||
let var_button_size = style.var("button.size");
|
||||
let var_graph_button_size = style.var("graph.button.size");
|
||||
let _var = style.var("scene.background.color");
|
||||
let _var = style.var("application.text.color");
|
||||
let _var = style.var("application.text.size");
|
||||
let _var = style.var("button.text.size");
|
||||
let _var = style.var("node.text.color");
|
||||
let _var = style.var("node.text.size");
|
||||
let _var = style.var("application.background.color");
|
||||
let _var = style.var("node.background.color");
|
||||
|
||||
assert!(style.value(var_graph_button_size).is_none());
|
||||
style.set_value("size",data(1.0));
|
||||
style.set_expression("graph.button.size",&[var_button_size],|args| args[0] + &data(100.0));
|
||||
style.set_expression("button.size",&[var_size],|args| args[0] + &data(10.0));
|
||||
style.set_value("button.size",data(3.0));
|
||||
|
||||
println!("{}",style.to_graphviz());
|
||||
println!("{:?}", style.value(var_graph_button_size));
|
||||
println!("{:?}", style.value(var_button_size));
|
||||
println!("{:?}", style.vars[var_graph_button_size]);
|
||||
println!("{:?}", style.sheets[style.vars[var_graph_button_size].binding.unwrap()]);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn simple_var_binding_1() {
|
||||
let mut style = Registry::new();
|
||||
let var1 = style.var(&["size"]);
|
||||
assert!(style.value(var1).is_none());
|
||||
style.set_value(&["size"],data(1.0));
|
||||
assert_eq!(style.value(var1),Some(&data(1.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn simple_var_binding_2() {
|
||||
let mut style = Registry::new();
|
||||
style.set_value(&["size"],data(1.0));
|
||||
let var1 = style.var(&["size"]);
|
||||
assert_eq!(style.value(var1),Some(&data(1.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn hierarchical_var_binding() {
|
||||
let mut style = Registry::new();
|
||||
let var1 = style.var("graph.button.size");
|
||||
assert!(style.value(var1).is_none());
|
||||
style.set_value("size",data(1.0));
|
||||
assert_eq!(style.value(var1),Some(&data(1.0)));
|
||||
style.set_value("button.size",data(2.0));
|
||||
assert_eq!(style.value(var1),Some(&data(2.0)));
|
||||
style.set_value("graph.button.size",data(3.0));
|
||||
assert_eq!(style.value(var1),Some(&data(3.0)));
|
||||
style.remove_value("graph.button.size");
|
||||
assert_eq!(style.value(var1),Some(&data(2.0)));
|
||||
style.remove_value("button.size");
|
||||
assert_eq!(style.value(var1),Some(&data(1.0)));
|
||||
style.remove_value("size");
|
||||
assert_eq!(style.value(var1),None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn expr_bindings_1() {
|
||||
let mut style = Registry::new();
|
||||
|
||||
let var_size = style.var("size");
|
||||
let var_button_size = style.var("button.size");
|
||||
let var_graph_button_size = style.var("graph.button.size");
|
||||
|
||||
assert!(style.value(var_graph_button_size).is_none());
|
||||
style.set_value("size",data(1.0));
|
||||
assert_eq!(style.value(var_graph_button_size),Some(&data(1.0)));
|
||||
style.set_expression("graph.button.size",&[var_button_size],|args| args[0] + &data(10.0));
|
||||
assert_eq!(style.value(var_graph_button_size),Some(&data(11.0)));
|
||||
style.set_expression("button.size",&[var_size],|args| args[0] + &data(100.0));
|
||||
assert_eq!(style.value(var_graph_button_size),Some(&data(111.0)));
|
||||
style.set_value("size",data(2.0));
|
||||
assert_eq!(style.value(var_graph_button_size),Some(&data(112.0)));
|
||||
style.set_value("button.size",data(3.0));
|
||||
assert_eq!(style.value(var_graph_button_size),Some(&data(13.0)));
|
||||
style.set_value("button.size",data(4.0));
|
||||
assert_eq!(style.value(var_graph_button_size),Some(&data(14.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn expr_circular() {
|
||||
let mut style = Registry::new();
|
||||
|
||||
let var_a = style.var("a");
|
||||
let var_b = style.var("b");
|
||||
|
||||
style.set_expression("a",&[var_b],|args| args[0].clone());
|
||||
style.set_expression("b",&[var_a],|args| args[0].clone());
|
||||
assert!(style.value(var_a).is_none());
|
||||
}
|
||||
}
|
117
gui/src/rust/ensogl/src/display/style/data.rs
Normal file
117
gui/src/rust/ensogl/src/display/style/data.rs
Normal file
@ -0,0 +1,117 @@
|
||||
//! Definition of style sheet values.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::data::color;
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Data ===
|
||||
// ============
|
||||
|
||||
/// Type of values in the style sheet.
|
||||
#[derive(Debug,Clone,PartialEq)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Data {
|
||||
Invalid(String),
|
||||
Number(f32),
|
||||
Rgba(color::LinSrgba),
|
||||
}
|
||||
|
||||
|
||||
// === Constructors ===
|
||||
|
||||
/// Smart constructor for `Data`.
|
||||
pub fn data<T:Into<Data>>(t:T) -> Data {
|
||||
t.into()
|
||||
}
|
||||
|
||||
impl From<f32> for Data {
|
||||
fn from(t:f32) -> Data {
|
||||
Data::Number(t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Impls ===
|
||||
|
||||
//impl Eq for Data {}
|
||||
|
||||
impl Display for Data {
|
||||
fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Invalid(s) => write!(f,"{}",s),
|
||||
Self::Number(t) => write!(f,"Number({})",t),
|
||||
Self::Rgba(t) => write!(f,"Color({:?})",t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Data {
|
||||
/// Lighten the color by `amount`.
|
||||
pub fn lighten(&self, amount:f32) -> Self {
|
||||
match self {
|
||||
Data::Invalid(s) => Data::Invalid(s.clone()),
|
||||
Data::Rgba(t) => Data::Rgba(palette::Shade::lighten(t,amount)),
|
||||
this => Data::Invalid(format!("Cannot use method lighten on {}.",this))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Color Getters ===
|
||||
|
||||
macro_rules! define_color_getter {
|
||||
($($name:ident),*) => {$(
|
||||
impl Data {
|
||||
/// Component getter.
|
||||
pub fn $name(&self) -> Data {
|
||||
match self {
|
||||
Data::Invalid(s) => Data::Invalid(s.clone()),
|
||||
Data::Rgba(t) => Data::Number(t.$name),
|
||||
this => Data::Invalid (format!
|
||||
(concat!("Cannot access ",stringify!($name)," property of {}."),this))
|
||||
}
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
define_color_getter!(red,green,blue,alpha);
|
||||
|
||||
|
||||
|
||||
// === Operators ===
|
||||
|
||||
macro_rules! define_binary_number_operator {
|
||||
($($toks:tt)*) => {
|
||||
_define_binary_number_operator! { [&Data] [&Data] $($toks)* }
|
||||
_define_binary_number_operator! { [ Data] [&Data] $($toks)* }
|
||||
_define_binary_number_operator! { [&Data] [ Data] $($toks)* }
|
||||
_define_binary_number_operator! { [ Data] [ Data] $($toks)* }
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! _define_binary_number_operator {
|
||||
([$($t1:tt)*] [$($t2:tt)*] $name:ident :: $fn:ident, $($err:tt)*) => {
|
||||
impl $name<$($t2)*> for $($t1)* {
|
||||
type Output = Data;
|
||||
#[allow(clippy::redundant_closure_call)]
|
||||
fn $fn(self, rhs:$($t2)*) -> Self::Output {
|
||||
match(self,rhs) {
|
||||
(Data::Invalid(t),_) => Data::Invalid(t.clone()),
|
||||
(_,Data::Invalid(t)) => Data::Invalid(t.clone()),
|
||||
(Data::Number(lhs),Data::Number(rhs)) => Data::Number(lhs.$fn(rhs)),
|
||||
(lhs,rhs) => Data::Invalid(($($err)*)(lhs,rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_binary_number_operator!(Mul::mul,|lhs,rhs| format!("Cannot multiply {} by {}.",lhs,rhs));
|
||||
define_binary_number_operator!(Div::div,|lhs,rhs| format!("Cannot divide {} by {}.",lhs,rhs));
|
||||
define_binary_number_operator!(Add::add,|lhs,rhs| format!("Cannot add {} to {}.",lhs,rhs));
|
||||
define_binary_number_operator!(Sub::sub,|lhs,rhs| format!("Cannot subtract {} from {}.",rhs,lhs));
|
63
gui/src/rust/ensogl/src/display/style/path.rs
Normal file
63
gui/src/rust/ensogl/src/display/style/path.rs
Normal file
@ -0,0 +1,63 @@
|
||||
//! Path implementation used to navigate in the cascading style sheet hierarchy.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
||||
|
||||
// ============
|
||||
// === Path ===
|
||||
// ============
|
||||
|
||||
/// Path is a set of strings which describes how the variable or style sheet is nested in the
|
||||
/// cascading style sheet map.
|
||||
#[derive(Clone,Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct Path {
|
||||
pub rev_segments : Vec<String>
|
||||
}
|
||||
|
||||
impl Path {
|
||||
/// Builds the path from the provided segment iterator. Please note that the internal path
|
||||
/// representation is reversed, as the style sheet dependencies in the style sheet map tree are
|
||||
/// also kept in a reversed order. Please use the `visualize` utility to inspect the internal
|
||||
/// structure and learn more.
|
||||
pub fn from_segments<T,I,Item>(t:T) -> Self
|
||||
where T : IntoIterator<IntoIter=I,Item=Item>,
|
||||
I : DoubleEndedIterator + Iterator<Item=Item>,
|
||||
Item : Into<String> {
|
||||
Self::from_rev_segments(t.into_iter().rev())
|
||||
}
|
||||
|
||||
/// Builds the path from reversed segment iterator. See `from_segments` to learn more.
|
||||
pub fn from_rev_segments<T,Item>(t:T) -> Self
|
||||
where T : IntoIterator<Item=Item>,
|
||||
Item : Into<String> {
|
||||
let rev_segments = t.into_iter().map(|s|s.into()).collect();
|
||||
Self {rev_segments}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Path {
|
||||
fn from(t:&str) -> Self {
|
||||
Self::from_rev_segments(t.rsplit('.'))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Path> for Path {
|
||||
fn from(t:&Path) -> Self {
|
||||
t.clone()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! gen_var_path_conversions {
|
||||
($($($num:tt)?),*) => {$(
|
||||
impl<T:?Sized> From<&[&T$(;$num)?]> for Path
|
||||
where for <'t> &'t T : Into<String> {
|
||||
fn from(t:&[&T$(;$num)?]) -> Self {
|
||||
Self::from_segments(t.into_iter().map(|s|*s))
|
||||
}
|
||||
}
|
||||
)*};
|
||||
}
|
||||
|
||||
gen_var_path_conversions!(1,2,3,4,5,6,7,8,9,10,);
|
@ -10,6 +10,7 @@
|
||||
#![feature(cell_update)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(overlapping_marker_traits)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(specialization)]
|
||||
#![feature(fn_traits)]
|
||||
#![feature(trait_alias)]
|
||||
|
@ -81,7 +81,7 @@ impl {
|
||||
let name = name.as_ref().to_string();
|
||||
let buffer_dirty = self.buffer_dirty.clone();
|
||||
let shape_dirty = self.shape_dirty.clone();
|
||||
let ix = self.buffers.reserve_ix();
|
||||
let ix = self.buffers.reserve_index();
|
||||
group!(self.logger, "Adding buffer '{name}' at index {ix}.", {
|
||||
let on_set = Box::new(move || { buffer_dirty.set(ix) });
|
||||
let on_resize = Box::new(move || { shape_dirty.set() });
|
||||
|
113
gui/src/rust/lib/data/src/hash_map_tree.rs
Normal file
113
gui/src/rust/lib/data/src/hash_map_tree.rs
Normal file
@ -0,0 +1,113 @@
|
||||
//! A tree structure build on top of the `HashMap`.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
||||
|
||||
// ===================
|
||||
// === HashMapTree ===
|
||||
// ===================
|
||||
|
||||
/// A tree build on top of the `HashMap`. Each node in the tree can have zero or more branches
|
||||
/// accessible by the given key type.
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug (bound="K:Eq+Hash+Debug , T:Debug"))]
|
||||
#[derivative(Default (bound="K:Eq+Hash , T:Default"))]
|
||||
pub struct HashMapTree<K,T> {
|
||||
/// Value of the current tree node.
|
||||
pub value : T,
|
||||
/// Branches of the current tree node.
|
||||
pub branches : HashMap<K,HashMapTree<K,T>>
|
||||
}
|
||||
|
||||
impl<K,T> HashMapTree<K,T>
|
||||
where K:Eq+Hash {
|
||||
/// Constructor.
|
||||
pub fn new() -> Self where T:Default {
|
||||
default()
|
||||
}
|
||||
|
||||
/// Constructor with explicit root value.
|
||||
pub fn from_value(value:T) -> Self {
|
||||
let branches = default();
|
||||
Self {value,branches}
|
||||
}
|
||||
|
||||
/// Iterates over keys in `path`. For each key, traverses into the appropriate branch. In case
|
||||
/// the branch does not exist, a default instance will be created. Returns mutable reference to
|
||||
/// the target tree node.
|
||||
#[inline]
|
||||
pub fn get_node<P,I>(&mut self, path:P) -> &mut HashMapTree<K,T>
|
||||
where P:IntoIterator<Item=I>, T:Default, I:Into<K> {
|
||||
self.get_node_with(path,default)
|
||||
}
|
||||
|
||||
/// Iterates over keys in `path`. For each key, traverses into the appropriate branch. In case
|
||||
/// the branch does not exist, uses `cons` to construct it. Returns mutable reference to the
|
||||
/// target tree node.
|
||||
#[inline]
|
||||
pub fn get_node_with<P,I,F>(&mut self, path:P, f:F) -> &mut HashMapTree<K,T>
|
||||
where P:IntoIterator<Item=I>, I:Into<K>, F:FnMut()->T {
|
||||
self.get_node_traversing_with(path,f,|_|{})
|
||||
}
|
||||
|
||||
/// Iterates over keys in `path`. For each key, traverses into the appropriate branch. In case
|
||||
/// the branch does not exist, uses `cons` to construct it. Moreover, for each traversed branch
|
||||
/// the `callback` is evaluated. Returns mutable reference to the target tree node.
|
||||
#[inline]
|
||||
pub fn get_node_traversing_with<P,I,F,M>
|
||||
(&mut self, path:P, mut cons:F, mut callback:M) -> &mut HashMapTree<K,T>
|
||||
where P:IntoIterator<Item=I>, I:Into<K>, F:FnMut()->T, M:FnMut(&mut HashMapTree<K,T>) {
|
||||
path.into_iter().fold(self,|map,t| {
|
||||
let key = t.into();
|
||||
let node = map.branches.entry(key).or_insert_with(|| HashMapTree::from_value(cons()));
|
||||
callback(node);
|
||||
node
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<K,T> HashMapTree<K,Option<T>>
|
||||
where K:Eq+Hash {
|
||||
/// Gets the current value or creates new default one if missing.
|
||||
pub fn value_or_default(&mut self) -> &mut T where T:Default {
|
||||
self.value_or_set_with(default)
|
||||
}
|
||||
|
||||
/// Gets the current value or creates new one if missing.
|
||||
pub fn value_or_set(&mut self, val:T) -> &mut T {
|
||||
self.value_or_set_with(move || val)
|
||||
}
|
||||
|
||||
/// Gets the current value or creates new one if missing.
|
||||
pub fn value_or_set_with<F>(&mut self, cons:F) -> &mut T
|
||||
where F:FnOnce()->T {
|
||||
if self.value.is_none() {
|
||||
self.value = Some(cons());
|
||||
};
|
||||
self.value.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Impls ===
|
||||
|
||||
impl<'a,K,T> IntoIterator for &'a HashMapTree<K,T> {
|
||||
type Item = (&'a K, &'a HashMapTree<K,T>);
|
||||
type IntoIter = std::collections::hash_map::Iter<'a,K,HashMapTree<K,T>>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.branches.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,K,T> IntoIterator for &'a mut HashMapTree<K,T> {
|
||||
type Item = (&'a K, &'a mut HashMapTree<K,T>);
|
||||
type IntoIter = std::collections::hash_map::IterMut<'a,K,HashMapTree<K,T>>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.branches.iter_mut()
|
||||
}
|
||||
}
|
84
gui/src/rust/lib/data/src/index.rs
Normal file
84
gui/src/rust/lib/data/src/index.rs
Normal file
@ -0,0 +1,84 @@
|
||||
//! This module defines a typed index struct. Useful to introduce type safety when using indexes
|
||||
//! several indexable containers.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
|
||||
|
||||
// =============
|
||||
// === Index ===
|
||||
// =============
|
||||
|
||||
/// Typed newtype for `usize` meant to be used as a typed index.
|
||||
pub struct Index<T> {
|
||||
/// Raw value.
|
||||
pub raw : usize,
|
||||
phantom : PhantomData<T>
|
||||
}
|
||||
|
||||
impl<T> Index<T> {
|
||||
/// Constructor
|
||||
pub fn new(raw:usize) -> Self {
|
||||
let phantom = default();
|
||||
Self {raw,phantom}
|
||||
}
|
||||
}
|
||||
|
||||
// === Impls ===
|
||||
|
||||
impl<T> Copy for Index<T> {}
|
||||
impl<T> Eq for Index<T> {}
|
||||
|
||||
impl<T> Clone for Index<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Hash for Index<T> {
|
||||
fn hash<H:std::hash::Hasher>(&self, state:&mut H) {
|
||||
self.raw.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for Index<T> {
|
||||
fn eq(&self, other:&Self) -> bool {
|
||||
self.raw == other.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Index<T>> for usize {
|
||||
fn from(t:Index<T>) -> Self {
|
||||
t.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<&Index<T>> for usize {
|
||||
fn from(t:&Index<T>) -> Self {
|
||||
t.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<usize> for Index<T> {
|
||||
fn from(t:usize) -> Self {
|
||||
Self::new(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<&usize> for Index<T> {
|
||||
fn from(t:&usize) -> Self {
|
||||
Self::new(*t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Debug for Index<T> {
|
||||
fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f,"{}",self.raw)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Display for Index<T> {
|
||||
fn fmt(&self, f:&mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f,"{}",self.raw)
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
//! Library of general data structures.
|
||||
|
||||
#![feature(trait_alias)]
|
||||
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(missing_copy_implementations)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
pub mod hash_map_tree;
|
||||
pub mod index;
|
||||
pub mod opt_vec;
|
||||
pub mod text;
|
||||
|
||||
|
@ -1,90 +1,62 @@
|
||||
#![allow(missing_docs)]
|
||||
//! A sparse vector implementation.
|
||||
|
||||
use crate::prelude::*;
|
||||
use std::iter::FilterMap;
|
||||
use std::slice;
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === OptVec ===
|
||||
// ==============
|
||||
|
||||
// === Definition ===
|
||||
|
||||
/// A contiguous growable sparse array type. Similar to `Vec<T>`, but allowing missing values.
|
||||
/// After a value is removed, it remembers the index for reuse in the future.
|
||||
/// After a value is removed, it remembers the index for reuse in the future. Unlike `Vec`, it is
|
||||
/// parametrized with optional `Index` type variable which will be used for indexing the vector.
|
||||
/// Index have to implement the `Index` trait.
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
#[derivative(Default(bound=""))]
|
||||
#[derive(Clone,Debug,Shrinkwrap)]
|
||||
pub struct OptVec<T> {
|
||||
pub struct OptVec<T,Index=usize> {
|
||||
#[shrinkwrap(main_field)]
|
||||
pub items: Vec<Option<T>>,
|
||||
pub free_ixs: SmallVec<[Ix; 128]>,
|
||||
items : Vec<Option<T>>,
|
||||
free_ixs : SmallVec<[Index; 128]>,
|
||||
}
|
||||
|
||||
pub type Ix = usize;
|
||||
pub type Iter <'t, T> = FilterMap<slice::Iter <'t, Option<T>>, OptionAsRef <T>>;
|
||||
pub type IterMut <'t, T> = FilterMap<slice::IterMut<'t, Option<T>>, OptionAsRefMut<T>>;
|
||||
pub type OptionAsRef <T> = for<'r> fn(&'r Option<T>) -> Option<&'r T>;
|
||||
pub type OptionAsRefMut <T> = for<'r> fn(&'r mut Option<T>) -> Option<&'r mut T>;
|
||||
|
||||
impl<T> OptVec<T> {
|
||||
// === Types ===
|
||||
|
||||
/// A trait for any vector index type.
|
||||
pub trait Index = Debug + Copy + Into<usize> where usize : Into<Self>;
|
||||
|
||||
/// Iterator type of this vector.
|
||||
pub type Iter<'t,T> = FilterMap<slice::Iter<'t,Option<T>>, OptionAsRef<T>>;
|
||||
|
||||
/// Mutable iterator type of this vector.
|
||||
pub type IterMut<'t,T> = FilterMap<slice::IterMut<'t, Option<T>>, OptionAsRefMut<T>>;
|
||||
|
||||
/// Subtype of `Iter`.
|
||||
pub type OptionAsRef <T> = for<'r> fn(&'r Option<T>) -> Option<&'r T>;
|
||||
|
||||
/// Subtype of `IterMut`.
|
||||
pub type OptionAsRefMut <T> = for<'r> fn(&'r mut Option<T>) -> Option<&'r mut T>;
|
||||
|
||||
|
||||
// === Construction ===
|
||||
|
||||
impl<T,I:Index> OptVec<T,I> {
|
||||
/// Constructs a new, empty `Vec<T>`. It will not allocate until elements are pushed onto it.
|
||||
pub fn new() -> Self {
|
||||
default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts the provided element to the vector. It reuses free indexes if any.
|
||||
pub fn insert(&mut self, item: T) -> Ix {
|
||||
self.insert_with_ix(|_| item)
|
||||
}
|
||||
|
||||
/// Iterator.
|
||||
pub fn iter(&self) -> Iter<T> {
|
||||
self.items.iter().filter_map(Option::as_ref)
|
||||
}
|
||||
|
||||
/// Mutable iterator.
|
||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
||||
self.items.iter_mut().filter_map(Option::as_mut)
|
||||
}
|
||||
|
||||
/// Finds a free index and inserts the element. The index is re-used in case the array is sparse
|
||||
/// or is added in case of no free places.
|
||||
pub fn insert_with_ix<F: FnOnce(Ix) -> T>(&mut self, f: F) -> Ix {
|
||||
match self.free_ixs.pop() {
|
||||
None => {
|
||||
let ix = self.items.len();
|
||||
self.items.push(Some(f(ix)));
|
||||
ix
|
||||
}
|
||||
Some(ix) => {
|
||||
self.items[ix] = Some(f(ix));
|
||||
ix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserve an index for further reuse. Please remember that you cannot use the index to read
|
||||
/// values unless the value is set.
|
||||
pub fn reserve_ix(&mut self) -> Ix {
|
||||
self.free_ixs.pop().unwrap_or_else(|| {
|
||||
let ix = self.items.len();
|
||||
self.items.push(None);
|
||||
ix
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets the value at given index. Panics if the index was already freed.
|
||||
pub fn set(&mut self, ix:Ix, t:T) {
|
||||
self.items[ix] = Some(t);
|
||||
}
|
||||
|
||||
/// Removes the element at provided index and marks the index to be reused. Does nothing if the
|
||||
/// index was already empty. Panics if the index was out of bounds.
|
||||
pub fn remove(&mut self, ix: Ix) -> Option<T> {
|
||||
let item = self.items[ix].take();
|
||||
item.iter().for_each(|_| self.free_ixs.push(ix));
|
||||
item
|
||||
}
|
||||
// === Status Checks ===
|
||||
|
||||
impl<T,I:Index> OptVec<T,I> {
|
||||
/// Returns the number of elements in the vector, including reserved indexes. Also referred to
|
||||
/// as its 'length'.
|
||||
pub fn len(&self) -> usize {
|
||||
@ -98,35 +70,110 @@ impl<T> OptVec<T> {
|
||||
}
|
||||
|
||||
|
||||
// === Indexing ===
|
||||
// === Modifiers ===
|
||||
|
||||
impl<T> Index<usize> for OptVec<T> {
|
||||
type Output = T;
|
||||
fn index(&self, ix: usize) -> &Self::Output {
|
||||
self.items.index(ix).as_ref().unwrap()
|
||||
impl<T,I:Index> OptVec<T,I> {
|
||||
/// Inserts the provided element to the vector. It reuses free indexes if any.
|
||||
pub fn insert(&mut self, item: T) -> I {
|
||||
self.insert_with_ix(|_| item)
|
||||
}
|
||||
|
||||
/// Finds a free index and inserts the element. The index is re-used in case the array is sparse
|
||||
/// or is added in case of no free places.
|
||||
pub fn insert_with_ix<F:FnOnce(I) -> T>(&mut self, f: F) -> I {
|
||||
match self.free_ixs.pop() {
|
||||
None => {
|
||||
let index = self.items.len().into();
|
||||
self.items.push(Some(f(index)));
|
||||
index
|
||||
}
|
||||
Some(index) => {
|
||||
self.items[index.into()] = Some(f(index));
|
||||
index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserve an index for further reuse. Please remember that you cannot use the index to read
|
||||
/// values unless the value is set.
|
||||
pub fn reserve_index(&mut self) -> I {
|
||||
self.free_ixs.pop().unwrap_or_else(|| {
|
||||
let index = self.items.len().into();
|
||||
self.items.push(None);
|
||||
index
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets the value at given index. Panics if the index was already freed.
|
||||
pub fn set(&mut self, index:I, t:T) {
|
||||
self.items[index.into()] = Some(t);
|
||||
}
|
||||
|
||||
/// Removes the element at provided index and marks the index to be reused. Does nothing if the
|
||||
/// index was already empty. Panics if the index was out of bounds.
|
||||
pub fn remove(&mut self, index:I) -> Option<T> {
|
||||
let item = self.items[index.into()].take();
|
||||
item.iter().for_each(|_| self.free_ixs.push(index));
|
||||
item
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IndexMut<usize> for OptVec<T> {
|
||||
fn index_mut(&mut self, ix: usize) -> &mut Self::Output {
|
||||
self.items.index_mut(ix).as_mut().unwrap()
|
||||
|
||||
// === Indexing ===
|
||||
|
||||
impl<T,I:Index> OptVec<T,I> {
|
||||
/// Index into vector. Returns `None` if the key was already freed.
|
||||
pub fn safe_index(&self, index:I) -> Option<&T> {
|
||||
self.items[index.into()].as_ref()
|
||||
}
|
||||
|
||||
/// Index into vector. Returns `None` if the key was already freed.
|
||||
pub fn safe_index_mut(&mut self, index:I) -> Option<&mut T> {
|
||||
self.items[index.into()].as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T,I:Index> std::ops::Index<I> for OptVec<T,I> {
|
||||
type Output = T;
|
||||
fn index(&self, index:I) -> &Self::Output {
|
||||
let error = || panic!(format!("Trying to access removed index `{:?}`.",index));
|
||||
self.items.index(index.into()).as_ref().unwrap_or_else(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T,I:Index> std::ops::IndexMut<I> for OptVec<T,I> {
|
||||
fn index_mut(&mut self, index:I) -> &mut Self::Output {
|
||||
let error = || panic!(format!("Trying to access removed index `{:?}`.",index));
|
||||
self.items.index_mut(index.into()).as_mut().unwrap_or_else(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// === Iterators ===
|
||||
|
||||
impl<'a, T> IntoIterator for &'a OptVec<T> {
|
||||
impl<T,I:Index> OptVec<T,I> {
|
||||
/// Iterator.
|
||||
pub fn iter(&self) -> Iter<T> {
|
||||
self.items.iter().filter_map(Option::as_ref)
|
||||
}
|
||||
|
||||
/// Mutable iterator.
|
||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
||||
self.items.iter_mut().filter_map(Option::as_mut)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,T,I:Index> IntoIterator for &'a OptVec<T,I> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = Iter<'a, T>;
|
||||
type IntoIter = Iter<'a,T>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a mut OptVec<T> {
|
||||
impl<'a,T,I:Index> IntoIterator for &'a mut OptVec<T,I> {
|
||||
type Item = &'a mut T;
|
||||
type IntoIter = IterMut<'a, T>;
|
||||
type IntoIter = IterMut<'a,T>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter_mut()
|
||||
}
|
||||
@ -144,7 +191,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
let mut v = OptVec::new();
|
||||
let mut v = OptVec::<usize>::new();
|
||||
assert!(v.is_empty());
|
||||
|
||||
let ix1 = v.insert(1);
|
||||
@ -174,7 +221,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let mut v = OptVec::new();
|
||||
let mut v = OptVec::<usize>::new();
|
||||
|
||||
let ix1 = v.insert(0);
|
||||
let _ix2 = v.insert(1);
|
||||
@ -194,7 +241,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_iter_mut() {
|
||||
let mut v = OptVec::new();
|
||||
let mut v = OptVec::<usize>::new();
|
||||
|
||||
let ix1 = v.insert(0);
|
||||
let _ix2 = v.insert(1);
|
||||
|
@ -13,6 +13,8 @@ use graph_editor::GraphEditor;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use ensogl::display::object::ObjectOps;
|
||||
|
||||
use ensogl::display::style;
|
||||
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[allow(dead_code)]
|
||||
@ -53,4 +55,6 @@ fn init(app:&Application) {
|
||||
}
|
||||
was_rendered = true;
|
||||
}).forget();
|
||||
|
||||
style::test();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user