////
  // Copyright (c) 2021, 2026 Contributors to the Eclipse Foundation
  //
  // This program and the accompanying materials are made
  // available under the terms of the Eclipse Public License 2.0
  // which is available at https://www.eclipse.org/legal/epl-2.0/
  //
  // SPDX-License-Identifier: EPL-2.0
////

include::_initCommon.adoc[]

[[logistics-specification]]
== Logistics Specification

=== Create New Project

You can create a new specification by using the *File > New* menu on the Workbench menu bar. Start by creating a logistics project as follows:

. From the menu bar, select *File > New > Project...*
+
image:{imgsdir}/new_project.png[]
. In the New Project wizard, select *Logistics > Logistics Project* then click Next.
. In the  Project name  field, type your name as the name of your new project, for example "Tutorial".
. Leave the box checked to use the default location for your new project. Click Finish when you are done.

The wizard creates a machine specification in the project and configures the project for graphical editing. It will open the <<resources-and-peripherals-in-machine,machine editor>>, allowing the user to add the resources and peripherals to the machine.

Within the project, the different types of specification can be created:

* machine specification 
* settings specification
* activity specification
* activity dispatching specification

A new project always starts with machine specification, since it specifies the resources with their peripherals.

[NOTE]
====
If it is the first time a file is created in the project, a pop up dialog about adding Xtext nature to the project will appear. Click +Yes+ to continue.

image::{imgsdir}/image23.png[]
====

=== Create Machine Specification

Machine specification with file extension “machine” is used to specify the resources with their peripherals. 
This file is created automatically with the new project. It usually has the same name with the project, e.g. “tutorial.machine”.

//image::{imgsdir}/new_wizard.png[]

A machine specification file can be opened to edit. Below are the basic concepts and small examples within a machine specification file.

TIP: kbd:[Ctrl+Space] can be used to see the hints for the next step in textual editors.


---- 
include::{codedir}/tutorial.machine[lines=10..63]
----
<1> *Machine* - the unique name for a machine
<2> *PeripheralType* (_unmovable_) – it only declares actions
<3> *PeripheralType* (_movable_) - it may declare actions, but it also declares set points and axes. +
The *SetPoints* relate to the physical coordinate system of the peripheral on which the motion profile settings are applied. +
The *Axes* relate to the symbolic coordinate system on which the physical locations are applied. An axis specifies which set points change when its value changes. The unit is specified between the square brackets _[]_ and defaults to *m*(eters).
<4> *Conversion* - If the unit of an axis differs from the unit of its set points a conversion script is required. The conversion needs to convert a physical location in the symbolic axes coordinate system to a physical location in the physical set points coordinate system. For each axis a variable is available containing its coordinate value and for each set point a variable should be set containing the set point value. +
NOTE: The script language is JavaScript

<5> *Resource* – it defines its peripherals. For every movable peripheral in a resource its symbolic positions and paths need to be specified.
<6> *AxisPositions* (_optional_) - if a peripheral has multiple axes and the symbolic positions can be categorized in axis positions, these axis positions may be declared in this section. In this case only a physical location per axis position is required in the settings file for this axis in stead of one location per symbolic position.
<7> *SymbolicPositions* - declares the symbolic positions for this peripheral. Optionally a symbolic position may be expressed in its axes positions. If no axis position is specified (i.e. _Below_Left_ and _Below_Right_) the symbolic position will automatically be added to the axis positions for the axis.
<8> *Profiles* - declares the speed profiles to use for the paths.
<9> *Paths* - declares which moves are allowed in the system. If a path is declared between two locations the move is allowed using the speed *profile* as specified by the path. For each end point of a path its settling axes can be specified as a comma separated list between square brackets _[]_. Different types of paths are available: +
_unidirectional path_ - indicated by an unidirectional arrow *-\->*, only a move from left to right is allowed +
_bidirectional path_ - indicated by a bidirectional arrow *\<\->*, both moves from left to right and right to left are allowed +
_full mesh_ - indicated by keyword *FullMesh*, all moves from a location to another location in the full mesh are allowed.
<10> *Profiles* - You can specify more than one speed profile per path by means of the `profiles` keyword.

With the basic concepts as described above it is possible to make a full machine configuration. 

==== Extended/Advanced Machine Specification

Machine configurations can be simplified, compressed or advanced using the concepts in below example:

---- 
include::{codedir}/tutorial_ext.machine[lines=10..73]
----

<1> *import* - machine files can be split up into multiple files.
<2> *ProductDefinition* - A product can be defined in the machine file. Its name can be specified alongside with all its properties.
<3> *Properties* - Properties related to the product. These properties consist of a name and an associated type. Currently supported types are `*Boolean*`, `*Integer*` and `*String*` . These properties can be used and edited in the activity file.
<4> *Resource items* - multiple identical resources can be declared with identifiers 
    (name or number) between parentheses (Robot._take_, Robot._give_ in the example). 
<5> *Distances* - Instead of positions, distances can be specified. Distances only describe a move of a certain 
    distance where the location is unknown or not relevant. Typically used for circular, belt or mill movements. 
    Either *(AxisPositions SymbolicPositions and Paths)* or *Distances* must be specified. 
    They are mutual exclusive.

=== Create Settings Specification

Settings specification with file extension “setting” is used to specify physical settings for peripherals or peripheral actions. Within the project, create a “.setting” file by using the new file wizard.
 
NOTE: Multiple setting files are allowed in a project. They can be used to explore different system configurations

TIP: If another file is selected while running the new file wizard, this file will be automatically imported

image::{imgsdir}/new_wizard_setting.png[]

A setting file is opened. Below are the basic concepts in a settings file, illustrated with small examples.

TIP: kbd:[Ctrl+Space] can be used to see the hints for the next step in textual editors.

---- 
include::{codedir}/tutorial-move-adjustments.setting[lines=10..53]
----
<1> *import* - first step in a setting specification is to import a machine or other setting file. After that, it is allowed to specify properties for peripherals or actions.
<2> *Robot.M* - for a movable peripheral, it is required to set the motion profiles to its profiles and physical relative locations to its symbolic positions. These properties are always set per axis.
<3> *Timings* - if a peripheral contains actions, a timing must be specified. Any _Expression_ may be be used.
<4> *Profiles* - motion profiles need to be assigned to each profile individually. For the built-in motion calculator they can be either Third-order profile (*VAJ*) or Second-order profile (*VA*). Optionally a settling time (*S*) can be specified per profile.
<5> *Positions* - physical relative locations can be specified as a set of maximum, minimal and default values or one fixed value.
<6> *MoveAdjustments* - [optional] A correction of the timings calculated by the motion calculator. To be used for instance to specify any Jitter, ramp up/down or anything else. 
Any _Expression_ may be used. The calculated time is referred to as a **time** _Expression_.

==== Plotting a timing distribution

To gain insight in the probability density for timings in a distribution, the probability density factor (PDF) can be plotted in the Chart View. To do this, please select the distribution keyword of the requested distribution and select the 'Plot in Chart View' item from the context menu, as illustrated in the next figures

image::{imgsdir}/plot_distribution.png[]

TIP: The chart view also shows the _mean_ marker, this is the value used for scheduling.

image::{imgsdir}/chartview_distribution.png[]

==== Extended/Advanced Settings Specification

Setting files can be advanced using Expressions and/or combined Resource items:  

---- 
include::{codedir}/tutorial_ext.setting[lines="10..300"]
----

<1> *Expressions* -  instead of magic numbers Expressions can be used. Re-usable Expressions can be declared 
    anywhere in the settings file. Expressions can also be Distributions for example `val normalDist(mean =  0, sd = 0.1)` 
<2> *Calculations* - simple calculations using *+* *-* *** */* *%* *^* and parentheses are supported.
    Also trigonometry functions like *Sin*, *Cos*, *Tan*, *Asin*, *Acos*, *Atan*, *Atan2* and the constant *Pi* are supported,
    as well as the functions *Abs*, *Exp*, *Log*, *Min*, *Max*, *Round*, *Floor*, *Ceil* and *Sqrt*. The arguments of the calculations can also be Distributions.
<3> *Different settings for Resource items* - Place the identifier as specified in the machine file between the Resource and 
    the Peripheral to make specific settings for a Resource item (In this example: Robot.*_give_*.M and Robot.*_take_*.M).
<4> *Usage* - Expressions can be used to calculate the actual properties.
<5> *Resource items* - multiple resources with identical Peripheral settings can be specified using the Resource name.
<6> *Expressions in assignments* - Expressions calculations can directly be used in assignments.
<7> *Distances* -  when using distances the Distance must be specified as described.

TIP: Hovering over an Expression or an assignment yields the calculated result in a pop-up window.

NOTE: For a Peripheral within a Resource, settings must be specified for either the Resource or *all* Resource items. 
    An error will be raised if a combination is made.

===== Explore different settings.

Similar to machine files, setting files can also be split up into multiple files. 
*import* of machine and other setting files is supported.
In <<create-activity-dispatching-specification>> is described how to choose different setting files.

=== Create Activity Specification

Activity specification with file extension “activity” is used to specify activities of a machine. Within the project, create an “.activity” file by using the new file wizard.

TIP: If another file is selected while running the new file wizard, this file will be automatically imported

//image::{imgsdir}/new_wizard_1.png[]

An activity specification file is opened. Below are the basic concepts and small examples within a activity specification file.

TIP: kbd:[Ctrl+Space] can be used to see the hints for the next step in textual editors.

---- 
include::{codedir}/tutorial.activity[lines=10..30]
----
<1> *import* - first step in an activity specification is to import a machine specification file.
<2> *activity* - specify activities by defining individual actions and dependencies among these actions.
<3> *prerequisites* - specify the initial location for all movable peripherals for this activity. 
<4> *actions* - there are four types of actions: +
. _Resource claiming_ – action name, *claim* keyword and resource. +
  A resource can be passively claimed to ensure that no actions are performed by any of its peripherals until the resource is released again.
  To passively claim a resource, the *claim* keyword can be preceded by the *passive* keyword: *passive claim* <resource>.
  If more activities claim a resource passively, they potentially can run in parallel.
. _Resource releasing_ – action name, *release* keyword and resource +
. _Peripheral action_ – action name, resource, peripheral and peripheral action +
. _Move_ - action name, *move* keyword, resource, peripheral, symbolic position destination and speed profile. +
The default _Move_ action is point-to-point (stop at target position). 
However, it can be changed to *passing* (positions) or *continuing* (distances). 
By using the keyword, you specify that the action should not stop at target. 
Another name for *passing*/*continuing* is event-on-the-fly. 
This feature is used to concatenate _Move_ actions and the user needs to explicitly enable it. 
Here is an example declaration of a passing move: +
`+A1: move Drill.ZR passing UP with speed profile normal ALAP+` +
An example for distance moves can be found in <<advanced-activity-specification>> +
The images below illustrate the difference between two types of _Move_ actions.
+
[.float-group]
--
[.left]
.Movement point-to-point.
image::{imgsdir}/movement-point-to-point.png[]
[.left]
.Movement on-the-fly event.
image::{imgsdir}/events-on-the-fly.png[]
--
+
<5> *ALAP / ASAP* - Each action has _scheduling type_. 
There are two types available: As Soon As Possible (ASAP) and As Late As Possible (ALAP).
If no value is specified at the end of the action, then the scheduling type is *ASAP* by default.
To change it to *ALAP* you can add the *ALAP* keyword at the end of the action.
For more information, see section <<alap-constraints>>. +
_Resource claiming_ –  *ALAP* by default, cannot be changed. +
_Resource releasing_ – *ASAP* by default, cannot be changed. +
_Peripheral action_ – *ASAP* by default, can be changed to *ALAP*. +
_Move_ - *ASAP* by default, can be changed to *ALAP*. +
<6> *action flow* - uses arrows to specify action flow. _A1 -> A2_ represents A2 starts when A1 finishes. 
<7> *syncbar* - used to specify synchronization, for instance _A2 -> |S1 -> A3_ and _|S1 -> A4_ represents A3 and A4 start simultaneously after A2 finishes.

[[advanced-activity-specification]]
==== Extended/Advanced Activity Specification

Distance moves and resource items can be used in activities, as specified below:

---- 
include::{codedir}/tutorial_ext.activity[lines="10..300"] 
----

<1> *Resource item* - In an activity a resource item can be specified by the resource name followed by the identifier 
(Robot.*give* in the example).
<2> *in* - Denotes the product flow, stating that the peripheral receives a product with this action. Should always be coupled with an `*out*` action.
<3> *out* - Denotes the product flow, stating that the peripheral provides a product with this action. Should always be coupled with an `*in*` action.
<4> *entry* - Product enters the system. Properties defined in the ProductDefinition in machine file can be initialized here. For example, the product property `flipped` starts with the value `*False*`. 
<5> *exit* - Product that is currently active exits the system. This ensures that it cannot be referred to in any following actions.
<6> *@start* - Updates the value (at start,) of a specified product property with the newly given value. 
<7> *transfer1* - Transfers between '*in*' and '*out*' can be explicitly paired. This is only needed if there is ambiguity in the destination of a product. 
        The product will be transferred to/from the action with a matching slot name.
        If no specific name is specified the product is transferred using the *default* slot. 
<8> *Resource* - An activity can also refer to a resource, without specifying the specific 
resource item. The advantage of this is that the activity specification can be reused and 
instantiated for the specific resource items. The specific resource item is assigned in the 
activity instance in the activity dispatching specification. 
*This option is now obsolete and must be replaced with Parameters.*
<9> *Parameters* - For reuse and conciseness activities can have parameters. Their type can be a 
concrete global Resource (with resource items) or Product definition and types like SymbolicPosition, Action, Profile, 
Resource and Event. The declared parameters have to be provided in the dispatching files.
See also  <<extended-activity-dispatching-specification>> for usage and <<parameterized-activities-details>> for details.


NOTE: The shown activity is an activity that brings a product from _left_ to _right_ using 2 robots. 
      The product is flipped in the center. Graphically it looks as follows:

NOTE: an *out* transfer is always from the same peripheral. (only) If there are multiple products on one peripheral, the first product that has not yet passed the transfer position is chosen.

image::{imgsdir}/Move_and_Flip_activity.png[]

[[alap-constraints]]
==== Constraints for ALAP and ASAP scheduling actions

There are a number of validation rules implemented in {lsat} for the different scheduling algorithms.
In general you have to keep two things in mind:

. The <<schedule-activities, scheduler algorithm>> prefers *ASAP* scheduling over *ALAP* scheduling.
. A concatenated move with events on-the-fly may be delayed as a whole, but not in between its events.

===== Scenario 1

Consider action A1 in the <<scenario1>> with scheduling type *ALAP* and a sole successor (A2), which is not a syncbar.
In this case the *ALAP* keyword does not have any effect due to the *ASAP* (default) scheduling of action A2.

Eclipse will show you the following warning:

WARNING: The ALAP keyword does not have any effect for action A1.

[[scenario1]]
.ALAP scenario 1
image::{imgsdir}/alap-scenario-1.png[]

===== Scenario 2

Consider move A1 in <<scenario2>> which is *passing*.
As its successor is a syncbar, and this syncbar has more than one predecessor, then *move* A1 must be *ALAP*.
As moves A1 and A3 should be concatenated, there cannot be any delay between them. 
As action A2 might cause such a delay, move A1 needs to be scheduled ALAP to guarantee concatenation. 

Eclipse will show you the following error:

IMPORTANT: Move A1 must be set to ALAP to guarantee concatenation with successor move A3.

[[scenario2]]
.ALAP scenario 2
image::{imgsdir}/alap-scenario-2.png[]

===== Scenario 3

Consider move A3 in <<scenario3>> which is a continued move of A1.
Move A1 continues into move A3 by means of the *passing* keyword and therefore move A3 cannot be delayed.
As the predecessor of move A3 is a syncbar, move A3 must be *ASAP* to guarantee concatenation.

Eclipse will show you the following error:

IMPORTANT: Move A3 must be set to ASAP to guarantee concatenation with predecessor move A1.

[[scenario3]]
.ALAP scenario 3
image::{imgsdir}/alap-scenario-3.png[]

===== Scenario 4

Consider move M3 in <<scenario4>> which is a continued move of M1 and M2.

[[scenario4]]
.ALAP scenario 4
image::{imgsdir}/alap-scenario-4.png[]

Move M2 finally continues into move M3 by means of the *passing* keyword and therefore move M3 cannot be delayed.
Because action A1 is parallel to M2 this cannot be guaranteed hence to following warning will be shown:

WARNING: Parallel action 'A1' might interrupt concatenated move 'M3'.

If after a Timing analysis it appears that M3 is indeed delayed the following error will be shown:

[[scenario4-error]]
.ALAP scenario 4 Error
image::{imgsdir}/alap-scenario-4-timing-analysis-error.png[]

In the <<scenario4-error-etf>> the erroneous move is colored orange.

[[scenario4-error-etf]]
.ALAP scenario 4 Gantt chart
image::{imgsdir}/alap-scenario-4-timing-analysis-error-etf.png[]


===== JIT and time-constraints
Next to defining actions as *ASAP* or *ALAP*, JIT (Just-In-Time) and time constraints can be defined between two actions: _source_ and _target_.
These two actions do not need to be consecutive, there can be other actions in between.

A JIT constraint implies that the _source_ and _target_ action (and all possible actions in between) are scheduled such that 
there is no idle time in between the _source_ and the _target_ action. This could mean the _source_ action is delayed
until the JIT constraint can be met, which can also cause other actions depending on _source_ to be scheduled later. 
This is different than scheduling an action *ALAP*, which will only delay the action itself but not other actions. 

A time constraint defines a lower- and upper-bound between the end of the _source_ action and the start of the 
_target_ action. The _source_ and _target_ actions will be scheduled in such a way that the start of the _target_ action
is between the lower- and upper-bound later than the end of the _source_ action, independent of any intermediate actions.

When JIT or time-constraints cannot be fulfilled, LSAT will give an error showing which constraints could not be met.

JIT and time constraints can be defined in either the activity specification or the activity dispatching specification.
In the activity specification, constraints can either be added directly in the *action flow* for constraints between
consecutive actions, or in the *constraints* section. Both options are shown below:

-----
action flow {
  claim -> A -> B -jit-> C -> D -[2,4] -> E -> release
}

constraints {
  A -jit-> C
  C -[5,8]-> E
}
-----

JIT and time constraints can also be defined in the activity dispatching specification (see <<create-activity-dispatching-specification>>),
to either specify constraints between actions in different activities, or to give different constraints for different
instantiations of an activity. 
Constraints can either be specified in a *constraints* section inside an activity dispatching, for constraints within
one activity dispatching, or in a *constraints* section after all activity dispatchings for constraints. Both options
are shown below:

-----
activities init {
  Act1: Activity1
  Act2: Activity2

  constraints {
    Act1.D -jit-> Act2.A
    Act2.A -[1,10]-> Act2.B
  }
}

activities loop repeat : [1..5] {
  Act2: Activity2
  
  # JIT constraint between A and B for every repeat
  constraints {
    Act2.A -jit-> Act2.B
  }
}

# time constraint between Act2.E in init and the first Act2.E in loop
constraints {
  init.Act2.E -[0,20]-> loop.Act2.E 
}
-----

Note: a regular arrow in constraints sections (`-&gt;`) is a short-hand notation for a time constraint with bounds [0, &#x221E;] (`-[0,inf]-&gt;`).


==== Plotting a move

To gain insight in the motion path of a move, the motion path can be plotted in the Chart View. To do this please select the *move* keyword of the requested move and select the 'Plot in Chart View' item from the context menu, as illustrated in the next figures

image::{imgsdir}/plot_move.png[]

image::{imgsdir}/chartview_move.png[]

By right-clicking on the plot, a menu can be opened which allows selecting a plot.
For the _Third order point-to-point_ motion calculator the available plots are: position, velocity, acceleration and jerk.


[[create-activity-dispatching-specification]]
=== Create Activity Dispatching Specification

Activity dispatching specification with file extension “dispatching” is used to specify a sequence of activities to schedule. 
For more information about scheduling, see section <<schedule-activities>>. Within the project, create a “.dispatching” file by using the new file wizard.


//TIP: If another file is selected while running the new file wizard, this file will be automatically imported

//image::{imgsdir}/new_wizard.png[]

An activity dispatching file is opened. Below are the basic concepts and small examples within a activity dispatching file.

TIP: kbd:[Ctrl+Space] can be used to see the hints for the next step in textual editors.

---- 
include::{codedir}/tutorial.dispatching[lines=10..25]
----
<1> *import* - first step in an activity dispatching is to import an activity specification file.
<2> *iterations* - specifies the default number of iterations - for all resources - or the number of iterations for a 
    specific resource (see next line). 
    When omitting the *throughput* section the default number of iterations will be set to 1. 
    For more information about *iterations* see section <<specifying-the-number-of-iterations>>.
<3> *activities* - within an activity sequence one or more activities can be included. These activities will be scheduled as parallel as possible adhering to the claim/release strategy. If activities cannot be scheduled in parallel the order of this section is applied. +
Optionally a description can be added to the activity
<4> *offset* - optionally an offset can be defined for an activity sequence. The scheduler will ensure that these activities will not be started before the offset time.

[[extended-activity-dispatching-specification]]
==== Extended/Advanced Activity Dispatching Specification

---- 
include::{codedir}/tutorial_ext.dispatching[lines="10..1000"]
----
<1> *import* - import one or more activity files.
<2> *activity phase* - a phase name may be specified to indicate a specific phase like start-up, steady-flow, or tear-down.
<3> *parameters* - for activities that have parameters or their specific resource item not yet specified the parameters must be 
    specified (For example: The RobotMove activity requires 3 parameters).
<4> *user attributes* - user info can be added for an activity. This information will be passed to the trace file see <<schedule-activities>>.
<5> *repeat* - the number of time these activities need to be scheduled. This will be visible in the <<schedule-activities>>. By default 1.
<6> *yield* - the number of products _one_ repeat of activities yields.
<7> *user attributes* - attributes that will be assigned to the activity instance.
<8> the *steadyFlow* activity is functionally equal to *steadyFlowExpanded*.

NOTE: user attributes, activity phase, repeat step (and also activity trace points) are all stored in a generated Gantt Chart. 
See also <<schedule-activities>> 

==== Specifying the number of iterations

The number of iterations is used to calculate the throughput per resource, as explained in section <<calculating-the-throughput-per-resource>>.
In the activity dispatching specification example above the Robot resource performs activity _MoveRobot_ twice, once for the "first product" and once for the "second product".
In this case the number of iterations can be used for the calculation on how many products per hour can be processed by the _Robot_ resource.

CAUTION: The number of iterations does not influence the <<schedule-activities>> or <<conformance-check>>.

NOTE: *throughput* is now deprecated and can be replaced with *repeat* and *yield* as described in <<extended-activity-dispatching-specification>>.

[[create-supervisory-controller-specification]]
=== Create Supervisory Controller Specification

A specification with an individual activity sequence can be described in a "dispatching" specification, see <<create-activity-dispatching-specification, Create Activity Dispatching Specification>>.
A CIF specification is used to concisely describe a supervisory controller that defines all allowed activity sequences that establish a correct product flow, while taking into account product routing flexibility.

In a CIF specification, a network of automata is used as formalism.
The outgoing edges in an automaton refer to the allowed activities in the given automaton location. 
Multiple edges represent a scheduling choice where multiple activities are allowed.
Automata are synchronized on the activity names with multi-party synchronization. 
This means that an activity can only be executed in the current system state, if it is enabled in the current state of each of the synchronizing automata.


A small example of a supervisory controller is shown below.
---- 
include::{codedir}/tutorial.cif[lines=10..300]
----

<1> *controllable* - specifies all activities that are used in the specification, separated by commas.
<2> *supervisor* - the name of the supervisory controller
<3> *initial* - indicates the starting location of the supervisory controller
<4> *edge* - indicates that activity _MoveRobot_ can be executed from location _l0_, leading to location _l1_.

A supervisory controller can also be generated from a set of requirement and plant automata.
The plant automata specify all allowed activity orderings, and the requirements put constraints on the ordering of activities to establish the correct product flow.
Using supervisory controller synthesis, a supervisory controller is generated that enforces the requirements and ensures that the system does not deadlock.
The documentation and tutorials for CIF, including how to use supervisory controller synthesis, can be found at https://www.eclipse.org/escet.

=== Preferences 

==== Editors Configuration

===== Semantic Highlighting

The LSAT text editors (Activity, Machine, and Setting editors) support enhanced keyword highlighting to improve code readability and visual navigation.

image::{imgsdir}/keyword-coloring.png[]

The *Keyword Coloring* preferences page (accessible via menu:Window[Preferences, Logistics, Keyword Coloring] provides two highlightable elements:

. **Highlight motion calculator keywords (in Setting editor)** - When enabled, this option highlights motion argument names (for instance `V`, `A`, `J`, `S`) used in motion profile settings within the Setting editor. This makes it easier to distinguish between different motion parameters and their profiles at a glance.

. **Bold profile names** - When enabled, this option highlights profile names and references across the Activity, Machine, and Setting editors with a distinctive bold italic style. This helps quickly identify which profiles are being used throughout your specifications. Examples:
   - In Machine files: profile declarations like for instance `normal` and `fast`
   - In Settings files: profile assignments in motion settings
   - In Activity files: profile references in move actions

All options are disabled by default. Enabling/Disabling any option will immediately update the highlighting in all open editors, allowing you to customize the visual presentation according to your preferences.
