generator_annotations

auto-webclient grammar version yar.13

  1. Generator Contracts
    1. Default
    2. Handheld
    3. Production
  2. Annotations
    1. Global Features
    2. Handheld Menu
    3. Sparse Annotation Tree
      1. Navigation expressions
      2. Annotation Node
      3. Handheld

Generator Contracts

Default

The default generator.

global-features
	'full screen planning' {
		'plannings': list non-empty feature 'planning'
	}

	'dashboard' feature 'dashboard 2'

node-features
	'permissions' component {
		'source': stategroup (
			'user' {
				'user': user binding {
					'stategroup': stategroup binding {
						'state': state binding { }
					}
				}
			}
			'node' {
				'node': node binding { }
			}
		)
	}

	'dimension' component unbound {
		'dimension': stategroup @default: 'default' (
			'custom' {
				'width': number
				'height': number
			}
			'default' { }
		)
	}

	'margin' component unbound {
		'margin': stategroup @default: 'default' (
			'custom' {
				'top': number
				'right': number
				'bottom': number
				'left': number
			}
			'default' { }
		)
	}

	'color' component unbound {
		'color': stategroup @default: 'auto' (
			'auto' { }
			'blue' { }
			'orange' { }
			'green' { }
			'red' { }
			'black' { }
			'grey' { }
			'grey light' { }
			'grey dark' { }
			'teal' { }
			'purple' { }
			'hex' {
				'value': text
			}
		)
	}

	'range' {
		'dimension': feature 'dimension'
		'margin': feature 'margin'
		'range start': stategroup (
			'static' {
				'value': number
			}
			'dynamic' {
				'value': number binding { }
			}
		)
		'ranges': list {
			'type': stategroup (
				'green' { }
				'blue' { }
				'orange' { }
				'red' { }
			)
			'range size': stategroup (
				'static' {
					'value': number
				}
				'dynamic' {
					'value': number binding { }
				}
			)
		}
		'value': number binding { }
		'style': stategroup (
			'progress bar' { }
			'gauge' { }
		)
	}

	'pie chart' {
		'dimension': feature 'dimension'
		'margin': feature 'margin'
		'query': query binding {
			'label': query text binding { }
			'property': query number binding { }
			'merge small slices': stategroup (
				'yes' {
					'below percentage': number
				}
				'no' { }
			)
			'sorting': stategroup (
				'yes' {
					'direction': stategroup (
						'ascending' { }
						'descending' { }
					)
				}
				'no' { }
			)
		}
	}

	'bar chart' {
		'dimension': feature 'dimension'
		'margin': feature 'margin'
		'query': query binding {
			'label': query text binding { }
			'style': stategroup (
				'grouped' {
					'bars': list {
						'property': query number binding { }
						'color': feature 'color'
					}
				}
				'stacked' {
					'bars': list {
						'property': query number binding { }
						'color': feature 'color'
					}
				}
				'bar' {
					'property': query number binding { }
				}
			)
			'sorting': stategroup (
				'yes' {
					'direction': stategroup (
						'ascending' { }
						'descending' { }
					)
					'axis': stategroup (
						'single' {
							'sort': query number binding { }
						}
						'sum' { }
					)
				}
				'no' { }
			)
		}
	}

	'line chart query' component query {
		'dimension': feature 'dimension'
		'margin': feature 'margin'
		'label': query text binding { }
		'lines': list {
			'property': query number binding { }
			'color': feature 'color'
		}
		'style': stategroup (
			'line' { }
			'area' { }
		)
		'sort': query number binding {
			'direction': stategroup (
				'ascending' { }
				'descending' { }
			)
		}
	}

	'chart value' component query {
		'type': stategroup (
			'text' {
				'property': query text binding { }
			}
			'number' {
				'property': query number binding { }
			}
		// TODO 'state group' {
		// 	'property': query stategroup binding { }
		// }
		)
	}

	'2d chart query' component query {
		'title': text
		'x': feature 'chart value'
		'x label': stategroup @default: 'auto' (
			'auto' { }
			'text' {
				'property': query text binding { }
			}
		)
		'x axis title': stategroup @default: 'none' (
			'none' { }
			'set' {
				'text': text
			}
		)
		'y axis title': stategroup @default: 'none' (
			'none' { }
			'set' {
				'text': text
			}
		)
		'format x': stategroup @default: 'auto' (
			'auto' { }
			'day' { }
			'month' { }
			'month and year' { }
			'week' { }
			'week and year' { }
			'custom' {
				'parts': list non-empty {
					'type': stategroup (
						'abbreviated weekday name' { }
						'full weekday name' { }
						'abbreviated month name' { }
						'full month name' { }
						'the locale’s date and time' { }
						'zero-padded day of the month' { }
						'space-padded day of the month' { }
						'microseconds' { }
						'ISO 8601 week-based year without century' { }
						'ISO 8601 week-based year with century' { }
						'hour (24-hour clock)' { }
						'hour (12-hour clock)' { }
						'day of the year' { }
						'month' { }
						'minute' { }
						'milliseconds' { }
						'either AM or PM' { }
						'quarter of the year' { }
						'milliseconds since UNIX epoch' { }
						'seconds since UNIX epoch' { }
						'second' { }
						'Monday-based (ISO 8601) weekday' { }
						'Sunday-based week of the year' { }
						'ISO 8601 week of the year' { }
						'Sunday-based weekday' { }
						'Monday-based week of the year' { }
						'the locale’s date' { }
						'the locale’s time' { }
						'year without century' { }
						'year with century' { }
						'time zone offset' { }
						'percent sign' { }
						'text' {
							'value': text
						}
					)
				}
			}
		)
		'group x value': stategroup @default: 'no' (
			'no' { }
			'yes' {
				'group by': stategroup @default: 'none' (
					'none' { }
					'week' { }
					'month' { }
					'quarter' { }
					'year' { }
				)
			}
		)
		'size': stategroup @default: 'small' (
			'small' { }
			'medium' { }
			'large' { }
		)
		'bar mode': stategroup @default: 'grouped' (
			'grouped' { }
			'stacked' { }
		)
		'lines': list {
			'name': text @default: ""
			'y': query number binding { }
			/// setting `y aggregate` switches the default `sum` function to handle multiple y
			/// values on the same x value.
			'y aggregate': stategroup @default: 'sum' (
				'sum' { }
				'minimum' { }
				'maximum' { }
				'average' { }
			)
			'color': stategroup @default: 'auto' (
				'auto' { }
				'custom' {
					'color': text
				}
			)
			'style': stategroup @default: 'line' (
				'line' {
					'stack': stategroup @default: 'no' (
						'no' { }
						'yes' { }
					)
					'shape': stategroup @default: 'linear' (
						'linear' { }
						'horizontal vertical' { }
						'vertical horizontal' { }
						'horizontal vertical horizontal' { }
						'vertical horizontal vertical' { }
						'spline' { }
					)
					'dash': stategroup @default: 'solid' (
						'solid' { }
						'dot' { }
						'dash dot' { }
						'long dash dot' { }
					)
				}
				'area' { }
				'bar' { }
			)
			'partition': stategroup @default: 'no' (
				'no' { }
				'yes' {
					'value': query text binding { }
					'color': stategroup @default: 'auto' (
						'auto' { }
						'custom' {
							'color': query text binding { }
						}
					)
				}
			)
		}
	}

	'line chart' {
		'query': query binding {
			'chart': feature 'line chart query'
		}
	}

	'scatter chart' {
		'dimension': feature 'dimension'
		'margin': feature 'margin'
		'query': query binding {
			'label': query text binding { }
			'x label': text
			'x property': query number binding { }
			'y label': text
			'y property': query number binding { }
			'style': stategroup (
				'dot' { }
				'connected dot' {
					'sort': query number binding {
						'direction': stategroup (
							'ascending' { }
							'descending' { }
						)
					}
				}
				'bubble' {
					'z property': query number binding { }
				}
			)
		}
	}

	'radar chart' {
		'dimension': feature 'dimension'
		'margin': feature 'margin'
		'query': query binding {
			'label': query text binding { }
			'values': list {
				'property': query number binding { }
			}
			'style': stategroup (
				'spider' { }
				'radar' { }
			)
		}
	}

	'dashboard' {
		'cell width': number
		'cell height': number
		'grid gap': stategroup @default: 'yes' (
			'yes' {
				'size': number @default: 20
			}
			'no' { }
		)
		'widgets': list {
			'x': number
			'width': number
			'y': number
			'height': number
			'widget': stategroup (
				'number' {
					'value': number binding { }
					'number size': stategroup (
						'large' { }
						'fixed' {
							'value': number
						}
					)
					'unit size': stategroup @default: 'auto' (
						'auto' { }
						'fixed' {
							'value': number
						}
					)
				}
				'range' {
					'range': feature 'range'
				}
				'pie chart' {
					'chart': feature 'pie chart'
				}
				'bar chart' {
					'chart': feature 'bar chart'
				}
				'line chart' {
					'chart': feature 'line chart'
				}
				'scatter chart' {
					'chart': feature 'scatter chart'
				}
				'radar chart' {
					'chart': feature 'radar chart'
				}
				'legend' {
					'binding': stategroup (
						'static' {
							'values': list {
								'label': text
								'color': feature 'color'
							}
						}
						'dynamic' {
							'query': query binding {
								'label': query text binding { }
							}
						}
					)
				}
			)
		}
	}

	'dashboard 2' {
		'has permissions': stategroup @default: 'no' (
			'yes' feature 'permissions'
			'no' { }
		)
		'widgets': list {
			'type': stategroup (
				'grouped charts' {
					'query': query binding {
						'charts': list {
							'widget': stategroup (
								'2d chart' {
									'chart': feature '2d chart query'
								}
								'reference filter' {
									/// In order to use the reference filter, make sure the text property is a
									/// reference. Also configure the filter on the query property correctly by
									/// providing the filter `in selection` as follows:
									/// ```
									/// 'a reference' -> ^ : text 'entry' filter in selection
									/// ```
									'property': query text binding { }
								}
								'table' {
									'title': text
									'size': stategroup @default: 'small' (
										'small' { }
										'medium' { }
										'large' { }
									)
									'properties': list {
										'property': query property binding { }
									}
								}
							)
						}
					}
				}
				'tabs' {
					'widgets': list {
						'name': text
						'widget': feature 'dashboard 2'
					}
				}
			)
		}
	}

	'label' component {
		'parts': list non-empty {
			'type': stategroup (
				'static text' {
					'text': text
				}
				'dynamic text' {
					'text': text binding { }
				}
				'dynamic number' {
					'number': number binding { }
				}
			)
		}
	}

	'planning' component {
		'label': text
		'has permissions': stategroup @default: 'no' (
			'yes' feature 'permissions'
			'no' { }
		)
		'default zoom level': feature 'zoom level'
		'has more zoom levels': stategroup @default: 'no' (
			'yes' {
				'zoom levels': list non-empty feature 'zoom level'
			}
			'no' { }
		)
		'type': stategroup @default: 'default' (
			'default' { }
			'specific start and end' feature 'start and end'
		)
		'windows': list non-empty {
			'label': text
			'rows': feature 'planning rows'
		}
		'global commands': list {
			'command': command binding { }
		}
		'has holidays': stategroup @default: 'no' (
			'yes' {
				'holidays': collection binding {
					'holiday': text binding { }
					'start and end': feature 'start and end'
					'highlight background': stategroup @default: 'yes' (
						'yes' { }
						'state dependent' {
							'stategroup': stategroup binding {
								'state to highlight': state binding { }
							}
						}
						'no' { }
					)
				}
			}
			'no' { }
		)
	}

	'planning rows' component {
		'rows': collection binding {
			'label': feature 'label'
			'options': feature 'row options'
			'items': feature 'planning items'
			'has background items': stategroup @default: 'no' (
				'yes' feature 'planning background items'
				'no' { }
			)
			'has children': stategroup @default: 'no' (
				'yes' feature 'planning rows'
				'no' { }
			)
		}
		'has bottom rows': stategroup @default: 'no' (
			'yes' feature 'planning custom rows'
			'no' { }
		)
	}

	'planning items' component {
		'items': collection binding {
			'has label': stategroup (
				'yes' feature 'label'
				'no' { }
			)
			'start and end': feature 'start and end'
			'options': feature 'item options'
			'foreground options': feature 'foreground item options'
		}
	}

	'planning background items' component {
		'items': collection binding {
			'has label': stategroup @default: 'no' (
				'yes' feature 'label'
				'no' { }
			)
			'start and end': feature 'start and end'
			'options': feature 'item options'
		}
	}

	'planning custom rows' component {
		'rows': list {
			'label': feature 'label'
			'has tooltip': stategroup @default: 'no' (
				'yes' feature 'label'
				'no' { }
			)
			'items': feature 'planning items'
			'has background items': stategroup @default: 'no' (
				'yes' feature 'planning background items'
				'no' { }
			)
		}
	}

	'start and end' component {
		'start': number binding { }
		'end': number binding { }
	}

	'row options' component {
		'is reference set': stategroup @default: 'no' (
			'yes' {
				'reference': text binding { }
			}
			'no' { }
		)
		'has right label': stategroup @default: 'no' (
			'yes' {
				'label': feature 'label'
				'has tooltip': stategroup @default: 'no' (
					'yes' feature 'label'
					'no' { }
				)
			}
			'no' { }
		)
		'has filters': stategroup @default: 'no' (
			'yes' feature 'filters'
			'no' { }
		)
		'has tooltip': stategroup @default: 'no' (
			'yes' feature 'label'
			'no' { }
		)
		'filter start and end': stategroup @default: 'no' (
			'yes' feature 'start and end'
			'no' { }
		)
		'has popup': stategroup @default: 'no' (
			'yes' feature 'popup'
			'no' { }
		)
		'can create entry': stategroup @default: 'no' (
			'yes' {
				'create': command binding {
					'start': number binding { }
					'end': number binding { }
					'snap': feature 'snap'
				}
				'has alternative create command': stategroup @default: 'no' (
					'yes' {
						'create': command binding {
							'start': number binding { }
							'end': number binding { }
							'snap': feature 'snap'
						}
					}
					'no' { }
				)
				'draggable': stategroup (
					'yes' { }
					'no' { }
				)
			}
			'no' { }
		)
		'can be partitioned': stategroup @default: 'no' (
			'yes' feature 'partitions'
			'no' { }
		)
		'hide row when it has no items or child rows': stategroup @default: 'no' (
			'yes' { }
			'no' { }
		)
	}

	'item options' component {
		'is reference set': stategroup @default: 'no' (
			'yes' {
				'reference': text binding { }
			}
			'no' { }
		)
		'has filters': stategroup @default: 'no' (
			'yes' feature 'filters'
			'no' { }
		)
		'has tooltip': stategroup @default: 'no' (
			'yes' feature 'label'
			'no' { }
		)
		'has context menu': stategroup @default: 'no' (
			'yes' feature 'context menu'
			'no' { }
		)
	}

	'foreground item options' component {
		'draggable': stategroup @default: 'no' (
			'yes' feature 'draggable'
			'no' { }
		)
		'has popup': stategroup @default: 'no' (
			'yes' feature 'popup'
			'no' { }
		)
		'has icon bar': stategroup @default: 'no' (
			'yes' feature 'icon bar'
			'no' { }
		)
	}

	'partitions' component {
		'type': stategroup (
			'static' {
				'type': stategroup (
					'text' {
						'text': text binding { }
					}
					'stategroup' {
						'stategroup': stategroup binding { }
					}
				)
			}
			'dynamic' {
				'partitions': list non-empty {
					'label': text
					'type': stategroup (
						'text' {
							'text': text binding { }
						}
						'stategroup' {
							'stategroup': stategroup binding { }
						}
					)
				}
			}
		)
	}

	'filters' component {
		'filters': list non-empty {
			'label': text
			'type': stategroup (
				'number' {
					'number': number binding {
						'has default filter': stategroup @default: 'no' (
							'yes' {
								'relation': stategroup (
									'smaller than' { }
									'smaller than or equal to' { }
									'equal to' { }
									'greater than or equal to' { }
									'greater than' { }
								)
								'comparand': stategroup (
									'now' {
										'offset': number
									}
									'static number' {
										'criteria': number
									}
								)
							}
							'no' { }
						)
					}
				}
				'text' {
					'text': text binding {
						'has default filter': stategroup @default: 'no' (
							'yes' {
								'filter type': stategroup (
									'simple' {
										'value': text
									}
									'containment' {
										'relation': stategroup (
											'in' { }
											'not in' { }
										)
										'reference': text binding { }
									}
								)
							}
							'no' { }
						)
					}
				}
				'stategroup' {
					'stategroup': stategroup binding {
						'has default filter': stategroup @default: 'no' (
							'yes' {
								'filter type': stategroup (
									'state' { }
									'not state' { }
								)
								'state': state binding { }
							}
							'no' { }
						)
					}
				}
			)
		}
	}

	'zoom level' component unbound {
		'name': text
		'type': stategroup (
			'week' { }
			'day' {
				'show weekends': stategroup (
					'yes' { }
					'no' { }
				)
			}
			'hour' {
				'show weekends': stategroup (
					'yes' { }
					'no' { }
				)
			}
		)
	}

	'snap' component unbound {
		'snap': stategroup (
			'none' { }
			'minute' {
				'minutes': number
			}
			'day' { }
			'week' { }
			'month' { }
			'year' { }
		)
	}

	'popup' component {
		'label': feature 'label'
		'node': feature 'node'
		'has open view button': stategroup (
			'yes' {
				'label': text
			}
			'no' { }
		)
	}

	'context menu' component {
		'commands': list non-empty {
			'has icon': stategroup @default: 'no' (
				'yes' {
					'icon': text
				}
				'no' { }
			)
			'command': command binding { }
		}
	}

	'icon bar' component {
		'stategroups': list non-empty {
			'stategroup': stategroup binding {
				'states': list {
					'state': state binding {
						'has tooltip': stategroup @default: 'no' (
							'yes' feature 'label'
							'no' { }
						)
					}
				}
			}
		}
	}

	'draggable' component {
		'move': command binding {
			'start': number binding { }
			'can switch row': stategroup @default: 'no' (
				'yes' {
					'row': text binding { }
				}
				'no' { }
			)
			'snap': feature 'snap'
		}
		'has alternative move command': stategroup @default: 'no' (
			'yes' {
				'move': command binding {
					'start': number binding { }
					'can switch row': stategroup @default: 'no' (
						'yes' {
							'row': text binding { }
						}
						'no' { }
					)
					'snap': feature 'snap'
				}
			}
			'no' { }
		)
	}

	'node' component {
		'entries': list non-empty {
			'type': stategroup (
				'number' {
					'number': number binding { }
				}
				'text' {
					'text': text binding { }
				}
				'stategroup' {
					'stategroup': stategroup binding {
						'states': list {
							'state': state binding {
								'has node': stategroup @default: 'no' (
									'yes' feature 'node'
									'no' { }
								)
							}
						}
					}
				}
				'file' {
					'file': file binding { }
				}
				'command' {
					'command': command binding { }
				}
				'query' {
					'label': feature 'label'
					'query': query binding { }
				}
				'chart' {
					'label': feature 'label'
					'type': stategroup (
						'range' {
							'range': feature 'range'
						}
						'pie chart' {
							'chart': feature 'pie chart'
						}
						'bar chart' {
							'chart': feature 'bar chart'
						}
						'line chart' {
							'chart': feature 'line chart'
						}
						'scatter chart' {
							'chart': feature 'scatter chart'
						}
						'radar chart' {
							'chart': feature 'radar chart'
						}
					)
				}
			)
		}
	}

collection-features

stategroup-features

number-features

text-features

file-features

Handheld

The handheld generator.

global-features

node-features

collection-features

stategroup-features

number-features

text-features

file-features

Production

The production generator.

global-features

node-features

collection-features

stategroup-features

number-features

text-features

file-features

Annotations

Global Features

Configure global features provided by the selected generator.

'has global features': stategroup (
	'yes' {
		'configured features': dictionary { [ feature ]
			'has more features': stategroup = node-switch successor (
				| node = 'yes' { 'next feature' = successor }
				| none = 'no'
			)
			'feature': component 'feature'
		}
	}
	'no' { }
)

Handheld Menu

'handheld menu': stategroup (
	'yes' { [ handheld-menu (, ) ]
		'items': dictionary {
			'icon': [ icon: ] text
			'view': component 'handheld view selector'
			'has more items': stategroup = node-switch successor (
				| node = 'yes' { 'next item' = successor }
				| none = 'no'
			)
		}
	}
	'no' { }
)

Sparse Annotation Tree

The root node of the annotations.

'annotations': component 'extended annotations'
'singular path' {
	'has steps': stategroup (
		'yes' {
			'type': stategroup (
				'group' {
					'group': [ . ] reference
				}
			)
			'tail': component 'singular path'
		}
		'no' { }
	)
}
'conditional path' {
	'head': component 'singular path'
	'has steps': stategroup (
		'yes' {
			'type': stategroup (
				'state' {
					'state group': [ . ] reference
					'state': [ ? ] reference
				}
			)
			'tail': component 'conditional path'
		}
		'no' { }
	)
}
'collection path' {
	'head': component 'conditional path'
	'collection': [ ., [] ] reference
	'has more steps': stategroup (
		'yes' {
			'tail': component 'collection path'
		}
		'no' { }
	)
}
'query path' {
	'has steps': stategroup (
		'yes' {
			'type': stategroup (
				'parent' { [ ^ ] }
				'reference' {
					'reference': [ > ] reference
					'result': stategroup (
						'referenced node' { }
						'rule' {
							'rule': [ $ ] reference
						}
					)
				}
				'group' {
					'group': [ + ] reference
				}
				'state' {
					'state group': [ ? ] reference
					'state': [ | ] reference
				}
			)
			'tail': component 'query path'
		}
		'no' { }
	)
}

Annotation Node

'extended annotations' { [ (, ) ]
	'node features': component 'features matrix'
	'has handheld frames': stategroup (
		'yes' {
			'handheld frames': dictionary { [ handheld: ]
				'frame': component 'handheld view frame'
			}
			'main frame': reference = first
		}
		'no' { }
	)
	'properties': dictionary {
		'type': [ : ] stategroup (
			'command' { [ command ]
				'annotations': component 'extended annotations'
			}
			'action' { [ action ]
				'annotations': component 'extended annotations'
			}
			'group' { [ group ]
				'annotations': component 'extended annotations'
			}
			'reference set' { [ reference-set ]
				'has custom queries': stategroup (
					'yes' {
						'custom queries': dictionary { [ query ]
							'has more queries': stategroup = node-switch successor (
								| node = 'yes' { 'next query' = successor }
								| none = 'no'
							)
							'query': component 'custom query'
						}
					}
					'no' { }
				)
			}
			'collection' { [ collection ]
				'entries are custom properties': stategroup (
					'yes' { [ @properties ]
						'type': stategroup (
							'value' {
								'value attribute': [ value: ] reference
							}
							'node' { [ node ] }
						)
					}
					'no' { }
				)
				'show as list': stategroup (
					'yes' { [ @list: ]
						'property': [ . ] reference
					}
					'no' { }
				)
				'has custom queries': stategroup (
					'yes' {
						'custom queries': dictionary { [ query ]
							'has more queries': stategroup = node-switch successor (
								| node = 'yes' { 'next query' = successor }
								| none = 'no'
							)
							'query': component 'custom query'
						}
					}
					'no' { }
				)
				'collection features': component 'features matrix'
				'sub tree': stategroup (
					'yes' {
						'annotations': component 'extended annotations'
					}
					'no' { }
				)
			}
			'stategroup' { [ stategroup ]
				'stategroup features': component 'features matrix'
				'states': [ (, ) ] dictionary { [ | ]
					'annotations': component 'extended annotations'
				}
			}
			'number' { [ number ]
				'number features': component 'features matrix'
			}
			'text' { [ text ]
				'text features': component 'features matrix'
			}
			'file' { [ file ]
				'file features': component 'features matrix'
			}
		)
	}
}
'features matrix' {
	'configured features': dictionary { [ feature ]
		'has more features': stategroup = node-switch successor (
			| node = 'yes' { 'next feature' = successor }
			| none = 'no'
		)
		'feature': component 'feature'
	}
}
'feature' {
	'properties': component 'feature properties'
}
'feature properties' {
	'properties': [ (, ) ] dictionary {
		'type': [ = ] stategroup (
			'binding' {
				'type': stategroup (
					'user' { [ user ] }
					'node' { [ node ]
						'path': component 'query path'
					}
					'collection' { [ collection ]
						'path': component 'query path'
						'collection': [ . ] reference
					}
					'stategroup' { [ stategroup ]
						'path': component 'query path'
						'stategroup': [ . ] reference
					}
					'state' { [ state ]
						'state': reference
					}
					'number' { [ number ]
						'path': component 'query path'
						'number': [ . ] reference
					}
					'text' { [ text ]
						'path': component 'query path'
						'text': [ . ] reference
					}
					'file' { [ file ]
						'path': component 'query path'
						'file': [ . ] reference
					}
					'command' { [ command ]
						'path': component 'query path'
						'command': [ . ] reference
					}
					'action' { [ action ]
						'path': component 'query path'
						'action': [ . ] reference
					}
					'query' { [ query ]
						'path': component 'collection path'
						'query': component 'custom query'
					}
					'query property' { [ query property ]
						'property': reference
					}
					'query stategroup' { [ query stategroup ]
						'property': reference
					}
					'query number' { [ query number ]
						'property': reference
					}
					'query text' { [ query text ]
						'property': reference
					}
					'query file' { [ query file ]
						'property': reference
					}
				)
				'properties': component 'feature properties'
			}
			'configuration' {
				'type': stategroup (
					'list' {
						'properties': [ [, ] ] component 'feature properties list'
					}
					'stategroup' {
						'state': reference
						'properties': component 'feature properties'
					}
					'number' {
						'value': integer
					}
					'text' {
						'value': text
					}
				)
			}
			'feature' {
				'properties': component 'feature properties'
			}
		)
	}
}
'feature properties list' {
	'has entry': stategroup (
		'yes' {
			'entry': component 'feature properties'
			'tail': component 'feature properties list'
		}
		'no' { }
	)
}
'custom query' {
	'custom limit': stategroup (
		'yes' { [ limit: ]
			'sample': stategroup (
				'yes' {
					'sample size': integer
					'sample limit': [ /, / ] integer
				}
				'no' { }
			)
			'absolute limit': integer
		}
		'no' { }
	)
	'properties': [ [, ] ] dictionary {
		'has more properties': stategroup = node-switch successor (
			| node = 'yes' { 'next property' = successor }
			| none = 'no'
		)
		'context path': [ -> ] component 'query path'
		'type': [ : ] stategroup (
			'stategroup' { [ stategroup ]
				'property': reference
				'filter': stategroup (
					'yes' { [ filter ]
						'states': [ ? ] dictionary { [ | ]
							'is selected': stategroup (
								'yes' { [ selected ] }
								'no' { }
							)
						}
					}
					'simple' { [ filter simple ] }
					'no' { }
				)
			}
			'number' { [ number ]
				'property': reference
				'filter': stategroup (
					'yes' { [ filter ]
						'operator': stategroup (
							'smaller' { [ < ] }
							'smaller equal' { [ <= ] }
							'greater' { [ > ] }
							'greater equal' { [ >= ] }
							'equal' { [ == ] }
						)
						'criteria': stategroup (
							'now' { [ now ]
								'offset': [ + ] integer
							}
							'static' {
								'value': integer
							}
						)
					}
					'simple' { [ filter simple ] }
					'no' { }
				)
			}
			'text' { [ text ]
				'property': reference
				'filter': stategroup (
					'yes' { [ filter ]
						'criteria': text
					}
					'simple' { [ filter simple ] }
					'containment' { [ filter, selection ]
						'operator': stategroup (
							'in' { [ in ] }
							'not in' { [ not in ] }
						)
					}
					'no' { }
				)
			}
			'file' { [ file ]
				'property': reference
			}
			'action' { [ action ]
				'attribute': reference
			}
			'command' { [ command ]
				'attribute': reference
			}
		)
	}
	'custom sorting': stategroup (
		'yes' {
			'direction': stategroup (
				'ascending' { [ @ascending: ] }
				'descending' { [ @descending: ] }
			)
			'type': stategroup (
				'number' {
					'number': [ # ] reference
				}
				'text' {
					'text': [ . ] reference
				}
			)
		}
		'no' { }
	)
}

Handheld

'annotated collection selector' {
	'has step': stategroup (
		'yes' {
			'property': [ . ] reference
			'type': stategroup (
				'group' { }
				'collection' { [ [] ] }
				'state' {
					'state': [ ? ] reference
				}
			)
			'tail': component 'annotated collection selector'
		}
		'no' {
			'property': [ ., [] ] reference
		}
	)
}
'handheld frame selector' {
	'type': stategroup (
		'inline' {
			'frame': component 'handheld view frame'
		}
		'annotated' {
			'frame': reference
		}
	)
}
'handheld view details' {
	'title': stategroup (
		'yes' {
			'property': [ title: ] component 'handheld view descriptor'
		}
		'no' { }
	)
	'fields': dictionary {
		'has more fields': stategroup = node-switch successor (
			| node = 'yes' { 'next field' = successor }
			| none = 'no'
		)
		'emphasis': [ : ] stategroup (
			'yes' { [ @emphasis ] }
			'no' { }
		)
		'property': component 'handheld view descriptor'
	}
}
'handheld view elements' {
	'has element': stategroup (
		'yes' {
			'type': [ -> ] stategroup (
				'label' { [ label: ]
					'text': reference
				}
				'inline view' { [ inline view: ]
					'frame': component 'handheld frame selector'
				}
				'view' {
					'view': component 'handheld view selector'
				}
			)
			'tail': component 'handheld view elements'
		}
		'no' { }
	)
}
'handheld view frame' {
	'type': stategroup (
		'decision' { [ (, ) ]
			'options': dictionary {
				'has more options': stategroup = node-switch successor (
					| node = 'yes' { 'next option' = successor }
					| none = 'no'
				)
				'emphasis': [ : ] stategroup (
					'low' { }
					'medium' { [ @emphasis: medium ] }
					'high' { [ @emphasis: high ] }
				)
				'frame': component 'handheld frame selector'
			}
		}
		'collection navigation' { [ collection (, ) ]
			'collection context': [ path: ] stategroup (
				'this' { }
				'root' { [ root ] }
			)
			'path': component 'annotated collection selector'
			'annotations': group {
				'header': stategroup (
					'yes' { }
					'no' { [ @no-header ] }
				)
				'layout': stategroup (
					'set' { [ @layout: ]
						'type': stategroup (
							'tabular' { [ tabular ] }
							'cards' { [ cards ] }
							'buttons' { [ buttons ] }
							'partition' { [ partition ]
								'path': [ on ] component 'query path'
								'property': [ . ] reference
								'type': stategroup (
									'simple' { }
									'year' { [ by, year ] }
									'month' { [ by, month ] }
									'week' { [ by, week ] }
									'day' { [ by, day ] }
									'hour' { [ by, hour ] }
								)
							}
						)
					}
					'default' { }
				)
			}
			'details': stategroup (
				'yes' {
					'details': component 'handheld view details'
				}
				'no' {
					'property': [ label: ] component 'handheld view descriptor'
				}
			)
			'filters': stategroup (
				'yes' { [ filters: ]
					'fields': dictionary {
						'has more fields': stategroup = node-switch successor (
							| node = 'yes' { 'next field' = successor }
							| none = 'no'
						)
						'path': [ : ] component 'query path'
						'property': [ . ] reference
						'type': stategroup (
							'stategroup' {
								'filter': stategroup (
									'state' {
										'state': [ is ] reference
									}
									'not state' {
										'state': [ is not ] reference
									}
									'states' {
										'states': [ is (, ) ] dictionary { }
									}
									'simple' { [ stategroup ] }
								)
							}
							'number' {
								'filter': stategroup (
									'match' {
										'operator': stategroup (
											'smaller' { [ smaller ] }
											'smaller equal' { [ smaller or equal ] }
											'greater' { [ greater ] }
											'greater equal' { [ greater or equal ] }
											'equal' { [ equal ] }
										)
										'type': [ than ] stategroup (
											'now' { [ now + ] }
											'static' { }
										)
										'offset': integer
									}
									'simple' { [ number ] }
								)
							}
							'text' {
								'filter': stategroup (
									'pattern' {
										'criteria': [ match ] text
									}
									'simple' { [ text ] }
									'current node' { [ this ] }
									'containment' { [ filter, selection ]
										'operator': stategroup (
											'in' { [ in ] }
											'not in' { [ not in ] }
										)
									}
								)
							}
						)
					}
				}
				'no' { }
			)
			'sort': stategroup (
				'yes' { [ sort: ]
					'path': component 'query path'
					'property': component 'handheld view property'
					'direction': stategroup (
						'ascending' { [ ascending ] }
						'descending' { [ descending ] }
					)
				}
				'no' { }
			)
			'action': stategroup (
				'yes' { [ view: ]
					'emphasis': stategroup (
						'low' { }
						'medium' { [ @emphasis: medium ] }
						'high' { [ @emphasis: high ] }
					)
					'view': component 'handheld view selector'
				}
				'no' { }
			)
		}
		'group navigation' {
			'property': [ . ] reference
			'frame': component 'handheld frame selector'
		}
		'state navigation' {
			'property': [ . ] reference
			'state': [ ? ] reference
			'frame': component 'handheld frame selector'
		}
		'reference navigation' {
			'text': [ > ] reference
			'frame': component 'handheld frame selector'
		}
		'pivot view' { [ pivot (, ) ]
			'options': group { dynamic-order
				'show crosshair': stategroup (
					'yes' { [ @crosshair ] }
					'no' { }
				)
				'show grid': stategroup (
					'yes' { [ @grid ] }
					'no' { }
				)
			}
			'columns': [ columns: . ] reference
			'column grouping': [ : ] reference
			'column label': [ label: ] component 'handheld view descriptor'
			'cells': [ cells: . ] reference
			'row grouping': [ : ] reference
			'row label': [ label: ] component 'handheld view descriptor'
			'content': stategroup (
				'inline view' { [ inline view: ]
					'frame': component 'handheld frame selector'
				}
				'label' { [ label: ]
					'property': component 'handheld view descriptor'
				}
			)
		}
		'detail view' { [ details (, ) ]
			'details': component 'handheld view details'
			'elements': component 'handheld view elements'
		}
		'command view' { [ command (, ) ]
			'details': component 'handheld view details'
			'selection': [ view: ] stategroup (
				'button' {
					'emphasis': stategroup (
						'low' { }
						'medium' { [ @emphasis: medium ] }
						'high' { [ @emphasis: high ] }
					)
				}
				'scan' { [ @scan (, ) ]
					'referencer': group {
						'path': component 'conditional path'
						'collection': [ ., [] ] reference
					}
					'path': [ using: ] component 'conditional path'
					'search property': [ . ] reference
				}
			)
			'view': component 'handheld view selector'
		}
	)
}
'handheld view descriptor' {
	'type': stategroup (
		'dynamic' {
			'property': component 'handheld view property selector'
		}
		'static text' {
			'text': reference
		}
		'icon' {
			'icon name': [ icon: ] text
		}
	)
	'has tail': stategroup (
		'yes' { [ , ]
			'tail': component 'handheld view descriptor'
		}
		'no' { }
	)
}
'handheld view property' {
	'property': [ . ] reference
	'style': stategroup (
		'default' { }
		'barcode' { [ @barcode: ]
			'barcode type': stategroup (
				'CODE128' { [ CODE128 ] }
				'CODE128A' { [ CODE128A ] }
				'CODE128B' { [ CODE128B ] }
				'CODE128C' { [ CODE128C ] }
				'EAN13' { [ EAN13 ] }
				'EAN8' { [ EAN8 ] }
				'EAN5' { [ EAN5 ] }
				'EAN2' { [ EAN2 ] }
				'UPCA' { [ UPCA ] }
				'UPCE' { [ UPCE ] }
				'CODE39' { [ CODE39 ] }
				'ITF' { [ ITF ] }
				'ITF14' { [ ITF14 ] }
				'MSI10' { [ MSI10 ] }
				'MSI11' { [ MSI11 ] }
				'MSI1010' { [ MSI1010 ] }
				'MSI1110' { [ MSI1110 ] }
				'Pharmacode' { [ Pharmacode ] }
				'Codabar' { [ Codabar ] }
			)
		}
		'qrcode' { [ @qrcode ] }
	)
}
'handheld view property selector' {
	'type': stategroup (
		'switch' {
			'stategroup': [ . ] reference
			'states': [ (, ) ] dictionary { [ | ]
				'tail': component 'handheld view property selector'
			}
		}
		'step' {
			'type': stategroup (
				'group' {
					'group': [ . ] reference
				}
				'state' {
					'stategroup': [ . ] reference
					'state': [ ? ] reference
				}
				'reference' {
					'text': [ > ] reference
				}
				'parent' { [ ^ ] }
			)
			'tail': component 'handheld view property selector'
		}
		'property' {
			'property': component 'handheld view property'
		}
	)
}
'handheld command annotations' { [ (, ) ]
	'properties': dictionary {
		'type': [ : ] stategroup (
			'group' { [ group ]
				'parameters': component 'handheld command annotations'
			}
			'collection' { [ collection ]
				'parameters': component 'handheld command annotations'
			}
			'stategroup' { [ stategroup (, ) ]
				'states': dictionary {
					'parameters': component 'handheld command annotations'
				}
			}
			'text' { [ text ]
				'style': stategroup (
					'buttons' { [ @button ] }
					'keyboard' { [ @keyboard ] }
					'default' { }
					'scan' { [ @scan using: ]
						'path': component 'conditional path'
						'search property': [ . ] reference
					}
				)
			}
		)
	}
}
'handheld view context' {
	'has step': stategroup (
		'yes' { [ ^ ]
			'tail': component 'handheld view context'
		}
		'no' { }
	)
}
'handheld view selector' {
	'type': stategroup (
		'switch' {
			'property': [ . ] reference
			'states': [ (, ) ] dictionary { [ | ]
				'tail': component 'handheld view selector'
			}
		}
		'step' {
			'type': stategroup (
				'group' {
					'property': [ . ] reference
				}
				'state' {
					'property': [ . ] reference
					'state': [ ? ] reference
				}
				'reference' {
					'text': [ > ] reference
				}
			)
			'tail': component 'handheld view selector'
		}
		'command' {
			'command': [ command: ] reference
			'annotations': group { dynamic-order
				'auto execute': stategroup (
					'yes' { [ @auto-execute ] }
					'no' { }
				)
				'close after execute': stategroup (
					'yes' { }
					'no' { [ @keep-open ] }
				)
				'emphasis': stategroup (
					'low' { }
					'medium' { [ @emphasis: medium ] }
					'high' { [ @emphasis: high ] }
				)
			}
			'parameter annotations': stategroup (
				'yes' {
					'parameters': component 'handheld command annotations'
				}
				'no' { }
			)
			'open view': stategroup (
				'yes' { [ and ]
					'context': component 'handheld view context'
					'frame': component 'handheld frame selector'
				}
				'no' { }
			)
			'has details': stategroup (
				'no' { }
				'yes' { [ details (, ) ]
					'details': component 'handheld view details'
					'elements': component 'handheld view elements'
				}
			)
		}
		'view' {
			'emphasis': [ : ] stategroup (
				'low' { }
				'medium' { [ @emphasis: medium ] }
				'high' { [ @emphasis: high ] }
			)
			'context': component 'handheld view context'
			'frame': component 'handheld frame selector'
			'title': stategroup (
				'custom' { [ title: ]
					'property': component 'handheld view descriptor'
				}
				'default' { }
			)
		}
	)
}