diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..7745062
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* -text
diff --git a/.github/workflows/deploy-to-gh-pages.yml b/.github/workflows/deploy-to-gh-pages.yml
new file mode 100644
index 0000000..1fab66e
--- /dev/null
+++ b/.github/workflows/deploy-to-gh-pages.yml
@@ -0,0 +1,23 @@
+name: build demo
+
+on:
+ workflow_dispatch:
+ push:
+ pull_request:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+
+ - uses: hyoo-ru/mam_build@master2
+ with:
+ package: optimade/tmdne
+ modules: app
+
+ - uses: JamesIves/github-pages-deploy-action@4.1.7
+ with:
+ branch: gh-pages
+ folder: optimade/tmdne/app/-
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e3e8fe6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+-*
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 16a0d37..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,6 +0,0 @@
-from python:3.11-slim-buster
-
-copy . /app
-workdir /app
-run pip install -r requirements.txt
-cmd gunicorn src.this_material_does_not_exist.app:server -b 0.0.0.0:8050
diff --git a/LICENSE b/LICENSE
index c7c2544..0d0e9f4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,21 @@
-MIT License
-
-Copyright (c) 2023 Matthew Evans
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+MIT License
+
+Copyright (c) 2023 Matthew Evans
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index a81ec6f..65e29ef 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,38 @@
-
+
Get given random crystal structures predicted by ML materials discovery projects, and vote on whether you think it should be synthesizable (or, at least, whether it is worth trying!)
-Currently uses [crystaltoolkit](https://docs.crystaltoolkit.org) and data from the
+Currently uses [cifplayer](https://github.com/tilde-lab/cifplayer) and data from the
[OPTIMADE API](https://optimade.org) for the recent [Google DeepMind
paper](https://github.com/google-deepmind/materials_discovery).
+The physical properties prediction is done dynamically by [MPDS ML server](https://mpds.io/ml).
-
+
+
+
+## Build
+
+The `cifplayer` is powered by `$mol` framework. Note that, unlike many other frontend frameworks, `$mol` provides the same single environment for all its projects, under the standard namespace scheme. That is, all your `$mol`-based code lives inside the same directory `$MOL_HOME`. So if you don't have `$MOL_HOME` yet, please create it and navigate there
+
+```bash
+mkdir $MOL_HOME && cd $MOL_HOME
+```
+
+Then build with
+
+```bash
+npm exec mam optimade/tmdne/app
+```
+
+This will fetch the MAM server (MAM stands for the `$mol` abstract modules), clone this project, and compile it inside `optimade/tmdne/app/-/` subfolder. You will need the `web.js` bundle, that's it.
+
+
+## Develop
+
+Similarly to above, inside the `$MOL_HOME`, start the MAM dev-server with
+
+```bash
+npm exec mam
+```
+
+and navigate to http://localhost:9080, there select `optimade` namespace, then `tmdne`, then `app`. As you go through the folder structure, the selected project is being cloned and compiled on the fly, inside the corresponding subfolder of `$MOL_HOME`.
diff --git a/app/app.view.css b/app/app.view.css
new file mode 100644
index 0000000..6a11ea7
--- /dev/null
+++ b/app/app.view.css
@@ -0,0 +1,8 @@
+@media all and (max-width: 850px) {
+ [optimade_tmdne_app_param_mae], [optimade_tmdne_app_param_name] { display: none; }
+ [optimade_tmdne_app_acks] { display: none; }
+}
+
+@media all and (max-height: 650px) {
+ [optimade_tmdne_app_prediction] { display: none; }
+}
diff --git a/app/app.view.css.ts b/app/app.view.css.ts
new file mode 100644
index 0000000..31010bc
--- /dev/null
+++ b/app/app.view.css.ts
@@ -0,0 +1,151 @@
+namespace $.$$ {
+
+ $mol_style_define( $optimade_tmdne_app, {
+
+ overflow: 'hidden',
+ flex: {
+ direction: 'column',
+ },
+ align: {
+ items: 'center',
+ },
+
+ Player: {
+ flex: {
+ grow: 1,
+ },
+ width: '100%',
+ opacity: 1,
+ transition: 'opacity 0.15s',
+ '[optimade_tmdne_app_player_hidden]': {
+ 'true': {
+ opacity: 0.1,
+ },
+ },
+ },
+
+ Head_space: {
+ position: 'absolute',
+ top: $mol_gap.block,
+ left: 0,
+ right: 0,
+ flex: {
+ grow: 1,
+ },
+ pointerEvents: 'none',
+ },
+
+ Head_card: {
+ pointerEvents: 'auto',
+ margin: 'auto',
+ width: '35%',
+ textAlign: 'center',
+ },
+
+ Head_title: {
+ userSelect: 'none',
+ justify: {
+ content: 'center',
+ },
+ font: {
+ size: '1.2rem',
+ },
+ },
+
+ Prediction: {
+ userSelect: 'none',
+ font: {
+ size: '0.7rem',
+ },
+ lineHeight: '16px',
+ flex: {
+ grow: 0,
+ wrap: 'wrap',
+ },
+ position: 'absolute',
+ left: $mol_gap.block,
+ bottom: '11rem',
+ pointerEvents: 'none',
+ opacity: 1,
+ transition: 'opacity 0.15s',
+ '[optimade_tmdne_app_prediction_hidden]': {
+ 'true': {
+ opacity: 0,
+ },
+ },
+ },
+
+ Param: {
+ gap: '0.3rem',
+ flex: {
+ wrap: 'wrap',
+ },
+ },
+
+ Param_name: {
+ font: {
+ weight: 700,
+ },
+ },
+
+ Param_symbol: {
+ flex: {
+ direction: 'row',
+ },
+ },
+
+ Param_unit: {
+ flex: {
+ direction: 'row',
+ },
+ },
+
+ Param_mae_unit: {
+ flex: {
+ direction: 'row',
+ },
+ },
+
+ Param_value: {
+ gap: '0.25rem',
+ },
+
+ Foot: {
+ justify: {
+ content: 'space-between',
+ },
+ width: '24rem',
+ position: 'absolute',
+ bottom: '5.3rem',
+
+ pointerEvents: 'none',
+ transition: 'opacity 0.2s',
+ opacity: 1,
+ '[optimade_tmdne_app_foot_hidden]': {
+ 'true': {
+ opacity: 0,
+ },
+ },
+ zIndex: 1,
+ },
+
+ Hint_no: {
+ pointerEvents: 'auto',
+ color: '#ff6666',
+ },
+
+ Hint_yes: {
+ pointerEvents: 'auto',
+ color: $mol_theme.current,
+ },
+
+ Acks: {
+ font: {
+ size: '0.7rem',
+ },
+ zIndex: 0,
+ },
+
+ } )
+
+}
diff --git a/app/app.view.tree b/app/app.view.tree
new file mode 100644
index 0000000..da5a6de
--- /dev/null
+++ b/app/app.view.tree
@@ -0,0 +1,92 @@
+$optimade_tmdne_app $mol_view
+ title \This Material Does Not Exist?
+ number? 1
+ plugins /
+ <= Theme $mol_theme_auto
+ rotating? false
+ number_swiped? 0
+ number_prefetch? 0
+ sub /
+ <= Player $optimade_cifplayer_player
+ fullscreen? => player_fullscreen?
+ attr *
+ fullscreen <= player_fullscreen?
+ optimade_tmdne_app_player_hidden <= card_holding
+ data <= json null
+ Fullscreen null
+ Overlays null
+ event *
+ pointerdown? <=> player_pointerdown? null
+ pointerup? <=> player_pointerup? null
+ <= Head_space $mol_view
+ sub /
+ <= Head_card $mol_list
+ sub /
+ <= Head_title $mol_paragraph
+ title \Does this material exist?
+ <= Prediction $mol_list
+ attr *
+ optimade_tmdne_app_prediction_hidden <= rotating
+ sub <= params /
+ <= Param* $mol_view
+ sub /
+ <= Param_name* $mol_paragraph
+ title <= param_name* \
+ <= Param_symbol* $mol_html_view
+ minimal_height <= param_min_height 22
+ html <= param_symbol* \
+ \=
+ <= Param_value* $mol_view
+ sub /
+ <= param_value* \
+ <= Param_unit* $mol_html_view
+ minimal_height <= param_min_height
+ html <= param_unit* \
+ <= Param_mae* $mol_view
+ sub /
+ \(±
+ <= param_mae* \
+ <= Param_mae_unit* $mol_html_view
+ minimal_height <= param_min_height
+ html <= param_unit* \
+ \)
+ <= Foot $mol_view
+ attr *
+ optimade_tmdne_app_foot_hidden <= rotating
+ sub /
+ <= Hint_no $mol_button_minor
+ title \ᐊ No
+ click? <=> click_no? null
+ <= Hint_yes $mol_button_minor
+ title \Yes ᐅ
+ click? <=> click_yes? null
+ ^ cards / <= Card* $optimade_tmdne_card
+ name <= card_name* \
+ loaded <= card_loaded* false
+ why? <=> why*? \
+ pointer_holding? <=> card_holding? false
+ swiped_to? <=> swiped_to*? \
+ swipe_to_right => swipe_to_right*
+ swipe_to_left => swipe_to_left*
+ <= Acks $mol_view
+ sub /
+ <= Acks_a $mol_link
+ uri \https://www.optimade.org
+ sub /
+ \Powered by Optimade
+ <= Acks_b $mol_link
+ uri \https://github.com/tilde-lab/cifplayer
+ sub /
+ \and cifplayer
+ <= Acks_c $mol_link
+ uri \https://github.com/google-deepmind/materials_discovery
+ sub /
+ \using the GNome dataset
+ <= Acks_d $mol_link
+ uri \https://github.com/ml-evs/this-material-does-not-exist
+ sub /
+ \developed on GitHub
+ <= Acks_e $mol_link
+ uri \https://thispersondoesnotexist.com
+ sub /
+ \and inspired by...
diff --git a/app/app.view.ts b/app/app.view.ts
new file mode 100644
index 0000000..425935f
--- /dev/null
+++ b/app/app.view.ts
@@ -0,0 +1,191 @@
+namespace $.$$ {
+
+ export class $optimade_tmdne_app extends $.$optimade_tmdne_app {
+
+ @ $mol_mem_key
+ fetch_by_number( number: number ) {
+ $mol_wire_solid()
+ return this.$.$mol_fetch.json( `https://optimade-gnome.odbx.science/v1/structures?page_limit=1&page_offset=${number}` ) as any
+ }
+
+ @ $mol_mem_key
+ predict_by_number( number: number ) {
+ $mol_wire_solid()
+
+ const structure = JSON.stringify( this.fetch_by_number( number ) )
+ const params = new URLSearchParams({ structure })
+ const url = `https://labs.mpds.io/predict`
+
+ const prediction = this.$.$mol_wire_sync( this ).$.$mol_fetch.success( url, {
+ method: 'post',
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: params.toString(),
+ } ).json() ?? {} as any
+
+ return prediction
+ }
+
+ @ $mol_mem
+ json() {
+ return this.fetch_by_number( this.number() )
+ }
+
+ @ $mol_mem_key
+ card_name( n: number ) {
+ const json = this.fetch_by_number( n )
+ let str = json?.data[ 0 ]?.attributes?.chemical_formula_reduced
+ return formula_html( str )
+ }
+
+ @ $mol_mem_key
+ card_loaded( n: number ) {
+ try {
+ this.card_name( n )
+ return this.number() === n
+ } catch (error) {
+ if( $mol_promise_like( error ) ) return false
+ }
+ return false
+ }
+
+ cards(): readonly ( any )[] {
+ const swiped = this.number_swiped()
+ return [
+ this.Card( this.number_prefetch() ),
+ ... swiped ? [ this.Card( swiped ) ] : [],
+ this.Card( this.number() ),
+ ]
+ }
+
+ @ $mol_action
+ random_sample() {
+ return random_int( 1, 384937 )
+ }
+
+ @ $mol_mem
+ number( next?: number ): number {
+ return next ?? this.random_sample()
+ }
+
+ @ $mol_mem
+ number_prefetch( next?: number ): number {
+ return next ?? this.random_sample()
+ }
+
+ @ $mol_action
+ update() {
+ this.number_swiped( this.number() )
+ this.number( this.number_prefetch() )
+ const prefetch = this.random_sample()
+ this.number_prefetch( prefetch )
+ $mol_wire_async( this ).predict_by_number( prefetch )
+ }
+
+ @ $mol_mem
+ predict() {
+ return this.predict_by_number( this.number() )
+ }
+
+ @ $mol_mem
+ params(): readonly any[] {
+ const keys = Object.keys( this.predict().prediction )
+ return keys.map( k => this.Param( k ) )
+ }
+
+ @ $mol_mem_key
+ param_value( id: any ): string {
+ return this.predict().prediction[id].value ?? ''
+ }
+
+ @ $mol_mem_key
+ param_mae( id: any ): string {
+ return this.predict().prediction[id].mae ?? ''
+ }
+
+ @ $mol_mem_key
+ param_name( id: any ): string {
+ return this.predict().legend[id].name ?? ''
+ }
+
+ @ $mol_mem_key
+ param_unit( id: any ): string {
+ return this.predict().legend[id].gui_units ?? ''
+ }
+
+ @ $mol_mem_key
+ param_symbol( id: any ): string {
+ return this.predict().legend[id].symbol ?? ''
+ }
+
+ player_pointerdown( next?: any ) {
+ this.rotating( true )
+ }
+
+ player_pointerup( next?: any ) {
+ this.rotating( false )
+ }
+
+ click_no() {
+ this.swipe_to_left( this.number() )
+ }
+
+ click_yes() {
+ this.swipe_to_right( this.number() )
+ }
+
+ @ $mol_mem_key
+ swiped_to( id: number, next?: string ) {
+
+ const vote = next == 'left' ? 0 : next == 'right' ? 1 : undefined
+ if( vote !== undefined ) {
+
+ this.update()
+ const params = new URLSearchParams( {
+ id: this.fetch_by_number( id )?.data[ 0 ]?.attributes?._gnome_material_id,
+ comment: this.why( id ),
+ vote: vote.toString(),
+ } )
+
+ this.$.$mol_fetch.success( 'https://crus.absolidix.com', {
+ method: 'post',
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ body: params.toString(),
+ } )
+
+ }
+
+ return next ?? ''
+ }
+
+ }
+
+ function random_int( min: number, max: number ) {
+ return Math.floor( Math.random() * ( max - min + 1 ) ) + min
+ }
+
+ function formula_html( str: string ) {
+ let sub = false
+ let html = ''
+ for( let i = 0; i < str.length; i++ ) {
+ if( !isNaN( +str[ i ] ) || str[ i ] == '.' ) {
+ if( !sub ) {
+ html += ''
+ sub = true
+ }
+ } else {
+ if( sub ) {
+ html += ''
+ sub = false
+ }
+ }
+ html += str[ i ]
+ }
+ if( sub ) html += ''
+ return html ?? ''
+ }
+
+}
diff --git a/app/index.html b/app/index.html
new file mode 100644
index 0000000..efcd8ed
--- /dev/null
+++ b/app/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/card/card.view.css.ts b/card/card.view.css.ts
new file mode 100644
index 0000000..0fb9d55
--- /dev/null
+++ b/card/card.view.css.ts
@@ -0,0 +1,113 @@
+namespace $.$$ {
+
+ $mol_style_define( $optimade_tmdne_card, {
+
+ pointerEvents: 'auto',
+ width: 'max-content',
+ position: 'fixed',
+ left: '50%',
+ transform: 'translateX(-50%)',
+ bottom: '1.6rem',
+ zIndex: 2,
+
+ // position: 'relative',
+ // left: 0,
+ // right: 0,
+ // width: '100%',
+ // margin: 'auto',
+ // overflow: 'hidden',
+ // flex: {
+ // grow: 1,
+ // },
+
+ padding: '0.5rem',
+ Float: {
+ margin: 'auto',
+ },
+
+ Card_float: {
+ background: {
+ color: $mol_theme.back,
+ },
+ transform: 'translateY(125%)',
+ transition: 'transform 0.7s',
+ '[loaded]': {
+ 'true': {
+ transform: 'none',
+ },
+ },
+ border: {
+ radius: $mol_gap.round,
+ },
+ boxShadow: '0 0 0.5rem 0rem hsla(0,0%,0%,.125)',
+ },
+
+ Card_content: {
+ flex: {
+ direction: 'column',
+ },
+ background: {
+ color: $mol_style_func.hsla( 210, 80, 50, 0.3 ),
+ },
+ padding: $mol_gap.block,
+ border: {
+ radius: $mol_gap.round,
+ },
+ '[card_position]': {
+ 'right': {
+ background: {
+ color: $mol_style_func.hsla( 120, 80, 50, 0.3 ),
+ },
+ },
+ 'left': {
+ background: {
+ color: $mol_style_func.hsla( 0, 80, 50, 0.3 ),
+ },
+ },
+ },
+ },
+
+ Name: {
+ flex: {
+ direction: 'row',
+ },
+ padding: {
+ bottom: '0.5rem',
+ },
+ justify: {
+ content: 'center',
+ },
+ font: {
+ weight: 700,
+ size: '1.5rem',
+ },
+ },
+
+ Question: {
+ justify: {
+ content: 'center',
+ },
+ padding: {
+ bottom: '0.5rem',
+ },
+ },
+
+ Why: {
+ pointerEvents: 'auto',
+ maxWidth: '20rem',
+ },
+
+ Why_label: {
+ gap: '0.5rem',
+ },
+
+ Why_optional: {
+ color: $mol_theme.shade,
+ font: {
+ style: 'italic',
+ },
+ },
+
+ } )
+
+}
diff --git a/card/card.view.tree b/card/card.view.tree
new file mode 100644
index 0000000..fecfe84
--- /dev/null
+++ b/card/card.view.tree
@@ -0,0 +1,23 @@
+$optimade_tmdne_card $optimade_tmdne_swipe
+ allowed <= loaded false
+ content /
+ <= Card_float $mol_view
+ attr *
+ loaded <= loaded
+ sub / <= Card_content $mol_view
+ attr *
+ card_position <= card_position \
+ sub /
+ <= Name $mol_html_view
+ minimal_height 22
+ html <= name \
+ <= Question $mol_paragraph
+ title \Do you think it's synthesizable?
+ <= Why_label $mol_view
+ sub /
+ <= Why_title $mol_paragraph
+ title \Why?
+ <= Why_optional $mol_paragraph
+ title \(optional)
+ <= Why $mol_textarea
+ value? <=> why? \
diff --git a/card/card.view.ts b/card/card.view.ts
new file mode 100644
index 0000000..205ee00
--- /dev/null
+++ b/card/card.view.ts
@@ -0,0 +1,12 @@
+namespace $.$$ {
+
+ export class $optimade_tmdne_card extends $.$optimade_tmdne_card {
+
+ @ $mol_mem
+ card_position(): string {
+ return this.swiped_to() || this.passed() || ''
+ }
+
+ }
+
+}
diff --git a/d582d1239f.png b/d582d1239f.png
new file mode 100644
index 0000000..8aab0ed
Binary files /dev/null and b/d582d1239f.png differ
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 5cf4480..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-httpx
-crystal-toolkit
-optimade[pymatgen]
-gunicorn
diff --git a/results.csv b/results.csv
deleted file mode 100644
index 5f03388..0000000
--- a/results.csv
+++ /dev/null
@@ -1,261 +0,0 @@
-813805a1-179a-442b-b9da-1555b816138f,a8ba8cc16a,1
-813805a1-179a-442b-b9da-1555b816138f,4c4300b256,2
-813805a1-179a-442b-b9da-1555b816138f,4c4300b256,3
-813805a1-179a-442b-b9da-1555b816138f,4c4300b256,4
-813805a1-179a-442b-b9da-1555b816138f,4c4300b256,5
-813805a1-179a-442b-b9da-1555b816138f,48c04ddda9,1
-052430ea-71a4-45e0-a41c-6ff306996832,08f12dbe96,1
-052430ea-71a4-45e0-a41c-6ff306996832,373e1dabfe,2
-052430ea-71a4-45e0-a41c-6ff306996832,0ed077f153,2
-052430ea-71a4-45e0-a41c-6ff306996832,c3c11010ac,3
-052430ea-71a4-45e0-a41c-6ff306996832,ae4cf9267c,1
-052430ea-71a4-45e0-a41c-6ff306996832,8bf08247fa,1
-052430ea-71a4-45e0-a41c-6ff306996832,ae25695182,2
-052430ea-71a4-45e0-a41c-6ff306996832,feee8c9d63,3
-052430ea-71a4-45e0-a41c-6ff306996832,42769a42a5,1
-052430ea-71a4-45e0-a41c-6ff306996832,9fb7d29912,1
-052430ea-71a4-45e0-a41c-6ff306996832,9cd7028825,1
-052430ea-71a4-45e0-a41c-6ff306996832,f93489bf43,1
-052430ea-71a4-45e0-a41c-6ff306996832,ace503fa98,1
-052430ea-71a4-45e0-a41c-6ff306996832,85eed2ff79,2
-052430ea-71a4-45e0-a41c-6ff306996832,ef3ec0fe29,1
-052430ea-71a4-45e0-a41c-6ff306996832,46111b4fd6,1
-052430ea-71a4-45e0-a41c-6ff306996832,1355778f40,2
-052430ea-71a4-45e0-a41c-6ff306996832,fd48845ad0,3
-2023-12-10T01:35:29.183831,335e4fb7-ebfb-40be-a67b-c9b5986861f3,08f12dbe96,1
-2023-12-10T01:36:05.953010,335e4fb7-ebfb-40be-a67b-c9b5986861f3,373e1dabfe,2
-2023-12-10T01:36:15.569456,335e4fb7-ebfb-40be-a67b-c9b5986861f3,29996413f6,3
-2023-12-10T01:37:03.436101,335e4fb7-ebfb-40be-a67b-c9b5986861f3,b7866d38a4,1
-2023-12-10T01:40:07.901205,335e4fb7-ebfb-40be-a67b-c9b5986861f3,ae4cf9267c,2
-2023-12-10T01:53:25.229727,172.31.48.11,08f12dbe96,1
-2023-12-10T01:53:37.527790,172.31.48.11,373e1dabfe,2
-2023-12-10T04:39:08.401134,172.31.48.11,2032820f51,1
-2023-12-10T07:52:41.831894,172.31.48.11,2871f6d074,1
-2023-12-10T07:52:49.369994,172.31.48.11,8bf08247fa,2
-2023-12-10T07:52:58.968660,172.31.48.11,61f0bde892,3
-2023-12-10T08:40:09.841372,172.31.48.11,fe77f9ad05,1
-2023-12-10T08:40:40.469997,172.31.48.11,474990c5d5,2
-2023-12-10T08:41:56.930155,172.31.48.11,cd58cf65f4,1
-2023-12-10T08:42:11.230770,172.31.48.11,02fb284d16,2
-2023-12-10T08:42:13.081288,172.31.48.11,184bdb616c,3
-2023-12-10T08:42:27.729663,172.31.48.11,42769a42a5,4
-2023-12-10T08:44:22.294723,172.31.48.11,0a627e5e0c,5
-2023-12-10T08:44:29.163058,172.31.48.11,9fb7d29912,6
-2023-12-10T08:44:32.369661,172.31.48.11,9cd7028825,7
-2023-12-10T08:44:40.858716,172.31.48.11,74175f9642,1
-2023-12-10T08:44:42.146964,172.31.48.11,b1e7320905,8
-2023-12-10T08:44:47.722387,172.31.48.11,e34e18dd40,9
-2023-12-10T08:44:52.606806,172.31.48.11,d90550ac56,10
-2023-12-10T08:45:01.197856,172.31.48.11,5088f350e8,11
-2023-12-10T08:45:26.772820,172.31.48.11,22e3d0722b,12
-2023-12-10T09:04:49.820630,172.31.48.11,b5aa020a86,1
-2023-12-10T09:28:48.400872,172.31.48.11,38b594b9f0,1
-2023-12-10T09:28:57.459704,172.31.48.11,6b98dbca69,2
-2023-12-10T09:29:09.253819,172.31.48.11,5d89fc9011,3
-2023-12-10T10:12:28.754033,172.31.48.11,85eed2ff79,1
-2023-12-10T10:12:43.296791,172.31.48.11,3068b9a4b4,2
-2023-12-10T10:13:16.239041,172.31.48.11,ef3ec0fe29,3
-2023-12-10T10:47:21.519517,172.31.48.11,4810103dc8,1
-2023-12-10T11:42:18.309595,172.31.48.11,2d984e0731,1
-2023-12-10T11:42:23.584336,172.31.48.11,396a22636d,2
-2023-12-10T11:42:30.598941,172.31.48.11,aa68bc5ea6,3
-2023-12-10T11:42:32.480918,172.31.48.11,1e42be3bf6,4
-2023-12-10T11:42:33.469528,172.31.48.11,b9c0483275,5
-2023-12-10T11:42:34.091270,172.31.48.11,9342aaea05,6
-2023-12-10T11:42:35.224948,172.31.48.11,da3368a66d,7
-2023-12-10T11:42:36.071050,172.31.48.11,f814051baf,8
-2023-12-10T11:42:36.670731,172.31.48.11,2a3bd925a4,9
-2023-12-10T11:42:37.832525,172.31.48.11,b443ba681d,10
-2023-12-10T11:42:38.947643,172.31.48.11,b178b4b60b,11
-2023-12-10T11:42:39.713972,172.31.48.11,5d89fc9011,12
-2023-12-10T11:42:40.713326,172.31.48.11,f8410244a9,13
-2023-12-10T11:42:41.882827,172.31.48.11,c3c11010ac,14
-2023-12-10T11:42:42.867798,172.31.48.11,d9305374dd,15
-2023-12-10T11:42:44.038933,172.31.48.11,18617e1fb5,16
-2023-12-10T11:42:45.052252,172.31.48.11,bd4841bdf2,17
-2023-12-10T11:42:45.931141,172.31.48.11,ddc2576fb5,18
-2023-12-10T11:42:46.963853,172.31.48.11,77fca3844d,19
-2023-12-10T11:42:47.927634,172.31.48.11,56b1701b36,20
-2023-12-10T11:42:48.728264,172.31.48.11,c6e96e8418,21
-2023-12-10T11:42:49.786490,172.31.48.11,16d7a580f0,22
-2023-12-10T12:30:59.366286,172.31.48.11,1f46285073,1
-2023-12-10T12:33:31.625799,172.31.48.11,5a907bd5fc,2
-2023-12-10T14:46:09.137306,172.31.48.11,5a7f6fa180,1
-2023-12-10T14:46:33.444553,172.31.48.11,0ddc2ad967,2
-2023-12-10T15:30:45.443668,172.31.48.11,e1a304f4f9,1
-2023-12-10T15:52:51.706618,172.31.48.11,52c7b79e28,1
-2023-12-10T15:53:00.560805,172.31.48.11,5585fa5df2,2
-2023-12-10T15:53:04.628762,172.31.48.11,06aa9aba77,3
-2023-12-10T16:54:12.697351,172.31.48.11,67f06bea1b,3
-2023-12-10T18:43:48.233081,172.31.48.11,d481302ccb,1
-2023-12-10T18:44:18.340928,172.31.48.11,81aca8f34b,2
-2023-12-10T18:44:30.769207,172.31.48.11,b84a10bc99,3
-2023-12-10T19:28:43.219652,172.31.48.11,5a233705a7,1
-2023-12-10T19:41:38.989798,172.31.48.11,f94ce15e95,1
-2023-12-10T19:42:54.225213,172.31.48.11,a397e8a674,2
-2023-12-10T21:14:49.053379,172.31.48.11,0833d2b586,2
-2023-12-10T21:14:50.380240,172.31.48.11,609b04ad0a,3
-2023-12-10T21:14:50.626487,172.31.48.11,609b04ad0a,4
-2023-12-10T21:14:50.909309,172.31.48.11,609b04ad0a,5
-2023-12-10T21:14:57.828872,172.31.48.11,77fe38ef14,6
-2023-12-10T21:15:05.176034,172.31.48.11,7637c6768e,7
-2023-12-10T21:45:02.395845,172.31.48.11,ca0509de66,1
-2023-12-10T21:45:20.499606,172.31.48.11,089845da40,2
-2023-12-10T21:45:31.744310,172.31.48.11,e32a217602,3
-2023-12-10T21:45:38.619462,172.31.48.11,f1114bb798,4
-2023-12-10T21:46:10.468585,172.31.48.11,e5d42e2749,5
-2023-12-10T21:46:22.314337,172.31.48.11,d583bca697,6
-2023-12-10T21:46:34.861474,172.31.48.11,5915704b68,7
-2023-12-10T21:46:37.861299,172.31.48.11,4d84e5d5b1,8
-2023-12-10T21:49:27.160548,172.31.48.11,fbca34bf6a,9
-2023-12-10T21:49:35.469406,172.31.48.11,a8e20d3180,10
-2023-12-10T21:49:50.927423,172.31.48.11,ca39d06493,11
-2023-12-10T21:50:08.705153,172.31.48.11,cce2560603,12
-2023-12-10T21:50:18.603789,172.31.48.11,060e7101a6,13
-2023-12-10T21:50:22.818791,172.31.48.11,f7479791f4,14
-2023-12-10T21:50:28.741450,172.31.48.11,5d8f30a894,15
-2023-12-10T21:50:39.680865,172.31.48.11,3c61ed4d8d,16
-2023-12-10T21:50:41.796087,172.31.48.11,904280c87b,17
-2023-12-10T21:50:46.225198,172.31.48.11,87f1f3d8eb,18
-2023-12-10T21:55:34.162429,172.31.48.11,b92e677f98,19
-2023-12-10T21:56:05.493748,172.31.48.11,2d156a895c,20
-2023-12-10T21:56:08.948198,172.31.48.11,bd4841bdf2,21
-2023-12-10T21:56:12.408506,172.31.48.11,7484354c22,22
-2023-12-10T21:56:14.455737,172.31.48.11,8a825332e9,23
-2023-12-10T21:56:31.478971,172.31.48.11,beb8b638a3,24
-2023-12-10T21:56:42.929347,172.31.48.11,e7c9c3fd05,25
-2023-12-10T21:57:17.158976,172.31.48.11,5248a8de80,26
-2023-12-10T21:59:00.815424,172.31.48.11,f15f043fe7,27
-2023-12-10T21:59:15.734561,172.31.48.11,b0e03c8a4b,28,30
-2023-12-10T22:22:51.881985,172.31.48.11,29996413f6,1,20
-2023-12-10T22:23:03.372048,172.31.48.11,c3c11010ac,2,50
-2023-12-10T23:20:02.673454,172.31.48.11,4d99b1d990,1,50
-2023-12-10T23:20:14.229172,172.31.48.11,a51f0a97c0,2,100
-2023-12-10T23:20:21.139649,172.31.48.11,33e42a3c1a,3,50
-2023-12-10T23:20:38.142765,172.31.48.11,2032820f51,4,0
-2023-12-10T23:20:46.541335,172.31.48.11,6ea3e53db0,5,100
-2023-12-10T23:20:53.534309,172.31.48.11,2454bfcde1,6,0
-2023-12-11T07:24:29.099660,172.31.48.11,fb7e18c3b5,1,30
-2023-12-11T07:24:37.651226,172.31.48.11,26b5e16af3,2,30
-2023-12-11T13:39:58.513373,172.31.48.11,27e8fe6fe7,1,70
-2023-12-12T11:05:11.032420,172.31.48.11,184bdb616c,1,0
-2023-12-12T12:24:19.083940,172.31.48.11,9fb7d29912,1,0
-2023-12-12T12:45:32.855150,172.31.48.11,e34e18dd40,1,10
-2023-12-12T12:45:52.148692,172.31.48.11,5088f350e8,2,10
-2023-12-12T12:47:05.045739,172.31.48.11,22e3d0722b,3,10
-2023-12-12T12:48:50.641761,172.31.48.11,29996413f6,4,20
-2023-12-12T12:51:11.514975,172.31.48.11,b5aa020a86,5,10
-2023-12-12T12:51:48.741610,172.31.48.11,3c61ed4d8d,6,10
-2023-12-12T12:53:51.468949,172.31.48.11,b830de4210,7,10
-2023-12-12T12:54:03.380300,172.31.48.11,7274606d10,8,10
-2023-12-12T12:54:37.455742,172.31.48.11,f93489bf43,9,10
-2023-12-12T12:57:02.531810,172.31.48.11,38b594b9f0,10,30
-2023-12-12T12:57:13.080252,172.31.48.11,6b98dbca69,11,50
-2023-12-12T12:57:22.199671,172.31.48.11,5d89fc9011,12,10
-2023-12-12T12:59:05.116814,172.31.48.11,ace503fa98,13,10
-2023-12-12T12:59:34.917430,172.31.48.11,85eed2ff79,14,50
-2023-12-12T13:29:52.021308,172.31.48.11,ef3ec0fe29,1,80
-2023-12-12T13:30:24.010926,172.31.48.11,233b8a3c43,2,20
-2023-12-12T16:42:57.972303,172.31.48.11,9cbe35530e,1,0
-2023-12-12T16:42:59.052957,172.31.48.11,ee248120d7,2,0
-2023-12-12T16:48:02.699372,172.31.48.11,c9e4ebe1af,1,0
-2023-12-12T16:48:15.246189,172.31.48.11,6ea56365f1,2,0
-2023-12-13T02:03:10.100772,172.31.48.11,2d984e0731,1,70
-2023-12-13T11:47:57.296647,172.31.48.11,1e42be3bf6,1,70
-2023-12-13T13:43:09.442535,172.31.48.11,f814051baf,1,10
-2023-12-13T13:43:10.048567,172.31.48.11,2a3bd925a4,2,10
-2023-12-13T13:43:58.978255,172.31.48.11,b443ba681d,3,10
-2023-12-13T20:59:45.588906,172.31.48.11,08f12dbe96,50,1,'too much silicon'
-2023-12-28T08:03:16.472476,172.31.48.11,ae25695182,70,1,''
-2024-01-16T20:55:31.063683,172.31.48.5,3c61ed4d8d,50,1,'Na2LiYCl6'
-2024-01-16T20:56:24.728380,172.31.48.5,b830de4210,50,2,''
-2024-01-16T20:56:25.865390,172.31.48.5,bbafca2c58,50,3,''
-2024-01-16T20:56:27.074549,172.31.48.5,7274606d10,50,4,''
-2024-01-16T20:56:39.814852,172.31.48.5,f93489bf43,100,5,''
-2024-01-16T20:56:51.033777,172.31.48.5,38b594b9f0,100,6,''
-2024-01-16T20:56:54.827206,172.31.48.5,6b98dbca69,50,7,''
-2024-01-18T18:26:14.920275,172.31.48.5,233b8a3c43,100,1,''
-2024-01-18T18:26:16.917842,172.31.48.5,46111b4fd6,100,2,''
-2024-01-18T18:26:23.741739,172.31.48.5,2d302172db,100,3,''
-2024-01-19T16:17:34.590555,172.31.48.5,ee248120d7,100,1,''
-2024-01-19T16:17:56.594553,172.31.48.5,4810103dc8,50,2,''
-2024-01-19T16:18:09.267377,172.31.48.5,c9e4ebe1af,50,3,''
-2024-01-19T16:18:15.405813,172.31.48.5,6ea56365f1,50,4,''
-2024-01-19T16:18:23.752652,172.31.48.5,f4fe02cdf6,50,5,''
-2024-01-19T16:18:28.364266,172.31.48.5,15d1c55782,50,6,''
-2024-01-19T16:18:58.815686,172.31.48.5,96ec757620,50,7,''
-2024-01-19T16:19:04.905643,172.31.48.5,394472c73e,50,8,''
-2024-01-19T16:19:11.956784,172.31.48.5,2d984e0731,50,9,''
-2024-01-19T16:19:28.358419,172.31.48.5,396a22636d,50,10,''
-2024-01-19T16:19:31.637337,172.31.48.5,aa68bc5ea6,50,11,''
-2024-01-19T16:19:47.575308,172.31.48.5,1e42be3bf6,50,12,''
-2024-02-14T16:14:19.363408,172.31.48.12,67f06bea1b,20,1,''
-2024-02-24T12:18:39.897846,172.31.48.12,83db638923,20,1,''
-2024-03-03T02:43:37.852303,172.31.48.12,f93489bf43,90,1,''
-2024-03-03T02:45:34.056045,172.31.48.12,fd48845ad0,70,1,''
-2024-03-05T08:04:31.024660,172.31.48.12,2a3bd925a4,0,1,''
-2024-03-07T00:03:07.176115,172.31.48.12,5d89fc9011,0,1,''
-2024-03-07T00:03:12.681870,172.31.48.12,f8410244a9,0,2,''
-2024-03-07T00:03:16.087938,172.31.48.12,c3c11010ac,0,3,''
-2024-03-07T00:03:22.378839,172.31.48.12,d9305374dd,0,4,''
-2024-03-07T00:03:26.573822,172.31.48.12,18617e1fb5,0,5,''
-2024-03-07T00:03:35.790353,172.31.48.12,bd4841bdf2,0,6,''
-2024-03-07T00:03:56.033913,172.31.48.12,ddc2576fb5,0,7,''
-2024-03-24T23:24:33.769734,172.31.48.21,6ea3e53db0,30,1,''
-2024-03-25T19:18:02.604763,172.31.48.21,b1fd30944c,0,1,''
-2024-03-25T19:18:17.538123,172.31.48.21,b34312e784,0,2,''
-2024-03-25T19:19:10.513764,172.31.48.21,783030bd26,0,3,''
-2024-03-25T19:19:27.330949,172.31.48.21,672205188c,0,4,''
-2024-03-25T19:19:40.120784,172.31.48.21,e34e18dd40,0,5,''
-2024-03-25T19:49:18.373076,172.31.48.21,b715a6eeab,20,1,'it can be difficult to find someone who wants to deal with radioactive Tc'
-2024-03-25T19:51:28.318843,172.31.48.21,f7f1897372,10,2,'Protactinium (Pa) is one of the rarest and most expensive naturally occurring elements. (from Wikipedia)'
-2024-03-25T20:01:29.258004,172.31.48.21,184bdb616c,70,1,''
-2024-03-25T20:02:34.229114,172.31.48.21,02fb284d16,10,1,'it is unlikely that Tb, Pr and Lu would order as predicted here. the material might exist in a higher symmetry space group with Tb,Pr and Lu disordered, then it should be written as (Tb,Pr,Lu)5Sn4'
-2024-03-25T20:09:58.519545,172.31.48.21,fd48845ad0,0,1,'loose MgBr molecules in a crystals are not a thing'
-2024-03-25T20:10:04.188062,172.31.48.21,07570a66bc,0,2,''
-2024-03-25T20:10:45.706989,172.31.48.21,9cbe35530e,0,3,'noooooo'
-2024-03-25T20:48:01.556761,172.31.48.21,1e42be3bf6,60,1,''
-2024-03-25T20:48:02.267954,172.31.48.21,1e42be3bf6,60,2,''
-2024-03-25T20:48:11.353763,172.31.48.21,f814051baf,30,3,''
-2024-03-25T20:48:18.438292,172.31.48.21,2a3bd925a4,30,4,''
-2024-03-25T20:59:36.144502,172.31.48.21,d9305374dd,10,2,'Pr and Tb are likely to be disordered, strange coordinations'
-2024-03-25T20:59:46.745741,172.31.48.21,d9305374dd,10,1,'Pr and Tb are likely to be disordered, strange coordinations'
-2024-03-25T22:33:17.898483,172.31.48.21,e8ccd3fc77,50,1,''
-2024-03-25T22:33:23.167990,172.31.48.21,a6dc87910a,50,2,''
-2024-03-25T22:33:29.377579,172.31.48.21,d31da9d6dc,50,3,''
-2024-03-25T22:35:12.090498,172.31.48.21,62f68203f1,50,1,''
-2024-03-25T22:35:13.974530,172.31.48.21,280b630a85,50,2,''
-2024-03-25T22:50:38.024442,172.31.48.21,13ff474841,80,1,''
-2024-03-25T22:50:45.435729,172.31.48.21,d04b7c0a0c,20,2,''
-2024-03-26T07:02:18.517726,172.31.48.21,83bf568487,90,1,''
-2024-03-26T07:02:28.421269,172.31.48.21,d481302ccb,90,2,''
-2024-03-26T07:11:52.783329,172.31.48.21,5a907bd5fc,20,1,''
-2024-03-26T07:25:02.854034,172.31.48.21,b84a10bc99,10,2,''
-2024-03-26T07:25:17.928210,172.31.48.21,089845da40,40,3,''
-2024-03-26T07:25:44.998067,172.31.48.21,c4adb64fb5,10,4,''
-2024-03-26T16:07:10.156785,172.31.48.21,56b1701b36,30,1,''
-2024-03-26T16:07:21.775268,172.31.48.21,06f8f4799b,30,2,''
-2024-03-27T11:37:35.370114,172.31.48.21,7637c6768e,10,1,'pseudo-trigonal symmetry, gamma roughly 60 deg looks very wrong. CN=13 for Zr is also unlikely. Most likely occupantionally disordered'
-2024-03-27T11:42:04.475613,172.31.48.21,27e8fe6fe7,60,2,'Looks similar to Laves phases, mostly reasonable interatomic distances + coordination enviroments. Elements are chemically different enough to order'
-2024-03-27T11:45:28.699937,172.31.48.21,aba6abc8bf,20,3,'elements are too similar to order, unlikely Re coordination'
-2024-03-27T11:47:25.153803,172.31.48.21,aa68bc5ea6,20,4,'Co-coordinations seems unlikely, also fairly large unit cell'
-2024-03-27T11:49:03.737105,172.31.48.21,ca0509de66,70,5,'AlB2-type variant which is reasonable, but Ge and Si are likely disordered'
-2024-03-27T11:49:20.130023,172.31.48.21,ca0509de66,80,6,''
-2024-03-27T20:23:52.752055,172.31.48.21,e32a217602,20,1,''
-2024-03-27T20:23:58.091685,172.31.48.21,f1114bb798,90,2,''
-2024-03-27T20:25:38.114031,172.31.48.21,e5d42e2749,20,3,''
-2024-03-27T20:25:49.661376,172.31.48.21,d583bca697,20,4,''
-2024-03-27T20:25:56.752197,172.31.48.21,5915704b68,60,5,''
-2024-03-27T20:26:07.494552,172.31.48.21,4d84e5d5b1,80,6,''
-2024-03-27T20:26:16.076629,172.31.48.21,fbca34bf6a,80,7,''
-2024-03-27T20:26:22.654018,172.31.48.21,aa68bc5ea6,10,8,''
-2024-03-27T20:26:31.872105,172.31.48.21,a8e20d3180,20,9,''
-2024-03-27T20:26:32.743277,172.31.48.21,ca39d06493,20,10,''
-2024-03-28T12:32:15.013107,172.31.48.21,5d8f30a894,50,1,''
-2024-03-28T12:33:16.093023,172.31.48.21,5248a8de80,10,1,'a molecular structure like this is extremely unlikely to be stable'
-2024-03-28T13:24:00.366851,172.31.48.21,02fb284d16,50,1,''
-2024-03-28T13:24:01.093983,172.31.48.21,5a7f6fa180,50,2,''
-2024-03-28T13:24:13.008022,172.31.48.21,67f06bea1b,50,3,''
-2024-03-28T13:24:34.076199,172.31.48.21,70e240b00d,0,4,''
-2024-03-28T14:00:49.717186,172.31.48.21,4743aff8ac,0,1,''
-2024-03-28T14:01:19.363703,172.31.48.21,e65070289a,0,2,''
diff --git a/src/this_material_does_not_exist/__init__.py b/src/this_material_does_not_exist/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/src/this_material_does_not_exist/app.py b/src/this_material_does_not_exist/app.py
deleted file mode 100644
index ba07fed..0000000
--- a/src/this_material_does_not_exist/app.py
+++ /dev/null
@@ -1,162 +0,0 @@
-from __future__ import annotations
-import datetime
-import os
-from flask import request
-import random
-import uuid
-
-import crystal_toolkit.components as ctc
-import dash
-import httpx
-from crystal_toolkit.settings import SETTINGS
-from dash import html
-from dash.dependencies import Input, Output, State
-from optimade.adapters.structures import Structure as OptimadeStructure
-
-app = dash.Dash(
- assets_folder=str(SETTINGS.ASSETS_PATH),
- title="This Material Does Not Exist?",
-)
-
-# Required for gunicorn deployment via app:server
-server = app.server
-
-
-structure = None
-
-structure_component = ctc.StructureMoleculeComponent(structure, id="my_structure")
-
-layout = html.Div(
- [
- html.H2("Does this material exist?"),
- structure_component.title_layout(),
- html.A(None, id="link"),
- structure_component.layout(),
- html.Div(
- [
- html.H3("What's your likelihood that this material is synthesizable?"),
- dash.dcc.Slider(
- 0,
- 100,
- 10,
- value=50,
- marks={0: "0%", 50: "50%", 100: "100%"},
- id="slider",
- ),
- html.Label("Why? (Optional):"),
- dash.dcc.Textarea(
- id="comment-box",
- value="",
- style={
- "width": "100%",
- "height": "50px",
- "resize": "vertical",
- "padding": "5px",
- "font-size": "15px",
- "border": "1px solid #ccc",
- "border-radius": "5px",
- },
- ),
- html.Button(
- "Submit",
- id="submit",
- n_clicks=0,
- style={
- "margin": "10px",
- "padding": "15px 20px",
- "font-size": "16px",
- "background-color": "#333",
- "color": "white",
- "border": "none",
- "border-radius": "5px",
- "cursor": "pointer",
- },
- ),
- ],
- style={
- "width": "350px",
- "padding": "20px",
- "align": "center",
- "text-align": "center",
- },
- ),
- html.Footer(
- [
- html.P(
- "Scores will be recorded anonymously and shared publicly if they prove interesting!",
- style={"text-align": "center"},
- ),
- html.Div(
- [
- html.A(
- "Powered by OPTIMADE",
- href="https://www.optimade.org",
- style={"padding": "20px"},
- ),
- html.A(
- "and Crystal Toolkit",
- href="https://docs.crystaltoolkit.org",
- style={"padding": "20px"},
- ),
- html.A(
- "using the GNome dataset",
- href="https://github.com/google-deepmind/materials_discovery",
- style={"padding": "20px"},
- ),
- html.A(
- "developed on GitHub",
- href="https://github.com/ml-evs/this-material-does-not-exist",
- style={"padding": "20px"},
- ),
- html.A(
- "inspired by",
- href="https://thispersondoesnotexist.com/",
- style={"padding": "20px"},
- ),
- ],
- ),
- ]
- ),
- ],
- style=dict(
- margin="2em auto", display="grid", placeContent="center", placeItems="center"
- ),
-)
-
-# tell crystal toolkit about your app and layout
-ctc.register_crystal_toolkit(app, layout=layout)
-
-# random string per user session
-session_id = str(uuid.uuid4())
-random.seed(1)
-shuffled_entries = random.sample(range(0, 384938), 1000)
-
-
-@app.callback(
- Output(structure_component.id(), "data"),
- Output("link", "href"),
- Output("link", "children"),
- Output("comment-box", "value"),
- Input("submit", "n_clicks"),
- State("slider", "value"),
- State("comment-box", "value"),
- Input(structure_component.id(), "data"),
-)
-def get_structure(n_clicks: int, value: str, comment: str, data: dict):
- results_fname = os.environ.get("RESULTS_PATH", "results.csv")
- timestamp = datetime.datetime.now().isoformat()
- if data:
- with open(results_fname, "a") as f:
- f.write(
- f'{timestamp},{request.remote_addr},{data["properties"]["optimade_id"].split()[1]},{value},{n_clicks},{comment!r}\n'
- )
-
- ind = random.choice(shuffled_entries)
- base_url = "https://optimade-gnome.odbx.science/v1/structures"
- response = httpx.get(f"{base_url}?page_limit=1&page_offset={ind}").json()
- optimade_structure = response["data"][0]
- pmg_structure = OptimadeStructure(optimade_structure).as_pymatgen
- optimade_id = "GNome " + optimade_structure["id"].split("/")[-1].split(".")[0]
- optimade_url = base_url + "/" + optimade_structure["id"]
- pmg_structure.properties["optimade_id"] = optimade_id
- return pmg_structure, optimade_url, optimade_id, ""
diff --git a/swipe/swipe.view.css.ts b/swipe/swipe.view.css.ts
new file mode 100644
index 0000000..34280e7
--- /dev/null
+++ b/swipe/swipe.view.css.ts
@@ -0,0 +1,17 @@
+namespace $.$$ {
+
+ $mol_style_define( $optimade_tmdne_swipe, {
+
+ background: {
+ color: 'transparent',
+ },
+
+ Float: {
+ userSelect: 'none',
+ pointerEvents: 'none',
+ position: 'relative',
+ },
+
+ } )
+
+}
diff --git a/swipe/swipe.view.tree b/swipe/swipe.view.tree
new file mode 100644
index 0000000..41222d2
--- /dev/null
+++ b/swipe/swipe.view.tree
@@ -0,0 +1,29 @@
+$optimade_tmdne_swipe $mol_view
+ plugins /
+ <= Touch $mol_touch
+ allow_draw false
+ allow_pan <= allowed true
+ pan? => pan?
+ speed_threshold 1
+ right_threshold <= threshold 60
+ left_threshold <= threshold
+ swipe_distance 300
+ transition_smooth \left 0.5s
+ passed \
+ swiped_to? \
+ swipe_to_right null
+ swipe_to_left null
+ move_to_middle null
+ x? 0
+ sub /
+ <= Float $mol_view
+ sub <= content /
+ style *
+ left <= left \0px
+ transition <= transition? \
+
+ pointer_holding? false
+ event *
+ ^
+ pointerdown? <=> pointerdown? null
+ pointerup? <=> pointerup? null
diff --git a/swipe/swipe.view.ts b/swipe/swipe.view.ts
new file mode 100644
index 0000000..d2d0b49
--- /dev/null
+++ b/swipe/swipe.view.ts
@@ -0,0 +1,67 @@
+namespace $.$$ {
+
+ export class $optimade_tmdne_swipe extends $.$optimade_tmdne_swipe {
+
+ @ $mol_mem
+ x( next?: number ): number {
+ return next ?? ( this.start_x + this.pan().x )
+ }
+
+ @ $mol_mem
+ left(): string {
+ return this.x() + 'px'
+ }
+
+ start_x = 0
+ start_time?: number
+ pointerdown( next?: any ) {
+ this.start_x = parseFloat( $mol_dom_context.getComputedStyle( this.Float().dom_node() ).left )
+ this.start_time = (new $mol_time_moment).valueOf()
+
+ this.pan( new $mol_vector_2d( 0, 0 ) )
+ this.transition('')
+
+ this.pointer_holding( true )
+ }
+
+ pointerup( next?: any ) {
+ const speed = this.x() / ( (new $mol_time_moment).valueOf() - this.start_time! )
+
+ if( (this.passed() == 'right') || speed > this.speed_threshold() ) this.swipe_to_right()
+ else if( (this.passed() == 'left') || speed < ( - this.speed_threshold() ) ) this.swipe_to_left()
+ else this.move_to_middle()
+
+ this.pointer_holding( false )
+ }
+
+ move_to_middle() {
+ this.transition( this.transition_smooth() )
+ this.x( 0 )
+ this.swiped_to('')
+ }
+
+ swipe_to_right() {
+ this.transition( this.transition_smooth() )
+ this.x( this.swipe_distance() )
+ this.swiped_to( 'right' )
+ }
+
+ swipe_to_left() {
+ this.transition( this.transition_smooth() )
+ this.x( - this.swipe_distance() )
+ this.swiped_to( 'left' )
+ }
+
+ @ $mol_mem
+ passed(): string {
+ const x = this.x()
+
+ if( x < ( - this.left_threshold() ) ) return 'left'
+ if( x > this.right_threshold() ) return 'right'
+
+ return ''
+ }
+
+ }
+
+}