mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 13:30:24 +08:00
update MVS Stories app and deploy scripts (#1574)
* update MVS Stories app and deploy scripts * reorder changelog
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
build/
|
build/
|
||||||
|
deploy/
|
||||||
lib/
|
lib/
|
||||||
docs/site/
|
docs/site/
|
||||||
|
|
||||||
|
|||||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file, following t
|
|||||||
Note that since we don't clearly distinguish between a public and private interfaces there will be changes in non-major versions that are potentially breaking. If we make breaking changes to less used interfaces we will highlight it in here.
|
Note that since we don't clearly distinguish between a public and private interfaces there will be changes in non-major versions that are potentially breaking. If we make breaking changes to less used interfaces we will highlight it in here.
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
- [Breaking] Renamed some color schemes ('inferno' -> 'inferno-no-black', 'magma' -> 'magma-no-black', 'turbo' -> 'turbo-no-black', 'rainbow' -> 'simple-rainbow')
|
||||||
|
- [Breaking] `Box3D.nearestIntersectionWithRay` -> `nearestIntersectionWithRay3D` (use `Ray3D`)
|
||||||
|
- [Breaking] `Plane3D.distanceToSpher3D` -> `distanceToSphere3D` (fix spelling)
|
||||||
|
- [Breaking] fix typo `MarchinCubes` -> `MarchingCubes`
|
||||||
|
- [Breaking] `PluginContext.initViewer/initContainer/mount` are now async and have been renamed to include `Async` postfix
|
||||||
|
- [Breaking] Add `Volume.instances` support and a `VolumeInstances` transform to dynamically assign it
|
||||||
|
- This change is breaking because all volume objects require the `instances` field now.
|
||||||
- Update production build to use `esbuild`
|
- Update production build to use `esbuild`
|
||||||
- Emit explicit paths in `import`s in `lib/`
|
- Emit explicit paths in `import`s in `lib/`
|
||||||
- Fix outlines on opaque elements using illumination mode
|
- Fix outlines on opaque elements using illumination mode
|
||||||
@@ -21,7 +28,6 @@ Note that since we don't clearly distinguish between a public and private interf
|
|||||||
- Support `matrix` on transform params
|
- Support `matrix` on transform params
|
||||||
- Add `instance` node type
|
- Add `instance` node type
|
||||||
- Support transforming and instancing of structures, components, and volumes
|
- Support transforming and instancing of structures, components, and volumes
|
||||||
- [Breaking] Renamed some color schemes ('inferno' -> 'inferno-no-black', 'magma' -> 'magma-no-black', 'turbo' -> 'turbo-no-black', 'rainbow' -> 'simple-rainbow')
|
|
||||||
- Added new color schemes, synchronized with D3.js ('inferno', 'magma', 'turbo', 'rainbow', 'sinebow', 'warm', 'cool', 'cubehelix-default', 'category-10', 'observable-10', 'tableau-10')
|
- Added new color schemes, synchronized with D3.js ('inferno', 'magma', 'turbo', 'rainbow', 'sinebow', 'warm', 'cool', 'cubehelix-default', 'category-10', 'observable-10', 'tableau-10')
|
||||||
- Snapshot Markdown improvements
|
- Snapshot Markdown improvements
|
||||||
- Add `MarkdownExtensionManager` (`PluginContext.managers.markdownExtensions`)
|
- Add `MarkdownExtensionManager` (`PluginContext.managers.markdownExtensions`)
|
||||||
@@ -34,21 +40,16 @@ Note that since we don't clearly distinguish between a public and private interf
|
|||||||
- Fix isosurface compute shader normals when transformation matrix is applied to volume
|
- Fix isosurface compute shader normals when transformation matrix is applied to volume
|
||||||
- Symmetry operator naming for spacegroup symmetry - parenthesize multi-character indices (1_111-1 -> 1_(11)1(-1))
|
- Symmetry operator naming for spacegroup symmetry - parenthesize multi-character indices (1_111-1 -> 1_(11)1(-1))
|
||||||
- Add `SymmetryOperator.instanceId` that corresponds to a canonical operator name (e.g. ASM-1, ASM-X0-1 for assemblies, 1_555, 1_(11)1(-1) for crystals)
|
- Add `SymmetryOperator.instanceId` that corresponds to a canonical operator name (e.g. ASM-1, ASM-X0-1 for assemblies, 1_555, 1_(11)1(-1) for crystals)
|
||||||
- [Breaking] `PluginContext.initViewer/initContainer/mount` are now async and have been renamed to include `Async` postfix
|
|
||||||
- Mol2 Reader
|
- Mol2 Reader
|
||||||
- Fix column count parsing
|
- Fix column count parsing
|
||||||
- Add support for substructure
|
- Add support for substructure
|
||||||
- Fix shader error when clipping flags are set without clip objects present
|
- Fix shader error when clipping flags are set without clip objects present
|
||||||
- [Breaking] Add `Volume.instances` support and a `VolumeInstances` transform to dynamically assign it
|
|
||||||
- This change is breaking because all volume objects require the `instances` field now.
|
|
||||||
- Fix wrong group count calculation on geometry update (#1562)
|
- Fix wrong group count calculation on geometry update (#1562)
|
||||||
- Fix wrong instance index in `calcMeshColorSmoothing`
|
- Fix wrong instance index in `calcMeshColorSmoothing`
|
||||||
- Add `Ray3D` object and helpers
|
- Add `Ray3D` object and helpers
|
||||||
- [Breaking] `Box3D.nearestIntersectionWithRay` -> `nearestIntersectionWithRay3D` (use `Ray3D`)
|
|
||||||
- [Breaking] `Plane3D.distanceToSpher3D` -> `distanceToSphere3D` (fix spelling)
|
|
||||||
- [Breaking] fix typo `MarchinCubes` -> `MarchingCubes`
|
|
||||||
- Volume slice representation: add `relativeX/Y/Z` options for dimension
|
- Volume slice representation: add `relativeX/Y/Z` options for dimension
|
||||||
- Add `StructureInstances` transform
|
- Add `StructureInstances` transform
|
||||||
|
- Add `story-id` URL arg support to `mvs-stories` app
|
||||||
|
|
||||||
## [v4.18.0] - 2025-06-08
|
## [v4.18.0] - 2025-06-08
|
||||||
- MolViewSpec extension:
|
- MolViewSpec extension:
|
||||||
|
|||||||
@@ -190,9 +190,14 @@ To get syntax highlighting for shader files add the following to Visual Code's s
|
|||||||
npm publish
|
npm publish
|
||||||
|
|
||||||
## Deploy
|
## Deploy
|
||||||
|
To prepare apps and demos for https://molstar.org deploy, run:
|
||||||
|
|
||||||
npm run test
|
npm run test
|
||||||
npm run build
|
npm run deploy:local
|
||||||
node ./scripts/deploy.js # currently updates the viewer on molstar.org/viewer
|
|
||||||
|
To commit these changes remotely to the `molstar/molstar.github.io` repo:
|
||||||
|
|
||||||
|
npm run deploy:remote
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Just open an issue or make a pull request. All contributions are welcome.
|
Just open an issue or make a pull request. All contributions are welcome.
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
"lint-fix": "eslint . --fix",
|
"lint-fix": "eslint . --fix",
|
||||||
"test": "npm install --no-save \"gl@^6.0.2\" && npm run lint && jest",
|
"test": "npm install --no-save \"gl@^6.0.2\" && npm run lint && jest",
|
||||||
"jest": "jest",
|
"jest": "jest",
|
||||||
"clean": "node ./scripts/clean.js",
|
"clean": "node ./scripts/clean.js --all",
|
||||||
|
"clean:build": "node ./scripts/clean.js --build",
|
||||||
"build": "npm run build:apps && npm run build:lib",
|
"build": "npm run build:apps && npm run build:lib",
|
||||||
"build:apps": "node ./scripts/build.mjs -a -e --prd",
|
"build:apps": "node ./scripts/build.mjs -a -e --prd",
|
||||||
"build:lib": "concurrently \"tsc --incremental\" \"tsc --build tsconfig.commonjs.json --incremental\" && npm run build:lib-extra",
|
"build:lib": "concurrently \"tsc --incremental\" \"tsc --build tsconfig.commonjs.json --incremental\" && npm run build:lib-extra",
|
||||||
@@ -31,6 +32,8 @@
|
|||||||
"dev:examples": "node ./scripts/build.mjs -e",
|
"dev:examples": "node ./scripts/build.mjs -e",
|
||||||
"dev:browser-tests": "node ./scripts/build.mjs -bt",
|
"dev:browser-tests": "node ./scripts/build.mjs -bt",
|
||||||
"serve": "http-server -p 1338 -g",
|
"serve": "http-server -p 1338 -g",
|
||||||
|
"deploy:local": "npm run clean:build && npm run build:apps && node ./scripts/deploy.js --local",
|
||||||
|
"deploy:remote": "npm run clean:build && npm run build:apps && node ./scripts/deploy.js",
|
||||||
"model-server": "node lib/commonjs/servers/model/server.js",
|
"model-server": "node lib/commonjs/servers/model/server.js",
|
||||||
"model-server-watch": "nodemon --watch lib lib/commonjs/servers/model/server.js",
|
"model-server-watch": "nodemon --watch lib lib/commonjs/servers/model/server.js",
|
||||||
"volume-server-test": "node lib/commonjs/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
|
"volume-server-test": "node lib/commonjs/servers/volume/server.js --idMap em 'test/${id}.mdb' --defaultPort 1336",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const argparse = require('argparse');
|
||||||
|
|
||||||
function removeDir(dirPath) {
|
function removeDir(dirPath) {
|
||||||
for (const ent of fs.readdirSync(dirPath)) {
|
for (const ent of fs.readdirSync(dirPath)) {
|
||||||
@@ -24,11 +25,29 @@ function remove(entryPath) {
|
|||||||
fs.unlinkSync(entryPath);
|
fs.unlinkSync(entryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const toClean = [
|
const argParser = new argparse.ArgumentParser({
|
||||||
path.resolve(__dirname, '../build'),
|
add_help: true,
|
||||||
path.resolve(__dirname, '../lib'),
|
description: 'Clean Script'
|
||||||
path.resolve(__dirname, '../tsconfig.tsbuildinfo'),
|
});
|
||||||
];
|
argParser.add_argument('--build', { required: false, action: 'store_true' });
|
||||||
|
argParser.add_argument('--lib', { required: false, action: 'store_true' });
|
||||||
|
argParser.add_argument('--all', { required: false, action: 'store_true' });
|
||||||
|
const args = argParser.parse_args();
|
||||||
|
|
||||||
|
const toClean = [];
|
||||||
|
|
||||||
|
if (args.build || args.all) {
|
||||||
|
toClean.push(path.resolve(__dirname, '../build'));
|
||||||
|
toClean.push(path.resolve(__dirname, '../deploy/data'));
|
||||||
|
}
|
||||||
|
if (args.lib || args.all) {
|
||||||
|
toClean.push(
|
||||||
|
path.resolve(__dirname, '../lib'),
|
||||||
|
path.resolve(__dirname, '../tsconfig.tsbuildinfo'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('\n###', 'cleaning', toClean.join(', '));
|
||||||
|
|
||||||
toClean.forEach(ph => {
|
toClean.forEach(ph => {
|
||||||
if (fs.existsSync(ph)) {
|
if (fs.existsSync(ph)) {
|
||||||
|
|||||||
@@ -2,20 +2,24 @@
|
|||||||
* Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
* Copyright (c) 2019-2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||||
*
|
*
|
||||||
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
||||||
|
* @author David Sehnal <david.sehnal@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const git = require('simple-git');
|
const git = require('simple-git');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const fse = require("fs-extra");
|
const fse = require("fs-extra");
|
||||||
|
const argparse = require('argparse');
|
||||||
|
|
||||||
const VERSION = require(path.resolve(__dirname, '../package.json')).version;
|
const VERSION = require(path.resolve(__dirname, '../package.json')).version;
|
||||||
|
const MVS_STORIES_VERSION = require(path.resolve(__dirname, '../src/apps/mvs-stories/version.ts')).VERSION;
|
||||||
|
|
||||||
const remoteUrl = "https://github.com/molstar/molstar.github.io.git";
|
const remoteUrl = "https://github.com/molstar/molstar.github.io.git";
|
||||||
const dataDir = path.resolve(__dirname, '../data/');
|
const dataDir = path.resolve(__dirname, '../data/');
|
||||||
const buildDir = path.resolve(__dirname, '../build/');
|
const buildDir = path.resolve(__dirname, '../build/');
|
||||||
const deployDir = path.resolve(buildDir, 'deploy/');
|
const deployDir = path.resolve(__dirname, '../deploy/');
|
||||||
const localPath = path.resolve(deployDir, 'molstar.github.io/');
|
const localPath = path.resolve(deployDir, 'data/');
|
||||||
|
const repositoryPath = path.resolve(deployDir, 'molstar.github.io/');
|
||||||
|
|
||||||
const analyticsTag = /<!-- __MOLSTAR_ANALYTICS__ -->/g;
|
const analyticsTag = /<!-- __MOLSTAR_ANALYTICS__ -->/g;
|
||||||
const analyticsCode = `<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "c414cbae2d284ea995171a81e4a3e721"}'></script><!-- End Cloudflare Web Analytics --><iframe src="https://web3dsurvey.com/collector-iframe.html" style="width: 1px; height: 1px;"></iframe>`;
|
const analyticsCode = `<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "c414cbae2d284ea995171a81e4a3e721"}'></script><!-- End Cloudflare Web Analytics --><iframe src="https://web3dsurvey.com/collector-iframe.html" style="width: 1px; height: 1px;"></iframe>`;
|
||||||
@@ -80,54 +84,106 @@ function copyMe() {
|
|||||||
addAnalytics(path.resolve(meDeployPath, 'index.html'));
|
addAnalytics(path.resolve(meDeployPath, 'index.html'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyMVSStories() {
|
||||||
|
console.log('\n###', 'copy MVS stories files');
|
||||||
|
const mvsStoriesBuildPath = path.resolve(buildDir, 'mvs-stories/');
|
||||||
|
const mvsStoriesDeployPath = path.resolve(localPath, `stories-viewer/v${MVS_STORIES_VERSION}/`);
|
||||||
|
fse.copySync(mvsStoriesBuildPath, mvsStoriesDeployPath, { overwrite: true });
|
||||||
|
addAnalytics(path.resolve(mvsStoriesDeployPath, 'index.html'));
|
||||||
|
|
||||||
|
// TODO: add PWA
|
||||||
|
// addManifest(path.resolve(mvsStoriesDeployPath, 'index.html'));
|
||||||
|
// addPwa(path.resolve(mvsStoriesDeployPath, 'index.html'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyDemo(name) {
|
||||||
|
console.log('\n###', `copy demo files for ${name}`);
|
||||||
|
const demoBuildPath = path.resolve(buildDir, `examples/${name}/`);
|
||||||
|
const demoDeployPath = path.resolve(localPath, `demos/${name}/`);
|
||||||
|
fse.copySync(demoBuildPath, demoDeployPath, { overwrite: true });
|
||||||
|
addAnalytics(path.resolve(demoDeployPath, 'index.html'));
|
||||||
|
}
|
||||||
|
|
||||||
function copyDemos() {
|
function copyDemos() {
|
||||||
console.log('\n###', 'copy demos files');
|
console.log('\n###', 'copy demos files');
|
||||||
const lightingBuildPath = path.resolve(buildDir, 'examples/lighting/');
|
copyDemo('lighting');
|
||||||
const lightingDeployPath = path.resolve(localPath, 'demos/lighting/');
|
copyDemo('alpha-orbitals');
|
||||||
fse.copySync(lightingBuildPath, lightingDeployPath, { overwrite: true });
|
copyDemo('mvs-stories');
|
||||||
addAnalytics(path.resolve(lightingDeployPath, 'index.html'));
|
|
||||||
|
|
||||||
const orbitalsBuildPath = path.resolve(buildDir, 'examples/alpha-orbitals/');
|
|
||||||
const orbitalsDeployPath = path.resolve(localPath, 'demos/alpha-orbitals/');
|
|
||||||
fse.copySync(orbitalsBuildPath, orbitalsDeployPath, { overwrite: true });
|
|
||||||
addAnalytics(path.resolve(orbitalsDeployPath, 'index.html'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyFiles() {
|
function copyFiles() {
|
||||||
try {
|
try {
|
||||||
copyViewer();
|
copyViewer();
|
||||||
copyMe();
|
copyMe();
|
||||||
|
copyMVSStories();
|
||||||
copyDemos();
|
copyDemos();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function copyToRepository() {
|
||||||
|
console.log('\n###', 'copy repository files');
|
||||||
|
fse.copySync(localPath, repositoryPath, { overwrite: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncRepository() {
|
||||||
|
console.log('\n###', 'sync repository');
|
||||||
|
if (!fs.existsSync(path.resolve(repositoryPath, '.git/'))) {
|
||||||
|
console.log('\n###', 'clone repository');
|
||||||
|
git()
|
||||||
|
.outputHandler(log)
|
||||||
|
.clone(remoteUrl, repositoryPath)
|
||||||
|
.fetch(['--all'])
|
||||||
|
.exec(copyToRepository);
|
||||||
|
} else {
|
||||||
|
console.log('\n###', 'update repository');
|
||||||
|
git()
|
||||||
|
.outputHandler(log)
|
||||||
|
.fetch(['--all'])
|
||||||
|
.reset(['--hard', 'origin/master'])
|
||||||
|
.exec(copyToRepository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function commit() {
|
||||||
|
console.log('\n###', 'commit changes');
|
||||||
|
git()
|
||||||
|
.outputHandler(log)
|
||||||
|
.add(['-A'])
|
||||||
|
.commit(`Updated Apps and Demos
|
||||||
|
- Mol* version: ${VERSION}
|
||||||
|
- MVS Stories version: ${MVS_STORIES_VERSION}`)
|
||||||
|
.push();
|
||||||
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(localPath)) {
|
if (!fs.existsSync(localPath)) {
|
||||||
console.log('\n###', 'create localPath');
|
console.log('\n###', 'create localPath');
|
||||||
fs.mkdirSync(localPath, { recursive: true });
|
fs.mkdirSync(localPath, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
process.chdir(localPath);
|
const argParser = new argparse.ArgumentParser({
|
||||||
|
add_help: true,
|
||||||
|
description: 'Mol* Deploy'
|
||||||
|
});
|
||||||
|
argParser.add_argument('--local',{
|
||||||
|
help: 'Do not commit to remote repository.',
|
||||||
|
required: false,
|
||||||
|
action: 'store_true',
|
||||||
|
});
|
||||||
|
const args = argParser.parse_args();
|
||||||
|
|
||||||
if (!fs.existsSync(path.resolve(localPath, '.git/'))) {
|
copyFiles();
|
||||||
console.log('\n###', 'clone repository');
|
|
||||||
git()
|
if (args.local) {
|
||||||
.outputHandler(log)
|
process.exit(0);
|
||||||
.clone(remoteUrl, localPath)
|
}
|
||||||
.fetch(['--all'])
|
|
||||||
.exec(copyFiles)
|
if (!fs.existsSync(repositoryPath)) {
|
||||||
.add(['-A'])
|
console.log('\n###', 'create repositoryPath');
|
||||||
.commit('updated viewer & demos')
|
fs.mkdirSync(repositoryPath, { recursive: true });
|
||||||
.push();
|
}
|
||||||
} else {
|
|
||||||
console.log('\n###', 'update repository');
|
process.chdir(repositoryPath);
|
||||||
git()
|
syncRepository();
|
||||||
.outputHandler(log)
|
commit();
|
||||||
.fetch(['--all'])
|
|
||||||
.reset(['--hard', 'origin/master'])
|
|
||||||
.exec(copyFiles)
|
|
||||||
.add(['-A'])
|
|
||||||
.commit('updated viewer & demos')
|
|
||||||
.push();
|
|
||||||
}
|
|
||||||
@@ -76,6 +76,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
var urlParams = new URLSearchParams(window.location.search);
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
|
var storyId = urlParams.get('story-id');
|
||||||
var storyUrl = urlParams.get('story-url');
|
var storyUrl = urlParams.get('story-url');
|
||||||
var format = urlParams.get('data-format');
|
var format = urlParams.get('data-format');
|
||||||
|
|
||||||
@@ -84,11 +85,13 @@
|
|||||||
// storyUrl = 'https://raw.githubusercontent.com/molstar/molstar/master/examples/mvs/kinase-story.mvsj';
|
// storyUrl = 'https://raw.githubusercontent.com/molstar/molstar/master/examples/mvs/kinase-story.mvsj';
|
||||||
// }
|
// }
|
||||||
|
|
||||||
mvsStories.loadFromURL(
|
if (storyId) {
|
||||||
storyUrl,
|
mvsStories.loadFromID(storyId, { contextName: 'story1' });
|
||||||
{ format: format || 'mvsj', contextName: 'story1' },
|
} else if (storyUrl) {
|
||||||
);
|
mvsStories.loadFromURL(storyUrl, { format: format || 'mvsj', contextName: 'story1' });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<!-- __MOLSTAR_ANALYTICS__ -->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -37,4 +37,15 @@ export function loadFromData(data: MVSData | string | Uint8Array, options?: { fo
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStoryUrlFromId(id: string, format: 'mvsx' | 'mvsj' = 'mvsj') {
|
||||||
|
return `https://stories.molstar.org/api/story/${id}/data`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadFromID(id: string, options?: { format?: 'mvsx' | 'mvsj', contextName?: string }) {
|
||||||
|
loadFromURL(
|
||||||
|
getStoryUrlFromId(id, options?.format),
|
||||||
|
{ format: options?.format ?? 'mvsj', contextName: options?.contextName },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { MVSData };
|
export { MVSData };
|
||||||
7
src/apps/mvs-stories/version.ts
Normal file
7
src/apps/mvs-stories/version.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||||
|
*
|
||||||
|
* @author David Sehnal <david.sehnal@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const VERSION = 1;
|
||||||
@@ -118,6 +118,7 @@
|
|||||||
window.initStories();
|
window.initStories();
|
||||||
}, 0);
|
}, 0);
|
||||||
</script>
|
</script>
|
||||||
|
<!-- __MOLSTAR_ANALYTICS__ -->
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user