matterviz 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/dist/ContextMenu.svelte +1 -1
  2. package/dist/ContextMenu.svelte.d.ts +3 -3
  3. package/dist/DraggablePane.svelte +10 -5
  4. package/dist/DraggablePane.svelte.d.ts +3 -3
  5. package/dist/FilePicker.svelte.d.ts +3 -3
  6. package/dist/Icon.svelte.d.ts +3 -3
  7. package/dist/Nav.svelte +76 -31
  8. package/dist/SettingsSection.svelte.d.ts +3 -3
  9. package/dist/Spinner.svelte +18 -29
  10. package/dist/Spinner.svelte.d.ts +3 -3
  11. package/dist/app.css +4 -0
  12. package/dist/bands/Bands.svelte +216 -0
  13. package/dist/bands/Bands.svelte.d.ts +16 -0
  14. package/dist/bands/BandsAndDos.svelte +26 -0
  15. package/dist/bands/BandsAndDos.svelte.d.ts +16 -0
  16. package/dist/bands/Dos.svelte +124 -0
  17. package/dist/bands/Dos.svelte.d.ts +18 -0
  18. package/dist/bands/helpers.d.ts +11 -0
  19. package/dist/bands/helpers.js +195 -0
  20. package/dist/bands/index.d.ts +5 -0
  21. package/dist/bands/index.js +6 -0
  22. package/dist/bands/types.d.ts +54 -0
  23. package/dist/bands/types.js +2 -0
  24. package/dist/brillouin/BrillouinZone.svelte +373 -0
  25. package/dist/brillouin/BrillouinZone.svelte.d.ts +57 -0
  26. package/dist/brillouin/BrillouinZoneControls.svelte +88 -0
  27. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +14 -0
  28. package/dist/brillouin/BrillouinZoneExportPane.svelte +129 -0
  29. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  30. package/dist/brillouin/BrillouinZoneInfoPane.svelte +115 -0
  31. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  32. package/dist/brillouin/BrillouinZoneScene.svelte +180 -0
  33. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +34 -0
  34. package/dist/brillouin/compute.d.ts +7 -0
  35. package/dist/brillouin/compute.js +215 -0
  36. package/dist/brillouin/index.d.ts +7 -0
  37. package/dist/brillouin/index.js +7 -0
  38. package/dist/brillouin/types.d.ts +23 -0
  39. package/dist/brillouin/types.js +1 -0
  40. package/dist/composition/BarChart.svelte.d.ts +3 -3
  41. package/dist/composition/BubbleChart.svelte +7 -6
  42. package/dist/composition/BubbleChart.svelte.d.ts +3 -3
  43. package/dist/composition/Composition.svelte.d.ts +3 -3
  44. package/dist/composition/PieChart.svelte +1 -1
  45. package/dist/composition/PieChart.svelte.d.ts +3 -3
  46. package/dist/composition/parse.d.ts +3 -3
  47. package/dist/coordination/CoordinationBarPlot.svelte +241 -0
  48. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +29 -0
  49. package/dist/coordination/calc-coordination.d.ts +15 -0
  50. package/dist/coordination/calc-coordination.js +66 -0
  51. package/dist/coordination/index.d.ts +8 -0
  52. package/dist/coordination/index.js +7 -0
  53. package/dist/element/BohrAtom.svelte.d.ts +3 -3
  54. package/dist/element/ElementHeading.svelte.d.ts +3 -3
  55. package/dist/element/ElementPhoto.svelte.d.ts +3 -3
  56. package/dist/element/ElementStats.svelte.d.ts +3 -3
  57. package/dist/element/ElementTile.svelte +1 -1
  58. package/dist/element/ElementTile.svelte.d.ts +4 -4
  59. package/dist/element/Nucleus.svelte.d.ts +3 -3
  60. package/dist/icons.d.ts +4 -0
  61. package/dist/icons.js +4 -0
  62. package/dist/index.d.ts +5 -1
  63. package/dist/index.js +5 -1
  64. package/dist/io/export.d.ts +1 -6
  65. package/dist/io/export.js +12 -12
  66. package/dist/labels.d.ts +19 -0
  67. package/dist/labels.js +59 -0
  68. package/dist/math.d.ts +7 -2
  69. package/dist/math.js +24 -12
  70. package/dist/periodic-table/PeriodicTable.svelte.d.ts +3 -3
  71. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +3 -3
  72. package/dist/periodic-table/PropertySelect.svelte +1 -1
  73. package/dist/periodic-table/PropertySelect.svelte.d.ts +5 -4
  74. package/dist/periodic-table/TableInset.svelte.d.ts +3 -3
  75. package/dist/phase-diagram/PhaseDiagram2D.svelte +44 -107
  76. package/dist/phase-diagram/PhaseDiagram2D.svelte.d.ts +7 -27
  77. package/dist/phase-diagram/PhaseDiagram3D.svelte +67 -170
  78. package/dist/phase-diagram/PhaseDiagram3D.svelte.d.ts +7 -31
  79. package/dist/phase-diagram/PhaseDiagram4D.svelte +87 -145
  80. package/dist/phase-diagram/PhaseDiagram4D.svelte.d.ts +5 -28
  81. package/dist/phase-diagram/PhaseDiagramControls.svelte +9 -9
  82. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +6 -6
  83. package/dist/phase-diagram/PhaseDiagramInfoPane.svelte +4 -4
  84. package/dist/phase-diagram/PhaseDiagramInfoPane.svelte.d.ts +5 -5
  85. package/dist/phase-diagram/PhaseDiagramStats.svelte +9 -16
  86. package/dist/phase-diagram/PhaseDiagramStats.svelte.d.ts +3 -3
  87. package/dist/phase-diagram/StructurePopup.svelte.d.ts +3 -3
  88. package/dist/phase-diagram/barycentric-coords.js +13 -24
  89. package/dist/phase-diagram/helpers.d.ts +12 -14
  90. package/dist/phase-diagram/helpers.js +70 -23
  91. package/dist/phase-diagram/index.d.ts +58 -0
  92. package/dist/phase-diagram/index.js +44 -0
  93. package/dist/phase-diagram/thermodynamics.js +2 -3
  94. package/dist/phase-diagram/types.d.ts +3 -8
  95. package/dist/plot/BarPlot.svelte +474 -240
  96. package/dist/plot/BarPlot.svelte.d.ts +16 -37
  97. package/dist/plot/BarPlotControls.svelte +33 -201
  98. package/dist/plot/BarPlotControls.svelte.d.ts +11 -22
  99. package/dist/plot/ColorBar.svelte.d.ts +3 -3
  100. package/dist/plot/ColorScaleSelect.svelte +1 -1
  101. package/dist/plot/ColorScaleSelect.svelte.d.ts +3 -3
  102. package/dist/plot/ElementScatter.svelte +5 -5
  103. package/dist/plot/ElementScatter.svelte.d.ts +8 -8
  104. package/dist/plot/Histogram.svelte +318 -170
  105. package/dist/plot/Histogram.svelte.d.ts +21 -41
  106. package/dist/plot/HistogramControls.svelte +115 -347
  107. package/dist/plot/HistogramControls.svelte.d.ts +13 -28
  108. package/dist/plot/Line.svelte +1 -1
  109. package/dist/plot/Line.svelte.d.ts +4 -4
  110. package/dist/plot/PlotControls.svelte +280 -0
  111. package/dist/plot/PlotControls.svelte.d.ts +4 -0
  112. package/dist/plot/PlotLegend.svelte +9 -24
  113. package/dist/plot/PlotLegend.svelte.d.ts +3 -3
  114. package/dist/plot/ScatterPlot.svelte +536 -571
  115. package/dist/plot/ScatterPlot.svelte.d.ts +18 -90
  116. package/dist/plot/ScatterPlotControls.svelte +108 -316
  117. package/dist/plot/ScatterPlotControls.svelte.d.ts +11 -38
  118. package/dist/plot/ScatterPoint.svelte +1 -1
  119. package/dist/plot/ScatterPoint.svelte.d.ts +5 -5
  120. package/dist/plot/SpacegroupBarPlot.svelte +235 -0
  121. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
  122. package/dist/plot/data-transform.d.ts +2 -2
  123. package/dist/plot/data-transform.js +1 -5
  124. package/dist/plot/index.d.ts +12 -200
  125. package/dist/plot/index.js +14 -6
  126. package/dist/plot/layout.d.ts +10 -16
  127. package/dist/plot/layout.js +40 -25
  128. package/dist/plot/scales.d.ts +7 -8
  129. package/dist/plot/scales.js +22 -7
  130. package/dist/plot/types.d.ts +303 -0
  131. package/dist/plot/types.js +1 -0
  132. package/dist/rdf/RdfPlot.svelte +156 -0
  133. package/dist/rdf/RdfPlot.svelte.d.ts +20 -0
  134. package/dist/rdf/calc-rdf.d.ts +4 -0
  135. package/dist/rdf/calc-rdf.js +107 -0
  136. package/dist/rdf/index.d.ts +22 -0
  137. package/dist/rdf/index.js +2 -0
  138. package/dist/settings.d.ts +86 -75
  139. package/dist/settings.js +257 -155
  140. package/dist/structure/Bond.svelte +126 -110
  141. package/dist/structure/Bond.svelte.d.ts +7 -20
  142. package/dist/structure/CanvasTooltip.svelte.d.ts +4 -4
  143. package/dist/structure/Cylinder.svelte +29 -0
  144. package/dist/structure/Cylinder.svelte.d.ts +10 -0
  145. package/dist/structure/Lattice.svelte +1 -2
  146. package/dist/structure/Lattice.svelte.d.ts +3 -3
  147. package/dist/structure/Structure.svelte +23 -8
  148. package/dist/structure/Structure.svelte.d.ts +10 -7
  149. package/dist/structure/StructureControls.svelte +25 -134
  150. package/dist/structure/StructureControls.svelte.d.ts +4 -9
  151. package/dist/structure/StructureExportPane.svelte +188 -0
  152. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  153. package/dist/structure/StructureInfoPane.svelte.d.ts +3 -3
  154. package/dist/structure/StructureLegend.svelte +91 -27
  155. package/dist/structure/StructureLegend.svelte.d.ts +5 -4
  156. package/dist/structure/StructureScene.svelte +93 -100
  157. package/dist/structure/StructureScene.svelte.d.ts +15 -12
  158. package/dist/structure/Vector.svelte +19 -25
  159. package/dist/structure/Vector.svelte.d.ts +3 -3
  160. package/dist/structure/bonding.d.ts +16 -14
  161. package/dist/structure/bonding.js +207 -216
  162. package/dist/structure/export.d.ts +3 -0
  163. package/dist/structure/export.js +120 -0
  164. package/dist/structure/index.d.ts +15 -1
  165. package/dist/structure/index.js +2 -0
  166. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -3
  167. package/dist/symmetry/index.d.ts +1 -0
  168. package/dist/symmetry/index.js +1 -0
  169. package/dist/symmetry/spacegroups.d.ts +9 -0
  170. package/dist/symmetry/spacegroups.js +397 -0
  171. package/dist/theme/ThemeControl.svelte.d.ts +3 -3
  172. package/dist/theme/themes.js +2 -16
  173. package/dist/trajectory/Trajectory.svelte +52 -78
  174. package/dist/trajectory/Trajectory.svelte.d.ts +5 -5
  175. package/dist/trajectory/TrajectoryError.svelte.d.ts +3 -3
  176. package/dist/trajectory/TrajectoryExportPane.svelte +1 -1
  177. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +5 -5
  178. package/dist/trajectory/TrajectoryInfoPane.svelte +1 -1
  179. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -3
  180. package/dist/trajectory/extract.js +2 -1
  181. package/dist/trajectory/index.d.ts +1 -1
  182. package/dist/trajectory/index.js +1 -1
  183. package/dist/trajectory/parse.js +21 -14
  184. package/dist/utils.d.ts +1 -0
  185. package/dist/utils.js +17 -0
  186. package/dist/xrd/XrdPlot.svelte +14 -11
  187. package/dist/xrd/XrdPlot.svelte.d.ts +6 -5
  188. package/package.json +20 -12
  189. package/readme.md +1 -1
  190. package/dist/material/MaterialCard.svelte +0 -123
  191. package/dist/material/MaterialCard.svelte.d.ts +0 -9
  192. package/dist/material/index.d.ts +0 -1
  193. package/dist/material/index.js +0 -1
  194. package/dist/plot/formatting.d.ts +0 -7
  195. package/dist/plot/formatting.js +0 -53
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
+ export * from './bands';
2
+ export * from './brillouin';
1
3
  export * from './colors';
2
4
  export * from './composition';
3
5
  export { default as ContextMenu } from './ContextMenu.svelte';
6
+ export * from './coordination';
4
7
  export { default as DraggablePane } from './DraggablePane.svelte';
5
8
  export * from './element';
6
9
  export { default as FilePicker } from './FilePicker.svelte';
@@ -9,18 +12,19 @@ export { icon_data } from './icons';
9
12
  export { default as InfoCard } from './InfoCard.svelte';
10
13
  export * from './io';
11
14
  export * from './labels';
12
- export * from './material';
13
15
  export * from './math';
14
16
  export { default as Nav } from './Nav.svelte';
15
17
  export * from './periodic-table';
16
18
  export * from './phase-diagram';
17
19
  export * from './plot';
20
+ export * from './rdf';
18
21
  export * from './settings';
19
22
  export { default as SettingsSection } from './SettingsSection.svelte';
20
23
  export { default as Spinner } from './Spinner.svelte';
21
24
  export * from './structure';
22
25
  export * from './theme';
23
26
  export { default as Trajectory } from './trajectory/Trajectory.svelte';
27
+ export * from './utils';
24
28
  export * from './xrd';
25
29
  export const crystal_systems = [
26
30
  `triclinic`,
@@ -4,15 +4,10 @@ import { WebGLRenderer } from 'three';
4
4
  export interface CanvasWithRenderer extends HTMLCanvasElement {
5
5
  __customRenderer?: WebGLRenderer;
6
6
  }
7
- export declare function export_canvas_as_png(canvas: HTMLCanvasElement | null, structure: AnyStructure | undefined, png_dpi?: number, scene?: THREE.Scene | null, camera?: THREE.Camera | null): void;
7
+ export declare function export_canvas_as_png(canvas: HTMLCanvasElement | null, structure_or_filename: AnyStructure | string | undefined, png_dpi?: number, scene?: THREE.Scene | null, camera?: THREE.Camera | null): void;
8
8
  export declare function export_svg_as_svg(svg_element: SVGElement | null, filename: string): void;
9
9
  export declare function export_svg_as_png(svg_element: SVGElement | null, filename: string, png_dpi?: number): void;
10
- /** Generate FFmpeg command for WebM to MP4 conversion */
11
10
  export declare function get_ffmpeg_conversion_command(input_filename: string): string;
12
- /**
13
- * Export trajectory video as WebM with frame-by-frame rendering (prevents dropped frames).
14
- * Note: Browsers only support WebM natively. Use FFmpeg for MP4 conversion (see get_ffmpeg_conversion_command).
15
- */
16
11
  export declare function export_trajectory_video(canvas: HTMLCanvasElement | null, filename: string, options?: {
17
12
  fps?: number;
18
13
  total_frames?: number;
package/dist/io/export.js CHANGED
@@ -2,7 +2,7 @@ import { download } from './fetch';
2
2
  import { create_structure_filename } from '../structure/export';
3
3
  import { Vector2, WebGLRenderer } from 'three';
4
4
  // Export structure as PNG image from canvas
5
- export function export_canvas_as_png(canvas, structure, png_dpi = 150, scene = null, camera = null) {
5
+ export function export_canvas_as_png(canvas, structure_or_filename, png_dpi = 150, scene = null, camera = null) {
6
6
  try {
7
7
  if (!canvas) {
8
8
  if (typeof window !== `undefined`) {
@@ -10,6 +10,10 @@ export function export_canvas_as_png(canvas, structure, png_dpi = 150, scene = n
10
10
  }
11
11
  return;
12
12
  }
13
+ // Determine filename from either structure or direct filename
14
+ const filename = typeof structure_or_filename === `string`
15
+ ? structure_or_filename
16
+ : create_structure_filename(structure_or_filename, `png`);
13
17
  // Convert DPI to multiplier (72 DPI is baseline web resolution)
14
18
  // Cap to a reasonable upper bound to avoid excessive memory use
15
19
  const resolution_multiplier = Math.min(png_dpi / 72, 10);
@@ -19,7 +23,6 @@ export function export_canvas_as_png(canvas, structure, png_dpi = 150, scene = n
19
23
  try {
20
24
  canvas.toBlob((blob) => {
21
25
  if (blob) {
22
- const filename = create_structure_filename(structure, `png`);
23
26
  download(blob, filename, `image/png`);
24
27
  }
25
28
  else {
@@ -51,7 +54,6 @@ export function export_canvas_as_png(canvas, structure, png_dpi = 150, scene = n
51
54
  renderer.setPixelRatio(original_pixel_ratio);
52
55
  renderer.setSize(original_size.width, original_size.height, false);
53
56
  if (blob) {
54
- const filename = create_structure_filename(structure, `png`);
55
57
  download(blob, filename, `image/png`);
56
58
  }
57
59
  else {
@@ -182,15 +184,13 @@ export function export_svg_as_png(svg_element, filename, png_dpi = 150) {
182
184
  console.error(`Error exporting PNG:`, error);
183
185
  }
184
186
  }
185
- /** Generate FFmpeg command for WebM to MP4 conversion */
187
+ // Generate FFmpeg command for WebM to MP4 conversion
186
188
  export function get_ffmpeg_conversion_command(input_filename) {
187
189
  const output = input_filename.replace(/\.webm$/i, `.mp4`);
188
190
  return `ffmpeg -i "${input_filename}" -c:v libx264 -preset medium -crf 18 -pix_fmt yuv420p -movflags faststart "${output}"`;
189
191
  }
190
- /**
191
- * Export trajectory video as WebM with frame-by-frame rendering (prevents dropped frames).
192
- * Note: Browsers only support WebM natively. Use FFmpeg for MP4 conversion (see get_ffmpeg_conversion_command).
193
- */
192
+ // Export trajectory video as WebM with frame-by-frame rendering to prevent dropped frames.
193
+ // Note: Browsers only support WebM natively. Use FFmpeg for MP4 conversion (see get_ffmpeg_conversion_command).
194
194
  export async function export_trajectory_video(canvas, filename, options = {}) {
195
195
  const { fps = 30, total_frames = 100, on_progress, on_step, resolution_multiplier = 1, } = options;
196
196
  if (!canvas ||
@@ -211,9 +211,8 @@ export async function export_trajectory_video(canvas, filename, options = {}) {
211
211
  }
212
212
  // Calculate bitrate based on actual video dimensions
213
213
  // VP9 typically needs 0.08-0.12 bits per pixel per frame for good quality
214
- const target_width = canvas.width * resolution_multiplier;
215
- const target_height = canvas.height * resolution_multiplier;
216
- const pixels_per_frame = target_width * target_height;
214
+ // canvas dimensions include device pixel ratio and any resolution_multiplier
215
+ const pixels_per_frame = canvas.width * canvas.height;
217
216
  const bits_per_pixel_per_frame = 0.1; // Good quality for VP9
218
217
  // Clamp bitrate to reasonable bounds (1 Mbps min, 200 Mbps max)
219
218
  const calculated_bitrate = pixels_per_frame * fps * bits_per_pixel_per_frame;
@@ -281,7 +280,8 @@ export async function export_trajectory_video(canvas, filename, options = {}) {
281
280
  if (is_resolved)
282
281
  return;
283
282
  is_resolved = true;
284
- reject(new Error(`MediaRecorder error: ${event}`));
283
+ // Extract error details from MediaRecorderErrorEvent or ErrorEvent
284
+ reject(new Error(`MediaRecorder error: ${event.error}`));
285
285
  };
286
286
  // Stop recording with safety timeout
287
287
  try {
package/dist/labels.d.ts CHANGED
@@ -1,4 +1,11 @@
1
1
  import type { ChemicalElement, ElementCategory } from './';
2
+ import type { SymbolType } from 'd3-shape';
3
+ import * as d3_symbols from 'd3-shape';
4
+ export type D3Symbol = keyof typeof d3_symbols & `symbol${Capitalize<string>}`;
5
+ export type D3SymbolName = Exclude<D3Symbol extends `symbol${infer Name}` ? Name : never, ``>;
6
+ export declare const symbol_names: D3SymbolName[];
7
+ export declare const symbol_map: Record<D3SymbolName, SymbolType>;
8
+ export declare function format_value(value: number, formatter?: string): string;
2
9
  export declare const property_labels: Partial<Record<keyof ChemicalElement, [string, string | null]>>;
3
10
  export declare const heatmap_keys: (keyof ChemicalElement)[];
4
11
  export declare const heatmap_labels: Partial<Record<string, keyof ChemicalElement>>;
@@ -24,6 +31,18 @@ export declare const superscript_map: {
24
31
  readonly '+': "⁺";
25
32
  readonly '-': "⁻";
26
33
  };
34
+ export declare const subscript_map: {
35
+ readonly '0': "₀";
36
+ readonly '1': "₁";
37
+ readonly '2': "₂";
38
+ readonly '3': "₃";
39
+ readonly '4': "₄";
40
+ readonly '5': "₅";
41
+ readonly '6': "₆";
42
+ readonly '7': "₇";
43
+ readonly '8': "₈";
44
+ readonly '9': "₉";
45
+ };
27
46
  export declare function superscript_digits(input: string): string;
28
47
  export declare const trajectory_property_config: Record<string, {
29
48
  label: string;
package/dist/labels.js CHANGED
@@ -1,4 +1,51 @@
1
1
  import { format } from 'd3-format';
2
+ import * as d3_symbols from 'd3-shape';
3
+ import { timeFormat } from 'd3-time-format';
4
+ function name_for_symbol(sym) {
5
+ for (const key in d3_symbols) {
6
+ if (Object.prototype.hasOwnProperty.call(d3_symbols, key) &&
7
+ d3_symbols[key] === sym &&
8
+ /^symbol[A-Z]/.test(key))
9
+ return key.substring(6);
10
+ }
11
+ return null;
12
+ }
13
+ export const symbol_names = ([...new Set([...d3_symbols.symbolsFill, ...d3_symbols.symbolsStroke])]
14
+ .map((sym) => name_for_symbol(sym))
15
+ .filter((n) => n !== null));
16
+ const symbols_index = d3_symbols;
17
+ export const symbol_map = Object.fromEntries(symbol_names.map((name) => [name, symbols_index[`symbol${name}`]]));
18
+ // Format a value for display with optional time formatting
19
+ export function format_value(value, formatter) {
20
+ if (!formatter)
21
+ return `${value}`;
22
+ if (formatter.startsWith(`%`))
23
+ return timeFormat(formatter)(new Date(value));
24
+ // Handle special values consistently
25
+ if (value === -Infinity)
26
+ return `-Infinity`;
27
+ if (value === Infinity)
28
+ return `Infinity`;
29
+ if (Number.isNaN(value))
30
+ return `NaN`;
31
+ // Format and normalize unicode minus
32
+ const formatted = format(formatter)(value).replace(/−/g, `-`);
33
+ // Handle percentage formatting - remove trailing zeros
34
+ if (formatter.includes(`%`)) {
35
+ return formatted.includes(`.`)
36
+ ? formatted.replace(/(\.\d*?)0+%$/, `$1%`).replace(/\.%$/, `%`)
37
+ : formatted;
38
+ }
39
+ // Handle currency formatting - preserve precision if specified
40
+ if (formatter.includes(`$`) && formatter.includes(`.`) && /\.\d+f/.test(formatter)) {
41
+ return formatted;
42
+ }
43
+ // Remove trailing zeros after decimal point
44
+ const out = formatted.includes(`.`)
45
+ ? formatted.replace(/(\.\d*?)0+$/, `$1`).replace(/\.$/, ``)
46
+ : formatted;
47
+ return out === `-0` ? `0` : out;
48
+ }
2
49
  // TODO add labels and units for all elemental properties
3
50
  export const property_labels = {
4
51
  atomic_mass: [`Atomic Mass`, `u`],
@@ -152,6 +199,18 @@ export const superscript_map = {
152
199
  '+': `⁺`,
153
200
  '-': `⁻`,
154
201
  };
202
+ export const subscript_map = {
203
+ '0': `₀`,
204
+ '1': `₁`,
205
+ '2': `₂`,
206
+ '3': `₃`,
207
+ '4': `₄`,
208
+ '5': `₅`,
209
+ '6': `₆`,
210
+ '7': `₇`,
211
+ '8': `₈`,
212
+ '9': `₉`,
213
+ };
155
214
  export function superscript_digits(input) {
156
215
  // use replace all signs and digits with their unicode superscript equivalent
157
216
  return input.replace(/[\d+-]/g, (match) => superscript_map[match] ?? match);
package/dist/math.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import type { LatticeParams } from './structure/index';
1
+ import type { LatticeParams, Pbc } from './structure/index';
2
2
  export type Vec3 = [number, number, number];
3
+ export type Vec4 = [number, number, number, number];
3
4
  export type Vec9 = [
4
5
  number,
5
6
  number,
@@ -12,6 +13,7 @@ export type Vec9 = [
12
13
  number
13
14
  ];
14
15
  export type Matrix3x3 = [Vec3, Vec3, Vec3];
16
+ export type Matrix4x4 = [Vec4, Vec4, Vec4, Vec4];
15
17
  export type NdVector = number[];
16
18
  export declare const LOG_EPS = 1e-9;
17
19
  export declare const EPS = 1e-10;
@@ -27,10 +29,12 @@ export declare const euclidean_dist: (vec1: NdVector, vec2: NdVector) => number;
27
29
  export declare function pbc_dist(pos1: Vec3, // First position vector (Cartesian coordinates)
28
30
  pos2: Vec3, // Second position vector (Cartesian coordinates)
29
31
  lattice_matrix: Matrix3x3, // 3x3 lattice matrix where each row is a lattice vector
30
- lattice_inv?: Matrix3x3): number;
32
+ lattice_inv?: Matrix3x3, // Optional pre-computed inverse matrix for optimization (since lattice is usually constant and repeatedly inverting matrix is expensive)
33
+ pbc?: Pbc): number;
31
34
  export declare function matrix_inverse_3x3(matrix: Matrix3x3): Matrix3x3;
32
35
  export declare function mat3x3_vec3_multiply(matrix: Matrix3x3, vector: Vec3): Vec3;
33
36
  export declare function add<T extends NdVector>(...vecs: T[]): T;
37
+ export declare function subtract<T extends NdVector>(vec1: T, vec2: T): T;
34
38
  export declare function dot(vec1: NdVector, vec2: NdVector): number | number[] | number[][];
35
39
  export declare function to_voigt(tensor: number[][]): number[];
36
40
  export declare function from_voigt(voigt: number[]): number[][];
@@ -42,3 +46,4 @@ export declare function det_3x3(matrix: Matrix3x3): number;
42
46
  export declare function get_coefficient_of_variation(values: number[]): number;
43
47
  export declare function det_4x4(matrix: number[][]): number;
44
48
  export declare function cross_3d(a: Vec3, b: Vec3): Vec3;
49
+ export declare function is_square_matrix(matrix: unknown, dim: number): boolean;
package/dist/math.js CHANGED
@@ -38,20 +38,19 @@ export const euclidean_dist = (vec1, vec2) => {
38
38
  export function pbc_dist(pos1, // First position vector (Cartesian coordinates)
39
39
  pos2, // Second position vector (Cartesian coordinates)
40
40
  lattice_matrix, // 3x3 lattice matrix where each row is a lattice vector
41
- lattice_inv) {
42
- // Use provided inverse or compute it
41
+ lattice_inv, // Optional pre-computed inverse matrix for optimization (since lattice is usually constant and repeatedly inverting matrix is expensive)
42
+ pbc = [true, true, true]) {
43
43
  const inv_matrix = lattice_inv ?? matrix_inverse_3x3(lattice_matrix);
44
44
  // Convert Cartesian coordinates to fractional coordinates
45
45
  const [fx1, fy1, fz1] = mat3x3_vec3_multiply(inv_matrix, pos1);
46
46
  const [fx2, fy2, fz2] = mat3x3_vec3_multiply(inv_matrix, pos2);
47
- // Apply minimum image convention: wrap to [-0.5, 0.5)
48
- const wrapped_frac_diff = [fx1 - fx2, fy1 - fy2, fz1 - fz2].map((x) => x - Math.round(x));
47
+ // Apply minimum image convention only for periodic axes
48
+ const wrapped_frac_diff = [fx1 - fx2, fy1 - fy2, fz1 - fz2].map((diff, idx) => pbc[idx] ? diff - Math.round(diff) : diff);
49
49
  // Convert back to Cartesian coordinates
50
50
  const cart_diff = mat3x3_vec3_multiply(lattice_matrix, wrapped_frac_diff);
51
51
  return Math.hypot(...cart_diff);
52
52
  }
53
53
  export function matrix_inverse_3x3(matrix) {
54
- /** Calculate the inverse of a 3x3 matrix */
55
54
  const [[m11, m12, m13], [m21, m22, m23], [m31, m32, m33]] = matrix;
56
55
  const det = det_3x3(matrix);
57
56
  if (!Number.isFinite(det) || Math.abs(det) < EPS) {
@@ -87,9 +86,8 @@ export function mat3x3_vec3_multiply(matrix, vector) {
87
86
  }
88
87
  export function add(...vecs) {
89
88
  // add up any number of same-length vectors
90
- if (vecs.length === 0) {
89
+ if (vecs.length === 0)
91
90
  throw new Error(`Cannot add zero vectors`);
92
- }
93
91
  const first_vec = vecs[0];
94
92
  const length = first_vec.length;
95
93
  // Validate all vectors have the same length
@@ -106,6 +104,12 @@ export function add(...vecs) {
106
104
  }
107
105
  return result;
108
106
  }
107
+ export function subtract(vec1, vec2) {
108
+ if (vec1.length !== vec2.length) {
109
+ throw new Error(`Vectors must be of same length`);
110
+ }
111
+ return vec1.map((val, idx) => val - vec2[idx]);
112
+ }
109
113
  export function dot(vec1, vec2) {
110
114
  // Handle the case where both inputs are scalars
111
115
  if (typeof vec1 === `number` && typeof vec2 === `number`) {
@@ -236,11 +240,11 @@ export function get_coefficient_of_variation(values) {
236
240
  }
237
241
  // Compute 4x4 determinant (used for 4D barycentric coordinates)
238
242
  export function det_4x4(matrix) {
239
- const [a, b, c, d] = matrix;
240
- const [a0, a1, a2, a3] = a;
241
- const [b0, b1, b2, b3] = b;
242
- const [c0, c1, c2, c3] = c;
243
- const [d0, d1, d2, d3] = d;
243
+ const [a_row, b_row, c_row, d_row] = matrix;
244
+ const [a0, a1, a2, a3] = a_row;
245
+ const [b0, b1, b2, b3] = b_row;
246
+ const [c0, c1, c2, c3] = c_row;
247
+ const [d0, d1, d2, d3] = d_row;
244
248
  return (a0 *
245
249
  (b1 * (c2 * d3 - c3 * d2) - b2 * (c1 * d3 - c3 * d1) + b3 * (c1 * d2 - c2 * d1)) -
246
250
  a1 *
@@ -253,3 +257,11 @@ export function det_4x4(matrix) {
253
257
  export function cross_3d(a, b) {
254
258
  return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
255
259
  }
260
+ // Check if a matrix is square with dimension NxN
261
+ export function is_square_matrix(matrix, dim) {
262
+ if (!Array.isArray(matrix))
263
+ return false;
264
+ if (matrix.length !== dim)
265
+ return false;
266
+ return matrix.every((row) => Array.isArray(row) && row.length === dim);
267
+ }
@@ -5,7 +5,7 @@ import type { ComponentProps, Snippet } from 'svelte';
5
5
  import type { HTMLAttributes } from 'svelte/elements';
6
6
  import type { D3InterpolateName } from '../colors';
7
7
  import type { ScaleContext } from './index';
8
- interface Props extends HTMLAttributes<HTMLDivElement> {
8
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
9
9
  tile_props?: Partial<ComponentProps<typeof ElementTile>>;
10
10
  show_photo?: boolean;
11
11
  disabled?: boolean;
@@ -49,7 +49,7 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
49
49
  ]> | boolean;
50
50
  children?: Snippet;
51
51
  onenter?: (element: ChemicalElement) => void;
52
- }
53
- declare const PeriodicTable: import("svelte").Component<Props, {}, "color_scale" | "active_element" | "active_category" | "active_elements">;
52
+ };
53
+ declare const PeriodicTable: import("svelte").Component<$$ComponentProps, {}, "color_scale" | "active_element" | "active_category" | "active_elements">;
54
54
  type PeriodicTable = ReturnType<typeof PeriodicTable>;
55
55
  export default PeriodicTable;
@@ -1,5 +1,5 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
- interface Props extends HTMLAttributes<HTMLDivElement> {
2
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
3
3
  tile_gap?: string;
4
4
  symbol_font_size?: number;
5
5
  number_font_size?: number;
@@ -18,7 +18,7 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
18
18
  tooltip_padding?: string;
19
19
  tooltip_line_height?: number;
20
20
  tooltip_text_align?: string;
21
- }
22
- declare const PeriodicTableControls: import("svelte").Component<Props, {}, "tile_gap" | "symbol_font_size" | "number_font_size" | "name_font_size" | "value_font_size" | "tooltip_font_size" | "tooltip_bg_color" | "tile_border_radius" | "inner_transition_offset" | "tile_font_color" | "tile_transition_duration" | "hover_border_width" | "symbol_font_weight" | "number_font_weight" | "tooltip_border_radius" | "tooltip_padding" | "tooltip_line_height" | "tooltip_text_align">;
21
+ };
22
+ declare const PeriodicTableControls: import("svelte").Component<$$ComponentProps, {}, "tile_gap" | "symbol_font_size" | "number_font_size" | "name_font_size" | "value_font_size" | "tooltip_font_size" | "tooltip_bg_color" | "tile_border_radius" | "inner_transition_offset" | "tile_font_color" | "tile_transition_duration" | "hover_border_width" | "symbol_font_weight" | "number_font_weight" | "tooltip_border_radius" | "tooltip_padding" | "tooltip_line_height" | "tooltip_text_align">;
23
23
  type PeriodicTableControls = ReturnType<typeof PeriodicTableControls>;
24
24
  export default PeriodicTableControls;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">import { heatmap_labels } from '../labels';
2
2
  import Select from 'svelte-multiselect';
3
3
  const options = Object.keys(heatmap_labels);
4
- let { value = $bindable(null), empty = false, selected = empty ? [] : [options[1]], minSelect = 0, key = $bindable(``), ...rest } = $props();
4
+ let { value = $bindable(null), empty = false, selected = empty ? [] : [options[1]], minSelect = 0, key = $bindable(null), ...rest } = $props();
5
5
  $effect.pre(() => {
6
6
  key = heatmap_labels[value ?? ``] ?? null;
7
7
  });
@@ -1,12 +1,13 @@
1
1
  import type { ChemicalElement } from '..';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- interface Props extends HTMLAttributes<HTMLDivElement> {
2
+ import type { ComponentProps } from 'svelte';
3
+ import Select from 'svelte-multiselect';
4
+ type $$ComponentProps = Omit<ComponentProps<typeof Select>, `options`> & {
4
5
  value?: keyof ChemicalElement | null;
5
6
  empty?: boolean;
6
7
  selected?: string[];
7
8
  minSelect?: number;
8
9
  key?: string | null;
9
- }
10
- declare const PropertySelect: import("svelte").Component<Props, {}, "key" | "value">;
10
+ };
11
+ declare const PropertySelect: import("svelte").Component<$$ComponentProps, {}, "key" | "value">;
11
12
  type PropertySelect = ReturnType<typeof PropertySelect>;
12
13
  export default PropertySelect;
@@ -1,9 +1,9 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- interface Props extends HTMLAttributes<HTMLElementTagNameMap[`aside`]> {
3
+ type $$ComponentProps = HTMLAttributes<HTMLElementTagNameMap[`aside`]> & {
4
4
  as?: keyof HTMLElementTagNameMap;
5
5
  children?: Snippet;
6
- }
7
- declare const TableInset: import("svelte").Component<Props, {}, "">;
6
+ };
7
+ declare const TableInset: import("svelte").Component<$$ComponentProps, {}, "">;
8
8
  type TableInset = ReturnType<typeof TableInset>;
9
9
  export default TableInset;