Add other warnings for the cards

Signed-off-by: Egor Savkin <es@m-labs.hk>
pull/113/head
Egor Savkin 2023-12-06 16:27:43 +08:00
parent abb472f0ea
commit 63d83b5e10
7 changed files with 241 additions and 424 deletions

View File

@ -18,8 +18,10 @@ Start:
zola serve zola serve
``` ```
To update the .bundle.js and .jsx file: To build the .bundle.js from .jsx files:
``` ```
nix-shell -p nodejs --run "npm run build" nix-shell -p nodejs
npm install
npm run build
``` ```

View File

@ -3,7 +3,7 @@ import React from "react";
import {MaxLevel} from "./warnings"; import {MaxLevel} from "./warnings";
export function Warnings({warnings}) { export function CardWarnings({warnings, prefix}) {
const max_level = MaxLevel(warnings); const max_level = MaxLevel(warnings);
return ( return (
<OverlayTrigger <OverlayTrigger
@ -14,7 +14,7 @@ export function Warnings({warnings}) {
<div className="k-popup-warning" {...props}> <div className="k-popup-warning" {...props}>
{warnings.map((warning, _i) => { {warnings.map((warning, _i) => {
return ( return (
<p className="rule warning"> <p className="rule warning" key={`warnmsg_${prefix}_${warning.name}`}>
<i>{warning.message}</i> <i>{warning.message}</i>
</p> </p>
) )
@ -26,4 +26,14 @@ export function Warnings({warnings}) {
<img className="alert-warning" src={max_level.icon}/> <img className="alert-warning" src={max_level.icon}/>
</OverlayTrigger> </OverlayTrigger>
) )
}
export function WarningIndicator({warnings}) {
const max_level = MaxLevel(warnings);
return (
<img
className="alert-warning align-self-start"
src={max_level.icon}
/>
)
} }

View File

@ -2,6 +2,7 @@ import React, {PureComponent} from 'react';
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {SummaryPopup} from "./options/SummaryPopup.jsx"; import {SummaryPopup} from "./options/SummaryPopup.jsx";
import {formatMoney} from "./utils"; import {formatMoney} from "./utils";
import {WarningIndicator} from "./CardWarnings.jsx";
/** /**
@ -132,6 +133,7 @@ export class OrderSummary extends PureComponent {
} }
options = itemsData[index] && itemsData[index].options; options = itemsData[index] && itemsData[index].options;
options_data = itemsData[index] && itemsData[index].options_data; options_data = itemsData[index] && itemsData[index].options_data;
const warnings = itemsData[index] && itemsData[index].show_warnings;
return ( return (
<tr key={item.id} <tr key={item.id}
@ -153,11 +155,8 @@ export class OrderSummary extends PureComponent {
</button> </button>
<div style={{'width': '45px', 'height': '20px'}} className="d-inline-flex align-content-center align-self-center justify-content-evenly"> <div style={{'width': '45px', 'height': '20px'}} className="d-inline-flex align-content-center align-self-center justify-content-evenly">
{(warning ? ( {(warnings && warnings.length > 0 ? (
<img <WarningIndicator warnings={warnings}/>
className="alert-warning align-self-start"
src={`/images/${warning.icon}`}
/>
) : ( ) : (
<span style={{ <span style={{
'display': 'inline-block', 'display': 'inline-block',

View File

@ -4,7 +4,7 @@ import {Draggable} from "@hello-pangea/dnd";
import {DialogPopup} from "./options/DialogPopup.jsx"; import {DialogPopup} from "./options/DialogPopup.jsx";
import {productStyle} from "./utils"; import {productStyle} from "./utils";
import {Resources} from "./Resources.jsx"; import {Resources} from "./Resources.jsx";
import {Warnings} from "./Warnings.jsx"; import {CardWarnings} from "./CardWarnings.jsx";
/** /**
* Component that renders a product. * Component that renders a product.
@ -120,7 +120,7 @@ export class ProductCartItem extends PureComponent {
<div className="progress-container warning d-flex justify-content-evenly"> <div className="progress-container warning d-flex justify-content-evenly">
{warnings && warnings.length > 0 && {warnings && warnings.length > 0 &&
(<Warnings warnings={warnings} />) (<CardWarnings warnings={warnings} prefix={index} />)
} }
{options && ( {options && (

View File

@ -4,7 +4,7 @@ const count_item_occupied_eem = (item) => {
|| item.options_data.ext_pwr === false || item.options_data.ext_pwr === false
|| item.options_data.mono_eem === false || item.options_data.mono_eem === false
) )
return item.slotOccupied; return (item.consumes && item.consumes.eem) || 0;
else if (item.options_data.ext_pwr === true) else if (item.options_data.ext_pwr === true)
return 0; return 0;
else if (item.options_data.mono_eem === true || item.options_data.n_eem === "1 EEM") else if (item.options_data.mono_eem === true || item.options_data.n_eem === "1 EEM")
@ -12,29 +12,34 @@ const count_item_occupied_eem = (item) => {
else if (item.options_data.n_eem === "3 EEM") else if (item.options_data.n_eem === "3 EEM")
return 3; return 3;
return item.slotOccupied || 0; return (item.consumes && item.consumes.eem) || 0;
} }
const count_item_occupied_clock = (item) => { const count_item_occupied_clock = (item) => {
return (item.options_data && item.options_data.ext_clk === true) ? 0 : (item.clockOccupied || 0); return (item.options_data && (item.options_data.ext_clk === true || (item.options_data.ext_clk && item.options_data.ext_clk.checked === true)) ) ? 0 : ((item.consumes && item.consumes.clk) || 0);
} }
const count_item_occupied_idc = (item) => { const count_item_occupied_idc = (item) => {
return item.idcOccupied || 0; return (item.consumes && item.consumes.idc) || 0;
}
const count_item_occupied_hp = (item) => {
return (item.consumes && item.consumes.hp) || 0;
} }
export const item_occupied_counters = { export const item_occupied_counters = {
"eem": count_item_occupied_eem, "eem": count_item_occupied_eem,
"clk": count_item_occupied_clock, "clk": count_item_occupied_clock,
"idc": count_item_occupied_idc, "idc": count_item_occupied_idc,
"hp": count_item_occupied_hp,
} }
function CounterFactory(name) { function CounterFactory(name) {
return (data, index) => { return (data, index) => {
let count = 0; let count = 0;
for (let i = index + 1; i < data.length; i++) { for (let i = index + 1; i < data.length; i++) {
if (data[i].resources && !!data[i].resources.find((value, _i) => value.name === name)) break;
count += item_occupied_counters[name](data[i]); count += item_occupied_counters[name](data[i]);
if (data[i].resources && !!data[i].resources.find((value, _i) => value.name === name)) break;
} }
return count; return count;
} }
@ -43,7 +48,8 @@ function CounterFactory(name) {
const resource_counters = { const resource_counters = {
"eem": CounterFactory("eem"), "eem": CounterFactory("eem"),
"clk": CounterFactory("clk"), "clk": CounterFactory("clk"),
"idc": CounterFactory("idc") "idc": CounterFactory("idc"),
"hp": CounterFactory("hp"),
} }
function CountResources(data, index) { function CountResources(data, index) {

View File

@ -51,10 +51,6 @@ const wiring_constraint = (name) => {
} }
} }
const crate_overload = (data, index, _counters) => {
// TODO
}
const Types = { const Types = {
"eem_resource": { "eem_resource": {
level: "warning", level: "warning",
@ -91,11 +87,6 @@ const Types = {
trigger: wiring_constraint("eem"), trigger: wiring_constraint("eem"),
message: "Due to wiring constraints, the carrier can only connect to EEM cards immediately at its right, without crossing another carrier." message: "Due to wiring constraints, the carrier can only connect to EEM cards immediately at its right, without crossing another carrier."
}, },
"crate_overload": {
level: "warning",
trigger: crate_overload,
message: 'This card needs either a card that provides a clock source (e.g. Kasli or Clocker) at its left or use an external clock source.'
},
"default": { "default": {
level: "warning", level: "warning",
trigger: (_a, _b, _c) => { trigger: (_a, _b, _c) => {
@ -112,9 +103,9 @@ export function TriggerWarnings(data) {
element.show_warnings = element.warnings element.show_warnings = element.warnings
.map((warning, _) => { .map((warning, _) => {
if (!!Types[warning]) if (!!Types[warning])
return Types[warning].trigger(data, index, element.counted_resources) ? {trigger: undefined, ...Types[warning]} : null; return Types[warning].trigger(data, index, element.counted_resources) ? {trigger: undefined, name: warning, ...Types[warning]} : null;
else else
return Types.default.trigger(data, index, element.counted_resources); return Types.default;
}) })
.filter((warning, _) => { .filter((warning, _) => {
return !!warning return !!warning

View File

@ -56,14 +56,6 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: 'kasli', type: 'kasli',
hp: 8,
nbrSlotMin: 0,
nbrSlotMax: 12,
nbrCurrentSlot: 0,
nbrClockMax: 4,
nbrCurrentClock: 0,
slotOccupied: 1,
clockOccupied: 0,
options: [ options: [
{type: "Radio", args: {title: "DRTIO role", outvar: "drtio_role", variants: ["standalone", "master", "satellite"], tip: "Distributed Real Time Input/Output allows ARTIQ RTIO channels to be distributed among several satellite devices synchronized and controlled by a central core(master) device. Standalone option disables this feature."}}, {type: "Radio", args: {title: "DRTIO role", outvar: "drtio_role", variants: ["standalone", "master", "satellite"], tip: "Distributed Real Time Input/Output allows ARTIQ RTIO channels to be distributed among several satellite devices synchronized and controlled by a central core(master) device. Standalone option disables this feature."}},
{ {
@ -92,14 +84,17 @@ const shop_data = {
} }
], ],
resources: [ resources: [
{name: "eem", max: 5}, {name: "eem", max: 12},
{name: "clk", max: 4}, {name: "clk", max: 4},
], ],
warnings: [ warnings: [
"eem_resource", "eem_resource",
"clk_resource", "clk_resource",
"eem_wiring_constraint" "eem_wiring_constraint"
] ],
consumes: {
hp: 8
}
}, },
'kaslisoc': { 'kaslisoc': {
id: 'kaslisoc', id: 'kaslisoc',
@ -156,38 +151,18 @@ const shop_data = {
] ]
} }
], ],
rules: { resources: [
maxSlot: { {name: "eem", max: 12},
type: 'kaslisoc-max-slot', {name: "clk", max: 4},
icon: '/shop/icon-reminder.svg', ],
name: 'Kasli-SoC', warnings: [
message: 'Insufficient EEM connectors.', "eem_resource",
}, "clk_resource",
maxSlotWarning: { "eem_wiring_constraint"
type: 'kaslisoc-max-slot-warning', ],
icon: '/shop/icon-warning.svg', consumes: {
name: 'Kasli-SoC', hp: 8
message: 'Insufficient EEM connectors', }
},
maxClock: {
type: 'kaslisoc-max-clock',
icon: '/shop/icon-reminder.svg',
name: 'Kasli-SoC',
message: 'Insufficient clock connectors. Kasli-SoC has at most 4 clock connections.',
},
maxClockWarning: {
type: 'kaslisoc-max-clock-warning',
icon: '/shop/icon-warning.svg',
name: 'Kasli-SoC',
message: 'Insufficient clock connectors.',
},
follow: {
type: 'kaslisoc-follow',
icon: '/shop/icon-reminder.svg',
name: 'Kasli-SoC',
message: 'Due to wiring constraints, a Kasli-SoC can only connect to EEM cards immediately at its right, without crossing another carrier.',
},
},
}, },
'vhdcicarrier': { 'vhdcicarrier': {
id: 'vhdcicarrier', id: 'vhdcicarrier',
@ -204,46 +179,17 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: 'vhdcicarrier', type: 'vhdcicarrier',
hp: 8, resources: [
nbrSlotMin: 0, {name: "eem", max: 8},
nbrSlotMax: 8, ],
nbrCurrentSlot: 0, warnings: [
nbrClockMax: 0, "eem_resource",
nbrCurrentClock: 0, "clk_resource",
slotOccupied: 1, "eem_wiring_constraint"
clockOccupied: 0, ],
rules: { consumes: {
maxSlot: { hp: 8
type: 'vhdcicarrier-max-slot', }
icon: '/shop/icon-reminder.svg',
name: 'VHDCI carrier',
message: 'Insufficient EEM connectors.',
},
maxSlotWarning: {
type: 'vhdcicarrier-max-slot-warning',
icon: '/shop/icon-warning.svg',
name: 'VHDCI carrier',
message: 'Insufficient EEM connectors',
},
maxClock: {
type: 'vhdcicarrier-max-clock',
icon: '/shop/icon-reminder.svg',
name: 'VHDCI carrier',
message: 'The VHDCI carrier lacks clock connectors.',
},
maxClockWarning: {
type: 'vhdcicarrier-max-clock-warning',
icon: '/shop/icon-warning.svg',
name: 'VHDCI carrier',
message: 'The VHDCI carrier lacks clock connectors.',
},
follow: {
type: 'vhdcicarrier-follow',
icon: '/shop/icon-reminder.svg',
name: 'VHDCI carrier',
message: 'Due to wiring constraints, a VHDCI carrier can only connect to EEM cards immediately at its right, without crossing another carrier.',
},
},
}, },
'bnc-dio': { 'bnc-dio': {
id: 'bnc-dio', id: 'bnc-dio',
@ -265,12 +211,6 @@ const shop_data = {
datasheet_name: '2118/2128 BNC/SMA-TTL datasheet', datasheet_name: '2118/2128 BNC/SMA-TTL datasheet',
size: 'big', size: 'big',
type: null, type: null,
hp: 8,
nbrSlotMin: 0,
nbrSlotMax: 0,
nbrClockMax: 0,
slotOccupied: 1,
clockOccupied: 0,
options: [ options: [
{ {
"if": [ "if": [
@ -317,7 +257,11 @@ const shop_data = {
], ],
warnings: [ warnings: [
"no_eem_source" "no_eem_source"
] ],
consumes: {
hp: 8,
eem: 1
}
}, },
'sma-dio': { 'sma-dio': {
id: 'sma-dio', id: 'sma-dio',
@ -377,15 +321,13 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: null, type: null,
hp: 4,
nbrSlotMin: 0,
nbrSlotMax: 0,
nbrClockMax: 0,
slotOccupied: 1,
clockOccupied: 0,
warnings: [ warnings: [
"no_eem_source" "no_eem_source"
] ],
consumes: {
hp: 4,
eem: 1
}
}, },
'mcx-dio': { 'mcx-dio': {
id: 'mcx-dio', id: 'mcx-dio',
@ -471,20 +413,13 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: null, type: null,
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 2, hp: 4,
clockOccupied: 0, eem: 2
rules: { }
resources: {
type: 'mcx-dio',
icon: '/shop/icon-warning.svg',
name: 'MCX-DIO',
message: 'This card needs a card that provides two EEM connectors (e.g. Kasli) at its left.',
},
},
}, },
'rj45-dio': { 'rj45-dio': {
id: 'rj45-dio', id: 'rj45-dio',
@ -565,20 +500,13 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: null, type: null,
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 2, hp: 4,
clockOccupied: 0, eem: 2
rules: { }
resources: {
type: 'rj45-dio',
icon: '/shop/icon-warning.svg',
name: 'RJ45-DIO',
message: 'This card needs a card that provides two EEM connectors (e.g. Kasli) at its left.',
},
},
}, },
'urukul': { 'urukul': {
id: 'urukul', id: 'urukul',
@ -631,20 +559,15 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'urukul', type: 'urukul',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 2, consumes: {
clockOccupied: 1, hp: 4,
rules: { eem: 2,
resources: { clk: 1
type: 'urukul', }
icon: '/shop/icon-warning.svg',
name: 'Urukul',
message: 'This card needs a card that provides EEM and clocking connectors (e.g. Kasli) at its left.',
},
},
}, },
'urukul_4412': { 'urukul_4412': {
id: 'urukul_4412', id: 'urukul_4412',
@ -672,20 +595,15 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'urukul', type: 'urukul',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 2, consumes: {
clockOccupied: 1, hp: 4,
rules: { eem: 2,
resources: { clk: 1
type: 'urukul', }
icon: '/shop/icon-warning.svg',
name: 'Urukul',
message: 'This card needs a card that provides EEM and clocking connectors (e.g. Kasli) at its left.',
},
},
}, },
'phaser': { 'phaser': {
id: 'phaser', id: 'phaser',
@ -709,20 +627,15 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'urukul', type: 'urukul',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 1, consumes: {
clockOccupied: 1, hp: 4,
rules: { eem: 1,
resources: { clk: 1
type: 'phaser', }
icon: '/shop/icon-warning.svg',
name: 'Phaser',
message: 'This card needs a card that provides EEM and clocking connectors (e.g. Kasli) at its left.',
},
},
}, },
'zotino': { 'zotino': {
id: 'zotino', id: 'zotino',
@ -747,33 +660,17 @@ const shop_data = {
datasheet_name: '5432 Zotino datasheet', datasheet_name: '5432 Zotino datasheet',
size: 'small', size: 'small',
type: 'zotino', type: 'zotino',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 4, "idc_resource"
nbrCurrentSlot: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 1, hp: 4,
clockOccupied: 0, eem: 1
rules: {
maxSlot: {
type: 'zotino',
icon: '/shop/icon-reminder.svg',
name: 'Zotino',
message: 'Zotino has at most 4 IDC-BNC adapters.',
},
maxSlotWarning: {
type: 'zotino-max-slot-warning',
icon: '/shop/icon-warning.svg',
name: 'Zotino',
message: 'Insufficient connectors.',
},
resources: {
type: 'zotino',
icon: '/shop/icon-warning.svg',
name: 'Zotino',
message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.',
},
}, },
resources: [
{name: "idc", max: 4}
]
}, },
'fastino': { 'fastino': {
id: 'fastino', id: 'fastino',
@ -792,33 +689,17 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'zotino', type: 'zotino',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 4, "idc_resource",
nbrCurrentSlot: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 2, hp: 4,
clockOccupied: 0, eem: 1
rules: {
maxSlot: {
type: 'fastino',
icon: '/shop/icon-reminder.svg',
name: 'Fastino',
message: 'Fastino has at most 4 IDC-BNC adapters.',
},
maxSlotWarning: {
type: 'fastino-max-slot-warning',
icon: '/shop/icon-warning.svg',
name: 'Fastino',
message: 'Insufficient connectors.',
},
resources: {
type: 'fastino',
icon: '/shop/icon-warning.svg',
name: 'Fastino',
message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.',
},
}, },
resources: [
{name: "idc", max: 4}
]
}, },
'idc-bnc-adapter': { 'idc-bnc-adapter': {
id: 'idc-bnc-adapter', id: 'idc-bnc-adapter',
@ -834,20 +715,13 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: 'idc-bnc', type: 'idc-bnc',
hp: 8, warnings: [
nbrSlotMin: 0, "no_idc_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 1, hp: 8,
clockOccupied: 0, idc: 1
rules: { }
wrong: {
type: 'idc-bnc',
icon: '/shop/icon-warning.svg',
name: 'IDC-BNC',
message: 'Should be after a Zotino or a HD68-IDC or with another IDC-BNC.',
}
},
}, },
'idc-sma-adapter': { 'idc-sma-adapter': {
id: 'idc-sma-adapter', id: 'idc-sma-adapter',
@ -863,20 +737,13 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'idc-bnc', type: 'idc-bnc',
hp: 4, warnings: [
nbrSlotMin: 0, "no_idc_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 1, hp: 4,
clockOccupied: 0, idc: 1
rules: { }
wrong: {
type: 'idc-sma',
icon: '/shop/icon-warning.svg',
name: 'SMA-IDC',
message: 'Should be after a Zotino or a HD68-IDC or with another SMA-IDC.',
}
},
}, },
'idc-mcx-adapter': { 'idc-mcx-adapter': {
id: 'idc-mcx-adapter', id: 'idc-mcx-adapter',
@ -892,20 +759,13 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: 'idc-bnc', type: 'idc-bnc',
hp: 8, warnings: [
nbrSlotMin: 0, "no_idc_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 1, hp: 8,
clockOccupied: 0, idc: 1
rules: { }
wrong: {
type: 'idc-mcx',
icon: '/shop/icon-warning.svg',
name: 'MCX-IDC',
message: 'Should be after a Zotino or a HD68-IDC or with another MCX-IDC.',
}
},
}, },
'hd68-idc-adapter': { 'hd68-idc-adapter': {
id:'hd68-idc-adapter', id:'hd68-idc-adapter',
@ -919,37 +779,19 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'hd68', type: 'hd68',
hp: 4,
options: [ options: [
{type: "Radio", args: {title: "Cable length", outvar: "cable_len", variants: ["1 M", "2 M", "3 M"], tip: "The desired length of the HD68 cable", fallback: 1}}, {type: "Radio", args: {title: "Cable length", outvar: "cable_len", variants: ["1 M", "2 M", "3 M"], tip: "The desired length of the HD68 cable", fallback: 1}},
], ],
options_class: "hd68-idc", options_class: "hd68-idc",
nbrSlotMin: 1, warnings: [
nbrSlotMax: 4, "idc_resource"
nbrCurrentSlot: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 0, hp: 4
clockOccupied: 0,
rules: {
minAdapter: {
type: 'hd68-min-adapter',
icon: '/shop/icon-warning.svg',
name: 'HD68-IDC',
message: 'Need at least one IDC-BNC Adapter at its right.',
},
maxSlot: {
type: 'hd68-max-slot',
icon: '/shop/icon-reminder.svg',
name: 'HD68-IDC',
message: null,
},
maxSlotWarning: {
type: 'hd68-max-slot-warning',
icon: '/shop/icon-warning.svg',
name: 'HD68-IDC',
message: 'Insufficient connectors.',
},
}, },
resources: [
{name: "idc", max: 4}
]
}, },
'novo': { 'novo': {
id: 'novo', id: 'novo',
@ -994,19 +836,12 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: 'novo', type: 'novo',
hp: 8, warnings: [
nbrSlotMin: 0, "no_eem_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 2, hp: 8,
clockOccupied: 0, eem: 2
rules: {
resources: {
type: 'novo',
icon: '/shop/icon-warning.svg',
name: 'Sampler',
message: 'This card needs a card that provides EEM connectors (e.g. Kasli) at its left.',
},
} }
}, },
'koster': { 'koster': {
@ -1028,19 +863,12 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: 'koster', type: 'koster',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 2, hp: 4,
clockOccupied: 0, eem: 2
rules: {
resources: {
type: 'koster',
icon: '/shop/icon-warning.svg',
name: 'Grabber',
message: 'This card needs a card that provides EEM connectors (e.g. Kasli) at its left.',
},
} }
}, },
'clocker': { 'clocker': {
@ -1064,26 +892,19 @@ const shop_data = {
options_class: "clocker", options_class: "clocker",
size: 'small', size: 'small',
type: 'clocker', type: 'clocker',
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source",
nbrClockMax: 6, "clk_resource"
slotOccupied: 1, ],
clockOccupied: 1, consumes: {
rules: { hp: 4,
maxClock: { eem: 1,
type: 'clocker-max-clock', clk: 1
icon: '/shop/icon-reminder.svg',
name: 'Clocker',
message: 'Clocker has at most 6 clock connections.',
},
maxClockWarning: {
type: 'clocker-max-clock-warning',
icon: '/shop/icon-warning.svg',
name: 'Clocker',
message: 'Insufficient clock connectors.',
},
}, },
resources: [
{name: "clk", max: 6}
]
}, },
'stabilizer': { 'stabilizer': {
id: 'stabilizer', id: 'stabilizer',
@ -1109,12 +930,13 @@ const shop_data = {
options_class: "stabilizer", options_class: "stabilizer",
size: 'small', size: 'small',
type: null, type: null,
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 1, hp: 4,
clockOccupied: 0, eem: 1
},
}, },
'mirny': { 'mirny': {
id: 'mirny', id: 'mirny',
@ -1136,19 +958,14 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: null, type: null,
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 1, consumes: {
clockOccupied: 1, hp: 4,
rules: { eem: 1,
resources: { clk: 1
type: 'mirny',
icon: '/shop/icon-warning.svg',
name: 'Mirny',
message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.',
},
}, },
}, },
'almazny': { 'almazny': {
@ -1168,20 +985,15 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: null, type: null,
hp: 8, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 1, consumes: {
clockOccupied: 1, hp: 8,
rules: { eem: 1,
resources: { clk: 1
type: 'almazny', },
icon: '/shop/icon-warning.svg',
name: 'Almazny',
message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.',
},
}
}, },
'thermostat-eem': { 'thermostat-eem': {
id: 'thermostat-eem', id: 'thermostat-eem',
@ -1203,12 +1015,13 @@ const shop_data = {
], ],
size: 'small', size: 'small',
type: null, type: null,
hp: 4, warnings: [
nbrSlotMin: 0, "no_eem_source"
nbrSlotMax: 0, ],
nbrClockMax: 0, consumes: {
slotOccupied: 1, hp: 4,
clockOccupied: 0 eem: 1,
}
}, },
'shuttler': { 'shuttler': {
id: 'shuttler', id: 'shuttler',
@ -1227,20 +1040,15 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: null, type: null,
hp: 8, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 1, consumes: {
clockOccupied: 1, hp: 8,
rules: { eem: 1,
resources: { clk: 1
type: 'shuttler', },
icon: '/shop/icon-warning.svg',
name: 'Shuttler',
message: 'This card needs a card that provides a EEM connector (e.g. Kasli) at its left.',
},
}
}, },
'pounder': { 'pounder': {
id: 'pounder', id: 'pounder',
@ -1263,12 +1071,15 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: null, type: null,
hp: 8, warnings: [
nbrSlotMin: 0, "no_eem_source",
nbrSlotMax: 0, "no_clk_source"
nbrClockMax: 0, ],
slotOccupied: 1, consumes: {
clockOccupied: 1, hp: 4,
eem: 1,
clk: 1
}
}, },
'eem_pwr_mod': { 'eem_pwr_mod': {
id: 'eem_pwr_mod', id: 'eem_pwr_mod',
@ -1290,12 +1101,10 @@ const shop_data = {
], ],
size: 'big', size: 'big',
type: null, type: null,
hp: 8, warnings: [],
nbrSlotMin: 0, consumes: {
nbrSlotMax: 0, hp: 4,
nbrClockMax: 0, },
slotOccupied: 0,
clockOccupied: 0,
}, },
}, },