| Handle for a button of the control widget | DIALOG.control.ok.enabled = False |
+
+#### Control widget elements
+
+💡 The names of the **Control** widget elements are fixed
+
+* Usually, the names are corresponding with the elements' semantics. For example, the name of the **ok** button is 'ok'. The names can also be obtained from the `__doc__` string as shown in the code example below.
+* The control elements are accessed like all other widget attributes.
+
+```{code-block} python
+:caption: Accessing the control widget
+
+# Print control widget properties print (DIALOG.control.__doc__)
+ControlGroup
+
+Attributes:
+
+status (string) - Status tool tip icon
+ok (unspecified/various) - Control widget
+cancel (unspecified/various) - Control widget
+```
+
+#### Control button properties
+
+Control buttons only have the following two properties which can be set programmatically:
+
+| Property | Type | Example |
+| -------- | ---- | ------------------------------------------------ |
+| text | str | DIALOG.control.prev.text = 'Previous' |
+| enabled | bool | DIALOG.control.ok.enabled = False |
+
+#### Status label
+
+⚠️ The **Status label** of the control widget is invisible until a status text is set.
+
+* If a status text is set, a small warning icon appears, like in regular applications' dialogs.
+* The status label can be configured using its properties like all other widgets.
+
+![](assets/control_widget_status_label.png)
+
+```{code-block} python
+:caption: Using the Status label
+
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+
+# Set status label text
+DIALOG.control.status = 'No point selected.'
+
+# Set 'ok' button to disabled DIALOG.control.ok.enabled = False
+gom.script.sys.show_user_defined_dialog(dialog = DIALOG)
+
+```
+
+You can reset the status icon and clear the error message by assigning an empty string (`DIALOG.control.status = ''`).
+
+### Specific widgets
+
+#### Description field (label) widget
+
+![](assets/widget_label.png)
+
+Description field (label) widget
+: The Description field (label) widget allows to display static text. It is typically used for labelling a section or an individual element of a dialog.
+
+| Property | Type | Example |
+| --------- | ----- | ------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.label.tooltip = 'This is just a label!' |
+| enabled | bool | DIALOG.label.enabled = False |
+| focus | bool | DIALOG.label.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.label.visible = False |
+| text | str | DIALOG.label.text = 'New label:' |
+| word_wrap | bool | DIALOG.label.word_wrap = True |
+
+
+#### Continuous text widget
+
+![](assets/text_field.png)
+
+Continuous text widget
+: The Continuous text widget allows to display static text and keywords. A double click onto a text field widget opens the content editor. Some formatting can be applied.
+
+| Editor | Dialog |
+| -------------------------- | --------------------------- |
+| ![](assets/edit_text.png) | ![](assets/widget_text.png) |
+
+
+%* The keywords displayed in text field widgets can originate from different source:
+%
+% * Global application keywords
+%
+% * project related keywords
+%
+% * local script variables.
+%
+%⚠️ Local script variables can be displayed in text fields by inserting them via the 'insert expression' dialog.
+%
+% * Local script variables are invalid until the variable assignment is reached. They cannot be displayed statically in the text
+% field editor prior to script execution, so an invalid value will most certainly be displayed instead.
+%
+% To Do: Check how to insert local variables
+
+| Property | Type | Example |
+| ------------------- | ---- | ---------------------------------------------------------- |
+| enabled | bool | DIALOG.textWidget.enabled = False |
+| text | str | print(DIALOG.textWidget.text) |
+| wordwrap | bool | DIALOG.textWidget.wordwrap = True |
+| visible | bool | DIALOG.textWidget.visible = False |
+| default_font_family | str | DIALOG.textWidget.default_font_family = 'Arial Black' |
+| default_font_size | int | DIALOG.textWidget.default_font_size = 12 |
+
+##### Displaying keywords in a continuous text widget
+
+A keyword can be inserted into the text with the following procedure:
+
+1. RMB -> 'Insert Expression...'
+
+ ![](assets/widget_text_insert_expression1.png)
+
+2. Select 'Insert Keyword' button
+
+ ![](assets/widget_text_insert_expression2.png)
+
+3. Select the desired keyword from the tree
+
+ ![](assets/widget_text_insert_expression3.png)
+
+4. The keyword and its actual value are shown
+
+ ![](assets/widget_text_insert_expression4.png)
+
+5. The final rendering of the text widget
+
+ ![](assets/widget_text_insert_expression6.png)
+
+##### Internal representation of a dialog with text widget
+
+The dialog is stored as a JSON document internally.
+
+![](assets/text_field.png)
+
+```{code-block} python
+:caption: Internal representation of a dialog
+
+gom.script.sys.execute_user_defined_dialog (dialog={
+ "content": [
+ [
+ {
+ ...
+ },
+ {
+ "columns": 1,
+ "default_font_family": "",
+ "default_font_size": 0,
+ "name": "text",
+ "rows": 1,
+ "text": {
+ "id": "",
+ "text": "\\By clicking 'Close', the dialog will be closed.\
\",
+ "translatable": True
+ },
+ ...
+ "type": "display::text",
+ "wordwrap": False
+ }
+ ]
+ ],
+ "control": {
+ "id": "Close"
+ },
+ ...
+})
+```
+
+#### Image widget
+
+![](assets/widget_image.png)
+
+Image widget
+: The Image widget allows to display arbitrary images.
+
+
+| Property | Type | Example |
+| ------------------ | --------- | ------------------------------------------------------------ |
+| enabled | bool | DIALOG.image.enabled = False |
+| use_system_image | bool | DIALOG.image.use_system_image = True |
+| system_image | str | # Possible values: 'system_message_information', 'system_message_warning', 'system_message_critical', 'system_message_question' DIALOG.image.system_image = 'system_message_question' |
+| file_name | str | read-only! |
+| keep_original_size | bool | read-only! |
+| keep_aspect | bool | read-only! |
+| data | (special) | # This is the actual image data # Copy image from one dialog to another: my_dialog.my_image.data = image_container_dialog.image_1.data |
+| width | int | print('image width ' + str(DIALOG.image.width)) |
+| height | int | print('image height ' + str(DIALOG.image.height)) |
+| visible | bool | DIALOG.image.visible = False |
+
+Note that you can switch from a system image to a user image using the property `use_system_image`. But this user image must have been selected beforehand in the designer. You cannot read a new image file by setting the `filename` property. Also, all of the image formatting properties (`keep_original_size`, `keep_aspect`, `width`, `height`) only work in the designer. From the script you can only read these values. Although you cannot read images using the `filename` property you can copy images from one dialog to another using the `data` property. So you are able to prepare (create) a dialog as an image container holding several images. You can then use this image container dialog to copy the image you need to an actually displayed dialog.
+
+##### Internal representation of a dialog with image widget
+
+The dialog is stored as a JSON document internally. The 'data' element contains the image data.
+
+```{code-block} python
+:caption: Internal representation of an image
+
+# The 'data' element contains the image data (shortened version here)
+RESULT=gom.script.sys.execute_user_defined_dialog (dialog={
+ "content": [
+ [
+ {
+ "columns": 1,
+ "data": "AAAAAYlQTkcNChoKAAAADUlIRFIAAAQAAAACQAgCAAAAnPeDgptZSsdt...",
+ "file_name": "C:/Users/IQMPRINK/Downloads/zeiss-inspect_python.jpg",
+ "height": 144,
+ "keep_aspect": True,
+ "keep_original_size": False,
+ "name": "image",
+ "rows": 1,
+ "system_image": "system_message_information",
+ "tooltip": {
+ "id": "",
+ "text": "",
+ "translatable": True
+ },
+ "type": "image",
+ "use_system_image": False,
+ "width": 256
+ }
+ ]
+ ],
+ "control": {
+ "id": "Close"
+ },
+ "embedding": "always_toplevel",
+ "position": "automatic",
+ "size": {
+ "height": 233,
+ "width": 292
+ },
+ "sizemode": "automatic",
+ "style": "",
+ "title": {
+ "id": "",
+ "text": "Dialog with image",
+ "translatable": True
+ }
+})
+```
+
+#### Log widget
+
+![](assets/widget_log.png)
+
+Log widget
+: The Log widget can display multiple lines of unformatted text, which can be easily saved to a text file by clicking the save button.
+
+
+| Property | Type | Example |
+| -------------------- | --------- | -------------------------------------------------------------- |
+| enabled | bool | DIALOG.log.enabled = True |
+| text | str | DIALOG.log.text += 'Yet another log message.\n |
+| word_wrap | bool | DIALOG.log.word_wrap = True |
+| show_save | bool | DIALOG.log.show_save = False |
+| save_dialog_title | str | DIALOG.log.save_dialog_title = 'Save operator log' |
+| scroll_automatically | bool | DIALOG.log.scroll_automatically = True |
+| visible | bool | DIALOG.log.visible = False |
+| monospace | bool | # Use monospace font DIALOG.log.monospace = True |
+
+#### Progress bar widget
+
+![](assets/widget_progressbar.png)
+
+Progress bar widget
+: The Progress bar widget can be used in the two modes _system_ and _manual_.
+
+Manual mode
+: In this mode, the user may set the progress bar through its `value` variable.
+
+ ```{code-block} python
+ import gom, time
+ DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+ DIALOG.progress.minimum = 0
+ DIALOG.progress.maximum = 100
+ gom.script.sys.open_user_defined_dialog( dialog = DIALOG )
+ DIALOG.progress.value = 0
+ time.sleep(1)
+ DIALOG.progress.value = 33
+ time.sleep(1)
+ DIALOG.progress.value = 66
+ time.sleep(1)
+ DIALOG.progress.value = 100
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+ ```
+
+Automatic mode
+: In this mode, the progress bar displays the same progress informations as the progress bar in the lower right corner of the software.
+
+ ```{code-block} python
+ import gom
+ DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+ gom.script.sys.open_user_defined_dialog (dialog=DIALOG)
+ gom.script.sys.create_project ()
+ gom.script.sys.import_project (file='some project')
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+ ```
+
+You can switch between automatic and manual mode from within the script by setting the mode variable as shown below:
+
+```python
+# manual mode:
+DIALOG.progress.mode = "manual"
+
+# automatic mode:
+DIALOG.progress.mode = "system"
+```
+
+Partially controlled system progress bar
+: The range of a system progress bar can be divided into parts, sequentially controlled by an executed command.
+ * The progress bar range can be split into multiple parts.
+ * Each part controls an equally sized progress bar interval. If, for example, there are 3 parts, the first part ranges from 0 to 33, the second from 33 to 66 and the third from 66 to 100.
+ * When a command is executed, the command controls just the one active part of the progress bar widget.
+
+
+
+ ``` python
+ # -*- coding: utf-8 -*-
+
+ import gom
+
+ # Create a user defined dialog with a progress bar, mode 'system'
+ DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+ gom.script.sys.open_user_defined_dialog( dialog = DIALOG )
+
+ # Split progress bar into 3 parts
+ DIALOG.progress.parts = 3
+
+ # Current part is the first interval (part '0', because we are counting from '0')
+ DIALOG.progress.step = 0
+
+ # Execute load command. The command will control the first progress bar range from 0% to 33%.
+ # That means when the command has been finished, the progress bar will display '33%'.
+ gom.script.sys.load_project (file='some project')
+
+ # Current part is the second interval. The progress bar runs from 33% to 66%
+ DIALOG.progress.step = 1
+
+ gom.script.sys.switch_to_report_workspace ()
+ gom.script.report.update_report_page (
+ pages=gom.app.project.reports,
+ switch_alignment=True,
+ switch_stage=False)
+
+ # Current part is the third interval. The progress bar runs from 66% to 100%
+ DIALOG.progress.step = 2
+
+ gom.script.sys.switch_to_inspection_workspace ()
+ gom.script.sys.recalculate_all_elements ()
+ ```
+
+💡 It is possible to switch between automatic and manual mode for each part.
+
+| Property | Type | Example |
+| -------- | ----- | --------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.progressbar.tooltip = 'Work in progress!' |
+| enabled | bool | DIALOG.progressbar.enabled = False |
+| value | int | if DIALOG.progressbar.value < 50: |
+| focus | bool | DIALOG.progressbar.focus = True ⚠️ Only works if dialog is open |
+| minimum | int | DIALOG.progressbar.minimum = 20 |
+| maximum | int | DIALOG.progressbar.maximum = 50 |
+| visible | bool | DIALOG.progressbar.visible = False |
+| parts | int | # Set number of progress bar parts DIALOG.progressbar.parts = 3 |
+| step | int | # Set current step DIALOG.progressbar.step = 0 |
+| text | str | # Set text mode (none, percentage, step) DIALOG.progressbar.text = 'step' |
+| mode | str | # Set mode (system, manual) DIALOG.progressbar.mode = 'manual' |
+
+#### Element name widget
+
+![](assets/widget_element_name.png)
+
+Element name widget
+: The Element name widget is used to request an element name from the user. It is possible to select the default name (according to naming scheme, e.g. 'Point 2' if 'Point 1' already exists), or to enter an arbitrary name. `elementnameWidget` is the object name of the element name widget in the example below.
+
+```python
+# Let the user define 3 new points (the coordinates are created automatically in this example)
+for i in range(3):
+ DIALOG=gom.script.sys.create_user_defined_dialog (dialog='dialog definition')
+
+ #
+ # Event handler function called if anything happens inside of the dialog
+ #
+ def dialog_event_handler (widget):
+ pass
+
+ DIALOG.handler = dialog_event_handler
+
+ RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+
+ print (RESULT.elementnameWidget)
+
+ MCAD_ELEMENT=gom.script.primitive.create_point (
+ name=RESULT.elementnameWidget,
+ point={'point': gom.Vec3d (i+10.0, 0.0, 0.0)}
+ )
+```
+
+| Property | Type | Example |
+| -------- | ----- | ------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputEleName.tooltip = 'Enter the number of points!' |
+| enabled | bool | DIALOG.inputEleName.enabled = False |
+| value | int | DIALOG.inputEleName.value = 'Blob' |
+| focus | bool | DIALOG.inputEleName.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputEleName.visible = False |
+| basename | str | DIALOG.inputEleName.basename = 'Point' |
+| mode | str | # Mode to get the name suggestion from. ('manually', 'from_element_type', 'check_like') DIALOG.inputEleName.mode = 'from_element_type' |
+| read_only | bool | # Keep user from changing the default DIALOG.inputEleName.read_only = true |
+
+#### Integer widget
+
+![](assets/widget_integer.png)
+
+Integer widget
+: The Integer widget is used to request an integer value from the user. `integerWidget` is the object name of the integer widget in the example below.
+
+``` python
+RESULT=gom.script.sys.execute_user_defined_dialog (content='dialog definition')
+userInput = RESULT.integerWidget
+```
+
+| Property | Type | Example |
+| -------- | ------ | ---------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputInt.tooltip = 'Enter the number of points!' |
+| enabled | bool | DIALOG.inputInt.enabled = False |
+| value | int | if DIALOG.inputInt.value < 15: |
+| focus | bool | DIALOG.inputInt.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputInt.visible = False |
+| minimum | double | DIALOG.inputInt.minimum = 20 |
+| maximum | double | DIALOG.inputInt.maximum = 50 |
+
+#### Decimal widget
+
+![](assets/widget_decimal.png)
+
+Decimal widget
+: The Decimal widget is used to request a floating point value from the user. It is possible to choose the number of digits and a unit. The selectable units are the ones from the user preferences (Edit \> Application \> Settings \> Preferences) in the _Default units_ tab. `decimalWidget` is the object name of the decimal widget in the example below.
+
+``` python
+RESULT=gom.script.sys.execute_user_defined_dialog (content='dialog definition')
+userInput = RESULT.decimalWidget
+```
+
+| Property | Type | Example |
+| --------- | ------ | ------------------------------------------------------------------------ |
+| tooltip | str | DIALOG.input.tooltip = 'Enter distance between points!' |
+| enabled | bool | DIALOG.input.enabled = False |
+| value | int | if DIALOG.input.value < 15: |
+| focus | bool | DIALOG.input.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.input.visible = False |
+| minimum | double | DIALOG.input.minimum = 20 |
+| maximum | double | DIALOG.input.maximum = 50 |
+| precision | double | # Set precision to 2 decimals DIALOG.input.precision = 2 |
+| unit | str | # Set unit ID DIALOG.input.unit = 'LENGTH' |
+
+% No visible effect:
+% background_style - str - Set style sheet based background color - red, green, blue
+
+#### Text entry field
+![](assets/widget_text_entry.png)
+
+Text entry field
+: The Text entry field widget can be used to get string input from the user. A simple use case is given by the next code block. `textEntryWidget` is the object name of the widget in the example below.
+
+``` python
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+DIALOG.textEntryWidget = "some default text"
+RESULT = gom.script.sys.show_user_defined_dialog(dialog = DIALOG)
+print( RESULT.textEntryWidget ) # the user input string
+```
+
+| Property | Type | Example |
+| --------- | ----- | -------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputString.tooltip = 'Enter object description' |
+| enabled | bool | DIALOG.inputString.enabled = True |
+| value | str | DIALOG.inputString.value = "Warsaw" |
+| focus | bool | DIALOG.inputString.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputString.visible = False |
+| read_only | bool | if DIALOG.inputString.read_only: |
+| password | bool | # Hide user input by replacing each character by a dot DIALOG.inputString.password = True |
+
+#### Slider widget
+
+![](assets/widget_slider.png)
+
+Slider widget
+: The Slider widget can be used to get a float value from a certain interval from the user. `sliderWidget` is the object name of the slider widget in the example below.
+
+``` python
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+
+RESULT = gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+print( RESULT.sliderWidget ) # some text
+```
+
+| Property | Type | Example |
+| ------------- | ------ | -------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.input.tooltip = 'Drag slider to change rotation' |
+| enabled | bool | DIALOG.input.enabled = True |
+| value | str | print('Angle:', str(DIALOG.input.value)) |
+| focus | bool | DIALOG.input.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.input.visible = False |
+| minimum | double | DIALOG.input.minimum = -90 |
+| maximum | double | DIALOG.input.maximum = 90 |
+| precision | double | # Set precision to 1 decimal DIALOG.input.precision = 1 |
+| step | double | # Set step size to 15 DIALOG.input.step = 15 |
+| orientation | str | print(DIALOG.input.orientation) ⚠️ read-only |
+
+% ticks are not drawn:
+% tick_interval - double - Interval of ticks drawn
+
+
+#### Checkbox widget
+
+![](assets/widget_checkbox.png)
+
+Checkbox widget
+: The Checkbox widget can be used to get boolean input from the user. `checkboxWidget` is the object name of the checkbox widget in the example below.
+
+``` python
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+print (RESULT.checkboxWidget)
+```
+
+| Property | Type | Example |
+| --------- | ----- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputCheckbox.tooltip = 'Check this option to clear the results after evaluation.' |
+| enabled | bool | DIALOG.inputCheckbox.enabled = True |
+| value | bool | print('Evaluation enabled:', str(DIALOG.inputCheckbox.value)) |
+| title | str | DIALOG.inputCheckbox.title = 'Mirror option' |
+| visible | bool | DIALOG.inputCheckbox.visible = False |
+
+#### File widget
+
+![](assets/widget_file.png)
+
+File widget
+: By clicking the File widget, a file selection dialog is opened. This allows to select a file from the file system.
+
+
+| Property | Type | Example |
+| --------- | ----- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputFile.tooltip = 'Select a file for the protocol' |
+| enabled | bool | DIALOG.inputFile.enabled = False |
+| value | str | if DIALOG.inputFile.value != '': |
+| focus | bool | DIALOG.inputFile.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputFile.visible = False |
+| type | str | # Possible values: 'any' (any file), 'new' (not an existing file), # 'file' (an existing file), 'multi_file' (multiple existing files), # 'directory' (an existing folder) DIALOG.inputFile.type = 'any' |
+| title | str | DIALOG.inputFile.title = 'Select the location for the protocol files' |
+| default | str | DIALOG.inputFile.default = 'D:/data/default.txt' |
+| file | str | print(DIALOG.inputFile.file) |
+| file_types | list | # Show only specified file types; each list item must consist of \[\, \\] DIALOG.inputFile.file_types = \[\['*.g3d', 'Mesh data'\], \['*.stp', 'CAD data'\]\] ⚠️ ``limited`` must be set to ``True`` in order to apply the filter! |
+| limited | bool | # Limit file selection to 'file_types' DIALOG.inputFile.limited = True |
+
+% Clarify this:
+% selection_type - str - File selector type; any, directory, executable, file, multi_file
+
+#### Date widget
+
+![](assets/widget_date.png)
+
+Date widget
+: The Date widget requests a date from the user. `dateWidget` is the object name of the date widget in the example below.
+
+``` python
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+dateObject = DIALOG.dateWidget.value # date object
+print( DIALOG.dateWidget.year ) # integer
+print( DIALOG.dateWidget.month ) # integer
+print( DIALOG.dateWidget.day ) # integer
+```
+
+| Property | Type | Example |
+| ----------------- | --------- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputDate.tooltip = 'Enter fabrication date' |
+| enabled | bool | DIALOG.inputDate.enabled = False |
+| value | (special) | print('Selected date:', str(DIALOG.inputDate.value)) |
+| focus | bool | DIALOG.inputDate.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputDate.visible = False |
+| use_current_date | bool | DIALOG.inputDate.use_current_date = True 💡 if set, use current date to initialize widget. |
+| year | int | DIALOG.inputDate.year = 2014 |
+| month | int | DIALOG.inputDate.month = 12 |
+| day | int | DIALOG.inputDate.day = 24 |
+| show_today_button | bool | DIALOG.inputDate.show_today_button = True |
+
+
+#### Color widget
+
+![](assets/widget_color.png)
+
+Color widget
+: The Color widget allows to select a color. `colorWidget` is the object name of the color widget in the example below. `gomColor` behaves in the same way as `gom.Color( ... )`.
+
+``` python
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+
+#
+# Event handler function called if anything happens inside of the dialog
+#
+def dialog_event_handler (widget):
+ if widget == DIALOG.colorWidget:
+ gomColor = DIALOG.colorWidget.color
+ print( gomColor) # output: gom.Color (#ffffffff)
+
+DIALOG.handler = dialog_event_handler
+
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+print('Selection:', RESULT.colorWidget) # example output (white): 0xffffffff
+```
+
+| Property | Type | Example |
+| -------------------- | --------- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputColor.tooltip = 'Select a color for the marks.' |
+| enabled | bool | DIALOG.inputColor.enabled = True |
+| value | (special) | print('Mark color:', str(DIALOG.inputColor.value)) |
+| focus | bool | DIALOG.inputColor.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputColor.visible = False |
+| transparency_allowed | bool | DIALOG.inputColor.transparency_allowed = True |
+
+#### Unit widget
+
+![](assets/widget_unit.png)
+
+Unit widget
+: The Unit widget allows to select a unit. `unitWidget` is the object name of the color widget in the example below.
+
+``` python
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+
+#
+# Event handler function called if anything happens inside of the dialog
+#
+def dialog_event_handler (widget):
+ if widget == DIALOG.unitWidget:
+ unit = DIALOG.unitWidget.value
+ print( unit) # ANGLE
+
+DIALOG.handler = dialog_event_handler
+
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+```
+
+| Property | Type | Example |
+| -------------------- | --------- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.inputUnit.tooltip = 'Select a unit.' |
+| enabled | bool | DIALOG.inputUnit.enabled = True |
+| value | (special) | print('Unit ID:', DIALOG.inputUnit.value) |
+| focus | bool | DIALOG.inputUnit.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.inputUnit.visible = False |
+
+#### Selection element widget
+
+![](assets/widget_selection_element.png)
+
+Selection element widget
+: The Selection element widget can be used to select the elements from the element explorer. The following element types can be chosen:
+ * Any Point
+ * Point element
+ * Line element
+ * Plane element
+ * Direction
+ * User-defined
+ `elementSelectionWidget` is the object name of the element selection widget in the example below.
+
+``` python
+DIALOG=gom.script.sys.execute_user_defined_dialog (content='dialog definition')
+
+selectedElement = DIALOG.elementSelectionWidget
+print(selectedElement.value ) # output: gom.app.project.inspection['Equidistant Surface Points 1']
+```
+
+| Property | Type | Example |
+| -------- | --------- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.selectElement.tooltip = 'Select a line for rotation' |
+| enabled | bool | DIALOG.selectElement.enabled = False |
+| value |(special) | if DIALOG.selectElement.value != None: |
+| focus | bool | DIALOG.selectElement.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.selectElement.visible = False |
+| supplier | str | # Read-only property # Possible values: 'any', 'points', 'lines', 'planes', 'directions', 'custom' print(DIALOG.selectElement.supplier) |
+| filter | function | Element filter function for the 'custom' supplier. See example below. |
+
+The following script shows how to use a custom filter for element selection. The example filter allows the user to select a system plane:
+
+``` python
+DIALOG4=gom.script.sys.create_user_defined_dialog (content='...')
+
+
+def dialog_event_handler (widget):
+ pass
+
+# filter system planes
+def element_filter( element ):
+ try:
+ if element.type == 'plane':
+ return True
+ except Exception as e:
+ pass
+ return False
+
+DIALOG4.handler = dialog_event_handler
+DIALOG4.input_new.filter = element_filter
+
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG4)
+
+print("Chosen system plane:", RESULT.input_new.name)
+```
+
+The complete code of the example is attached to this document.
+
+% To Do: attach example
+
+#### Selection list widget
+
+![](assets/widget_list_selection.png)
+
+Selection list widget
+: The Selection list widget allows to make a selection from a predefined set of options. The selected item can be accessed from a script through its object name (e.g. `selectionListWidget`) as follows.
+
+``` python
+selectedValue = DIALOG.selectionListWidget.value
+print( selectedValue ) # output: entry2
+```
+
+| Property | Type | Example |
+| -------- | ----------- | ---------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.selectEntry.tooltip = 'Select one of the operating modes' |
+| enabled | bool | DIALOG.selectEntry.enabled = False |
+| value | str | DIALOG.selectEntry.value = 'Debug' |
+| focus | bool | DIALOG.selectEntry.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.select_mode.visible = False |
+| items | list of str | DIALOG.selectEntry.items = ['Debug', 'Info', 'Warn', 'Error', 'Fatal'] |
+
+
+#### Button widget
+
+![](assets/widget_button_off.png)
+
+![](assets/widget_button_on.png)
+
+Button widget
+: The Button widget allows to trigger an event or to return a boolean value, respectively. There are two types of buttons: push buttons and toggle buttons. The push button is a regular button and needs an event handler to manage its action. The toggle button has two states - active and inactive - and the user can toggle between them by clicking the button. The button is highlighted in active state as shown in the screenshot. The state of the toggle button can be accessed as follows.
+
+``` python
+toggleButtonState = DIALOG.toggleButtonWidget.value
+print(toggleButtonState) # output: True
+```
+
+The buttons size and icon can be changed in the Dialog Editor.
+
+| Property | Type | Example |
+| ---------------- | ---- | --------------------------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.button.tooltip = 'Click to start evaluation' |
+| enabled | bool | DIALOG.button.enabled = False |
+| value | bool | if DIALOG.button.value: 💡 Only for toggle button! |
+| text | str | DIALOG.button.text = 'Click here!' |
+| type | str | # Possible values: 'push', 'toggle' DIALOG.button.type = 'toggle' DIALOG.button.value = True |
+| icon_type | str | # Possible values: 'none', 'file', 'system' # but see remark below! DIALOG.button.icon_type = 'none' |
+| icon_system_type | str | # Possible values: 'ok', 'cancel', # 'arrow_left', 'arrow_right', 'arrow_up', 'arrow_down' DIALOG.button.icon_system_type = 'ok' |
+| icon_system_size | str | # Possible values: 'default', 'large', 'extra_large' DIALOG.button.icon_system_size = 'extra_large' |
+| visible | bool | DIALOG.button.visible = False
+
+💡 There are also values for file icons. These only work straightforward using the dialog designer but not from a script. You can only change between no icon and system icons in a straightforward way.
+
+#### Radio button widget
+
+![](assets/widget_radiobutton.png)
+
+Radio button widget
+: The Radio button widget enables the user to choose an option from a predefined set. Each option has a label and a unique ID, which both can be set in the scripting dialog editor by double clicking the widget. The IDs are 'ONE', 'TWO' and 'THREE' in the example below.
+
+``` python
+selectedChoice = DIALOG.radiobuttonsWidget.value
+print( selectedChoice ) # output: ONE
+
+if selectedChoice == 'ONE':
+ print("IDs are strings.") # output: IDs are strings.
+```
+
+| Property | Type | Example |
+| -------- | -------------- | --------------------------------------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.radiobuttons.tooltip = 'Choose one alternative!' |
+| enabled | bool | DIALOG.radiobuttons.enabled = False |
+| value | str | DIALOG.radiobuttons.value = 'Value3' |
+| visible | bool | DIALOG.radiobuttons.visible = False |
+| items | (special list) | # Possible values is a list of lists of two strings. # Each first string is the returned value # Each second string is the entries' title DIALOG.radiobuttons.items = [['Value1', 'Title1'], ['Value2', 'Title2'], ['Value3', 'Title3']] DIALOG.radiobuttons.default = 'Value2' |
+| default | str | DIALOG.radiobuttons.default = 'Value1' |
+
+
+#### Abort button widget
+
+![](assets/widget_abort_disabled.png)
+
+Abort button widget
+: The Abort button widget aborts the current action. It is disabled if no action is currently executed. It behaves in the same manner as the abort button in the lower right corner of the ZEISS Inspect software.
+
+![](assets/built-in_progressbar.png)
+
+% To Do: Add enabled abort button. Check if the button still exists in ZEISS Inspect.
+
+#### Tolerances widget
+
+![](assets/widget_tolerances.png)
+
+Tolerances widget
+: The Tolerances widget is a group of input widgets which allows to configure all parameters related to tolerances.
+
+| Property | Type | Example |
+| ---------------- | --------------------- | ---------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.tolerancesWidget.tooltip = 'Configure tolerances' |
+| enabled | bool | DIALOG.tolerancesWidget.enabled = False |
+| value | (unspecified/various) | The current value of the widget. Type depends on the widget type and can be 'none' for empty widgets. |
+| focus | bool | DIALOG.tolerancesWidget.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.tolerancesWidget.visible = False |
+| expanded | bool | # Check if widged is expanded if DIALOG.tolerancesWidget.expanded == True: |
+| mode | str | # Tolerance mode ('no_tolerance', 'via_tolerance_table', 'from_cad', 'manual', 'from_element') print( DIALOG.tolerancesWidget.mode ) |
+| upper | double | DIALOG.tolerancesWidget.upper = 0.3 |
+| lower | double | DIALOG.tolerancesWidget.lower = 0.2
+| use_warn_limit | bool | # Use warning levels DIALOG.tolerancesWidget = True |
+| upper_warn | bool | DIALOG.tolerancesWidget.upper_warn = 0.5 |
+| lower_warn | bool | DIALOG.tolerancesWidget.lower_warn = 0.4
+| link_limits | bool | # Allow setting of upper / lower limits separately DIALOG.tolerancesWidget.link_limits = False |
+| unit | str | # Set unit ID DIALOG.tolerancesWidget.unit = 'LENGTH' |
+
+#### File system browser widget
+
+![](assets/widget_fsbrowser.png)
+
+File system browser widget
+: The File system browser widget allows to view the file system and to select a file or a set of files, respectively. A filter can be set to show only files with certain filename extensions.
+
+| Property | Type | Example |
+| ------------------ | --------------------- | -------------------------------------------------------------------------------------- |
+| tooltip | str | DIALOG.filesystemWidget.tooltip = 'Select CAD file' |
+| enabled | bool | DIALOG.filesystemWidget.enabled = False |
+| value | (unspecified/various) | The current value of the widget. Type depends on the widget type and can be 'none' for empty widgets. |
+| focus | bool | DIALOG.filesystemWidget.focus = True ⚠️ Only works if dialog is open |
+| visible | bool | DIALOG.filesystemWidget.visible = False |
+| root | str | DIALOG.filesystemWidget.root = 'C:/Users' |
+| show_date | bool | DIALOG.filesystemWidget.show_date = True |
+| show_size | bool | DIALOG.filesystemWidget.show_size = True |
+| show_type | bool | DIALOG.filesystemWidget.show_type = True |
+| use_multiselection | bool | # Enable selection of multiple files DIALOG.filesystemWidget.use_multiselection = True |
+| selected | list | print(DIALOG.filesystemWidget.selected) # example output: \['C:/temp/Basic_Training_GOM_Inspect_Pro/Training Data/Raw Data/Actual/GOM Training Object Mesh 1.g3d', 'C:/temp/Basic_Training_GOM_Inspect_Pro/Training Data/Raw Data/Actual/GOM Training Object Mesh 2.g3d'\] |
+| filter | list | # Apply a filter of filename extensions DIALOG.filesystemWidget.filter = \[ '\*.g3d', '\*.stp' \] |
+
+## Executing dialogs
+
+- [Dialog commands](#dialog-commands)
+ - [Break dialog (`execute`)](#break-dialog-execute)
+ - [Extendable break dialog (`create` and `show`)](#extendable-break-dialog-create-and-show)
+ - [Info dialog (`create`, `open` and `close`)](#info-dialog-create-open-and-close)
+- [Dialog results](#dialog-results)
+ - [Custom results](#custom-results)
+- [Configuring dialog widgets](#configuring-dialog-widgets)
+- [Event handler functions](#event-handler-functions)
+ - [Registering event handlers](#registering-event-handlers)
+ - [Closing dialogs from within the event handler](#closing-dialogs-from-within-the-event-handler)
+ - [Using a timer to activate the event handler](#using-a-timer-to-activate-the-event-handler)
+- [Determining the existing widget attributes](#determining-the-existing-widget-attributes)
+
+### Dialog commands
+
+#### Break dialog (`execute`)
+
+![](assets/dialog1_break.png)
+
+* Standard case of a dialog.
+* The dialog is created and executed with a single command.
+* The command blocks the script until the dialog is closed again.
+* The dialog result is returned.
+
+![](assets/dialog1.png)
+
+``` python
+RESULT=gom.script.sys.execute_user_defined_dialog (dialog={
+ "content": [
+ [
+ {
+ "columns": 1,
+ "name": "label",
+ "rows": 1,
+ "text": {
+ "id": "",
+ "text": "Distance",
+ "translatable": True
+ },
+ "tooltip": {
+ "id": "",
+ "text": "",
+ "translatable": True
+ },
+ "type": "label",
+ "word_wrap": False
+ },
+ {
+ "background_style": "",
+ "columns": 1,
+ "maximum": 1000,
+ "minimum": 0,
+ "name": "inputDistance",
+ "precision": 2,
+ "rows": 1,
+ "tooltip": {
+ "id": "",
+ "text": "",
+ "translatable": True
+ },
+ "type": "input::number",
+ "unit": "",
+ "value": 0
+ }
+ ]
+ ],
+ "control": {
+ "id": "OkCancel"
+ },
+ "embedding": "always_toplevel",
+ "position": "automatic",
+ "size": {
+ "height": 112,
+ "width": 198
+ },
+ "sizemode": "automatic",
+ "style": "",
+ "title": {
+ "id": "",
+ "text": "Distance",
+ "translatable": True
+ }
+})
+
+```
+
+#### Extendable break dialog (`create` and `show`)
+
+![](assets/dialog2_extendable_break.png)
+
+* A dialog is created and executed by subsequent commands.
+* This way, the created dialog can be modified by the script right before execution.
+
+```{code-block} python
+:caption: Creating and executing a dialog with two separate commands
+
+# Create dialog, but do not execute it yet
+DIALOG = gom.script.sys.create_user_defined_dialog (content='...')
+
+#
+# The dialog has been created. At this point of the script, the dialog handle DIALOG
+# can be used to access and configure dialog parts
+#
+
+# Execute dialog and fetch execution result
+RESULT = gom.script.sys.show_user_defined_dialog( dialog = DIALOG )
+```
+
+#### Info dialog (`create`, `open` and `close`)
+
+![](assets/dialog3_info.png)
+
+* In this mode, the script execution continues after the dialog has been opened.
+* The sequence of commands is as follows:
+ * the `create` command creates a dialog. The dialog can be configured now. Afterwards
+ * the `open` command is issued to display the dialog. The script executing continues. At last
+ * the `close` command closes the dialog again, if no closed manually by the user yet.
+
+💡 At script termination all open dialogs are closed automatically.
+
+```{code-block} python
+:caption: Non blocking configurable dialogs
+
+# Create dialog but do not execute it yet
+DIALOG = gom.script.sys.create_user_defined_dialog (content='...')
+
+#
+# The dialog has been created. At this point of the script, the dialog handle DIALOG
+# can be used to access and configure dialog parts
+#
+
+# Show dialog. The script execution continues.
+gom.script.sys.open_user_defined_dialog( dialog = DIALOG )
+
+#
+# The dialog content can be modified here, the dialog is still open
+#
+DIALOG.title = 'Stufe 2'
+
+# Close dialog again
+gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+```
+
+### Dialog results
+
+💡 The return value is an object with one property per interactive dialog widget containing its current value.
+
+* The return value is an object containing all current values.
+* Each dialog widget which can be changed by the script user writes its resulting value into this result object.
+* The key for each widget is its object name, which is unique.
+
+![](assets/result1.png)
+
+``` python
+#
+# Print whole dialog result. This is a result map with just one entry 'distance', named after
+# the unique name assigned to the spinbox.
+#
+print (RESULT) # Print whole result map
+# output: gom.dialog.DialogResult ('distance': 2.0, 'label': None)
+
+#
+# Print result for the element named 'distance'. This will lead to the spinbox content.
+#
+print (RESULT.distance)
+# output: 2.0
+```
+
+![](assets/result2.png)
+
+``` python
+# Print content of the 'name' widget
+print( RESULT.name )
+# output: Line 1
+
+# Print content of the widget named 'point1'. This can again be an element reference.
+print( RESULT.point1 )
+# output: gom.ActualReference (gom.app.project.inspection['Point 5'])
+
+# Print content of the widget named 'point2'.
+print( RESULT.point2 )
+# output: gom.ActualReference (gom.app.project.inspection['Point 6'])
+
+# construct a line with the user input. Therefore our dialog works similar to the 2-point line
+# construction dialog
+MCAD_ELEMENT=gom.script.primitive.create_line_by_2_points (
+ name= RESULT.name,
+ point1 = RESULT.point1,
+ point2 = RESULT.point2)
+```
+
+💡 The type of the result depends on the specific widget.
+
+#### Custom results
+
+You can return custom results from dialogs using an optional parameter to the `close_user_defined_dialog`-function. The following example produces 'Yes'
+and 'No' results for the different buttons and 'Cheater' when the user uses the close button of the dialog.
+
+``` python
+DIALOG = gom.script.sys.create_user_defined_dialog (content='...')
+
+#
+# Event handler function called if anything happens inside of the dialog
+#
+def dialog_event_handler (widget):
+ if widget == DIALOG.button_yes:
+ gom.script.sys.close_user_defined_dialog( dialog = DIALOG, result = 'Yes' )
+ if widget == DIALOG.button_no:
+ gom.script.sys.close_user_defined_dialog( dialog = DIALOG, result = 'No' )
+
+DIALOG.handler = dialog_event_handler
+
+try:
+ RESULT = gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+except gom.BreakError as e:
+ RESULT = 'Cheater'
+
+print('RESULT', RESULT)
+```
+
+Please find the complete example here: [dialog_yes_no.py](assets/dialog_yes_no.py)
+
+### Configuring dialog widgets
+
+* Dialogs created with the `create` and `open` commands can be modified before executed.
+* Each widget in the dialog can be accessed via the dialog handle.
+* The widget is identified by its unique name.
+
+```{code-block} python
+:caption: Configuring dialog widgets
+
+# Create dialog and receive dialog handle
+DIALOG = gom.script.sys.create_user_defined_dialog (content='...')
+
+# The handle for a widget inside of the dialog is addressed by its unique name
+WIDGET = DIALOG.distance
+
+# The widget parameter can be set via widget attributes. 'Value', for instance, relates to the current widget value.
+WIDGET.value = 3.0
+```
+
+* All widgets share some common standard attributes:
+
+| Attribute | Type | Property |
+| --------- | ------------------- | ----------------------------------------- |
+| name | str | Unique name of the widget - do not write! |
+| enabled | bool | Widget is currently active / inactive |
+| value | (depends on widget) | Current value |
+
+For the type of the value property for a specific widget, see section [Specific widgets](#specific-widgets) above. For widgets which are not used to enter some value, `value` is `None` and read-only. In addition, widgets have further attributes depending on their type (see section [Specific widgets](#specific-widgets) above for details).
+
+```{code-block} python
+:caption: Accessing widget attributes
+
+# Create dialog but do not execute it yet
+DIALOG=gom.script.sys.create_dialog (content='...')
+
+# Set name to 'default name' and disable 'ok' button
+DIALOG.name.value = "default name"
+DIALOG.control.ok.enabled = False
+
+# Execute dialog
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+```
+
+### Event handler functions
+
+#### Registering event handlers
+
+* A function can be registered to the dialog called on value changed.
+* Every time the user modified a dialog value, the **handler** function is called.
+* The handler function is also called on application global signals, e.g. when application data has been changed. In these cases is the string `'system'` passed to the handler function. Those global signals are caused by changing the element selection or opening a project for example.
+* The handler function can access dialog widget properties.
+* The handler function is registered using the special attribute `handler`.
+* The **prev** and **next** buttons of a wizard dialog are the only control widgets, which trigger the event handler.
+
+```{code-block} python
+:caption: Dialog handler functions
+
+DIALOG=gom.script.sys.create_user_defined_dialog (content='dialog definition')
+
+# Handler function registered to the dialog
+def handler_function (widget):
+ # Print information about the modified widget
+ print ("Modified:", str (widget))
+ # If the 'name' widget is empty, the 'ok' button is disabled.
+ if DIALOG.name.value == "":
+ DIALOG.control.ok.enabled = False
+ else:
+ DIALOG.control.ok.enabled = True
+
+ if str(widget) == 'system':
+ print("It is a global event.")
+ elif str(widget) == 'initialize':
+ print("Dialog is displayed for the first time.")
+
+# Register dialog handler
+DIALOG.handler = handler_function
+
+# Execute dialog
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+```
+
+A complete example with a handler function can be found in the file [scriptingEditorExampleDialog.py](assets/scriptingEditorExampleDialog.py). The argument passed to the event handler is either the dialog widget (e.g. a button) which triggered the event handler or a string. The following table lists all possible strings:
+
+| Value | Description |
+| ------------ | ---------------------------------------------------------------------------- |
+| 'system' | Passed to the event handler in the case of a global event. |
+| 'timer' | Passed to the event handler in the case of a global event. |
+| 'initialize' | Passed to the event handler when the dialog is displayed for the first time. |
+
+If the widget parameter is not a string, it represents a widget object. Note, that you cannot use the `is` operator on these objects. Always use `==` and similar
+operators to compare the widget parameter:
+
+```{code-block} python
+:caption: Comparing widget parameters
+
+def handler_function (widget):
+ ...
+ # compare widget using "==", using "is" will not work!
+ if widget == DIALOG.textInput:
+ if DIALOG.textInput.value == "":
+ DIALOG.control.ok.enabled = False
+ else:
+ DIALOG.control.ok.enabled = True
+```
+
+#### Closing dialogs from within the event handler
+
+💡 Dialogs can be closed from within event handlers.
+
+![](assets/event_handler_script_launcher.png)
+
+```{code-block} python
+:caption: Button event handler
+
+def dialog_event_handler (widget):
+ if widget == DIALOG.button1:
+ execute_func_1 ()
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+ elif widget == DIALOG.button2:
+ execute_func_2 ()
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+ elif widget == DIALOG.button3:
+ execute_func_3 ()
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+```
+
+⚠️ Right after the dialog has been closed its handle becomes invalid.
+
+This implies, that the event handler function must be written in a way that no dialog dependent code is executed after the dialog has been closed.
+
+#### Using a timer to activate the event handler
+
+Each `DIALOG` has a special property named `DIALOG.timer`. This timer property can be used to trigger the event handler registered to `DIALOG` in
+certain time intervals. When the event handler is triggered by the timer, the string `timer` is passed to it. The `__doc__`-string of the timer gives information
+about its attributes:
+
+``` python
+print(DIALOG.timer.__doc__)
+# output:
+# Timer
+#
+# Attributes:
+# enabled (boolean) - timer enabled
+# interval (integer) - timer interval [ms]
+```
+
+💡 Please note that the timer is disabled by default.
+
+Example:
+
+![](assets/event_handler_timer_edit.png)
+
+```{code-block} python
+:caption: Button/Timer event handler
+
+DIALOG=gom.script.sys.create_user_defined_dialog (content='boring dialog definition')
+
+#
+# Event handler function called if anything happens inside of the dialog
+#
+state = False
+def dialog_event_handler (widget):
+ global state
+ if widget == DIALOG.start:
+ DIALOG.timer.interval = DIALOG.interval.value * 1000
+ DIALOG.timer.enabled = True
+ DIALOG.start.enabled = False
+ DIALOG.stop.enabled = True
+ elif widget == DIALOG.stop:
+ DIALOG.timer.enabled = False
+ DIALOG.start.enabled = True
+ DIALOG.stop.enabled = False
+ elif widget == DIALOG.interval:
+ DIALOG.timer.interval = DIALOG.interval.value * 1000
+ elif widget == DIALOG.exit:
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+ elif str(widget) == 'system':
+ print("Its a system event.")
+ elif str(widget) == 'timer':
+ print("Its a timer event. Let´s swap the image.")
+ state = not state
+
+ if state:
+ DIALOG.image.system_image = 'system_message_warning'
+ else:
+ DIALOG.image.system_image = 'system_message_question'
+
+DIALOG.handler = dialog_event_handler
+DIALOG.stop.enabled = False
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+```
+
+The complete code of the example can be found here: [timer.py](assets/timer.py).
+
+### Determining the existing widget attributes
+
+* Because Python is a very dynamic language, the type of a variable or attribute can not be determined statically.
+* Instead, it is possible to query the variable dynamically during runtime.
+* The more commonly used widget attributes are documented in the section [Specific widgets](#specific-widgets) above.
+
+💡 Most objects support the attribute `__doc__` which prints the available object documentation to the console.
+
+```{code-block} python
+:caption: Print object documentation
+
+#
+# Query __doc__ attribute of a button widget
+#
+print (DIALOG.my_button.__doc__)
+# output:
+# Handle for a widget called 'my_button' of type 'Button' (button::pushbutton)
+#
+# Attributes:
+# name (string) - Name of the widget. The name can be used to access the widget via a dialog handle.
+# tooltip (string) - Tooltip of the widget. If empty, no tooltip is displayed.
+# enabled (boolean) - Enabled state of the widget. Default is 'enabled', set to false for disabling it.
+# value (unspecified/various) - The current value of the widget. Type depends on the widget type and can be 'none' for empty widgets.
+# attributes (map) - Map of all accessable widget attributes together with their current values.
+# focus (boolean) - Focus state of the widget. Can be used to set an explicit widget focus.
+# text (string) - Text of the button
+# type (string) - Button type ('push', 'toggle')
+# icon (Tom::Parse::Binary) - Icon of the button
+# icon_file_name (string) - Source file name of the icon
+# icon_size (string) - Icon size mode (icon, full)
+# icon_type (string) - Icon type (none, system, file)
+# icon_system_type (string) - System icon type (ok, cancel, arrow_up, arrow_down, arrow_left, arrow_right)
+# icon_system_size (string) - System icon size (default, large, extra_large)
+```
+
+## Wizards
+
+- [Control widgets](#control-widgets)
+
+* **Wizards** are dialogs with **\< Back** and **Next \>** buttons at the lower dialog edge.
+* The script programmer is responsible for adding functionality to this layout.
+* Wizards are not very versatile, but modifying the displayed texts and images is easily possible.
+
+⚠️ It is not possible to exchange widgets from within a dialog after the dialog has been created!
+
+Therefore Wizards only have simple options like exchange of images and texts in those containing elements.
+
+### Control widgets
+
+The operational elements in a control widget from a wizard do act like those in regular dialogs und can be accessed via handles as well:
+
+![](assets/wizard.png)
+
+```{code-block} python
+:caption: Wizard example
+
+#
+# Create dialog with wizard control panel
+#
+DIALOG=gom.script.sys.create_user_defined_dialog (content='boring dialog definition')
+#
+# Handler function to be registered to the dialog
+#
+def func (widget):
+ #
+ # Handle clicks onto the 'prev' button
+ #
+ if widget == DIALOG.control.prev:
+ # Here you would write code to display the content of the previous wizard 'page'
+
+ #
+ # Handle clicks onto the 'next' button
+ #
+ print("Prev button was clicked.")
+ elif widget == DIALOG.control.next:
+ # Here you would write code to display the content of the next wizard 'page'
+
+ #
+ # Update dialog button enabled state and register handler function
+ #
+ print("Next button was clicked.")
+
+DIALOG.handler = func
+
+#
+# Execute wizard dialog
+#
+RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+```
+
+[Creating wizard dialogs](creating_wizard_dialogs.md) shows some ways to manage wizard dialogs in greater detail.
diff --git a/2022-new-headings-intros/_sources/howtos/python_api_introduction/using_script_resources.md.txt b/2022-new-headings-intros/_sources/howtos/python_api_introduction/using_script_resources.md.txt
new file mode 100644
index 0000000..a54ef22
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/python_api_introduction/using_script_resources.md.txt
@@ -0,0 +1,31 @@
+# Using script resources
+
+The term "resource" is used to describe any files in your scripts directories that are not python scripts (`*.py`). You can use these files to include binary data such as images or other data like config files etc. in your add-ons.
+
+## Importing resources
+
+The resources files in your scripts directory are automatically recognized as such. You can as well add (import) resources using the context menu of the script editor.
+
+![](assets/import_script_resource.jpg)
+
+## Usage in scripts
+
+To get access to resource data in a script, the qualified name or relative path to the resource is needed.
+The qualified name starts with a `:` followed by the top-level folder and the path to the resource, e.g. `:PythonApiExamples/examples/script_resources/test_resource.txt`. You can also use a relative path to the currently executed script.
+
+```{hint}
+When using relative paths, the path is resolved to the script *currently executed*. This is not inevitably the script containing the `gom.Resource` call. E.g., when you import a script (A) containing a `gom.Resource` call in another script (B) and then execute the script (B), script (B) will be the *currently executed* one. In this case, usage of qualified names is advised.
+```
+
+Suppose you created a script called `resource_example.py` in a folder next to `test_resource.txt`. In the script, you can read the data in the following way:
+
+```python
+res = gom.Resource ("test_resource.txt")
+if (res.exists()):
+ print (res.open().read())
+```
+
+## See also
+
+* [Examples of category `script_resources`](../../python_examples/script_resources.md)
+* [`gom.Resource` API Definition](../../python_api/resource_api.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_actuals.md.txt b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_actuals.md.txt
new file mode 100644
index 0000000..36ae266
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_actuals.md.txt
@@ -0,0 +1,108 @@
+# Scripted actuals
+
+![](assets/scripted_actual_explorer.jpg)
+
+Scripted actual elements (short: scripted actuals), are scripted elements that refer to the actual, e.g. measured state of a geometrical object. Therefore, they appear in the "Actual Element" category of the GOM Inspect Element Explorer.
+
+In this how-to, the creation of a very basic point element is presented to show how scripted actuals are developed by example.
+
+## Example: Simple offset point
+
+Assume we want to create a scripted point. A point, whose position is just offsetted by a couple of millimeters from another point. Though the use of such element is clearly limited, it serves as an easy example on the general approach.
+
+As explained in the previous chapter, at first we select the element type in the script properties. For our offset-point, we naturally choose "Actual element" -> "Point".
+
+![](assets/offset_point_creation_type.jpg)
+
+Then, we write the code, which needs a `dialog` and a `calculation` function. Let's begin with the `dialog` function.
+
+### `dialog`
+
+```{code-block} python
+---
+linenos:
+---
+def dialog(context, params):
+
+ DIALOG=gom.script.sys.create_user_defined_dialog (dialog={ })
+
+ if 'x' in params:
+ DIALOG.i_x.value = params['x']
+ if 'base' in params:
+ DIALOG.point.value = params['base']
+
+ RESULT=gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+
+ params['x'] = DIALOG.i_x.value
+ params['base'] = DIALOG.point.value
+
+ context.name = 'My scripted point'
+ return params
+```
+
+As you can see, the function takes the parameters `context` and `params`. Although the `context` object has several members, for now we will only use it to set a name for our scripted element (line 15). The main objective of our dialog function is to fill the second parameter, the `params` map (python type: dictionary).
+
+In this case, we want to ask the user on which point our offset-point should be based on, and by how much the point should be offset. We [create a user dialog](../python_api_introduction/script_dialogs_introduction.md) and in the dialog editor, we add two input widgets:
+
+* `Input -> Decimal`: a decimal widget for the offset input
+* `Selection -> Selection element`: an element widget to select a point-like element
+
+![](assets/offset_point_dialog.jpg)
+
+It's important to note the widgets' "Object name"s, so we can adress them in the code. Second, it's important to set the "Type" of the selection element widget to `Any point`, so the user gets only the choice between elements that offer some point information.
+
+When finished with dialog creation, we have our desired JSON code, which we can use as a parameter for the `gom.script.sys.create_user_defined_dialog` command (line 3). This gives as a `DIALOG` handle, which we will use further.
+
+In case the `dialog` function is called from "Edit creation parameters", e.g the user wants to change parameters after the element was already created, the `params` map is not empty. Instead, it holds the *command parameters* from the last creation. Hence, we should prefill our DIALOG's widgets with the current values (see line 5 to 8). We can access the values of the widgets using the dialog handle and widgets' object names: `DIALOG..value`.
+
+Then, the dialog is shown to the user (line 10) and afterwards the results are collected (lines 12/13). After setting the element name, the parameters are returned. The framework then continues to call the `calculation` function.
+
+### `calculation`
+
+In most applications, the tricky part probably comes now, where you could solve complex mathematical problems to compute your final element values necessary.
+However, in this example, things are easy.
+
+```{code-block} python
+---
+linenos:
+---
+def calculation(context, params):
+
+ base = params['base'].center_coordinate
+ context.result[0] = (base.x + params['x'], base.y, base.z)
+
+ return True
+```
+
+The parameters of the `calculation` function are again `context` and `params`. From the `params`, we can access the selected point element using `params['base']`.
+What we get is a `gom.Reference` to the element the user selected. We can now [access the element's properties](../python_api_introduction/python_api_introduction.md#access-element-properties), such as the `center_coordinate`.
+
+Finally, we have to fill the `context.result` member. Depending on the scripted element type we want to create, it takes different formats.
+As described in the [Scripted elements API reference](../../python_api/scripted_elements_api.md), a point element takes a coorinate tuple `(x, y, z)`.
+The result for stage `0` (we ignore other stages for this example) is set in line 4. We return `True` to indicate the computation went fine.
+
+### Running the example
+
+That's it! When we now run the example, the dialog appears, we can select base point and offset value.
+
+![](assets/offset_point_user_dialog.jpg)
+
+After clicking "OK", a "My scripted point" element is created and visible in the explorer.
+
+![](assets/scripted_actual_explorer.jpg)
+
+
+```{seealso}
+The code of the example can also be found in the `Python API Examples` add-on, which contains many more examples, along with [Example documentation](../../python_examples/index.md).
+```
+
+## Further reading
+
+Now you've grasped the basic concept of scripted actuals. However, there are some relevant topics missing to complete a fully-integrated experience of a scripted actual. E.g. you might have noticed that we did not cover:
+
+* Error handling during calculation
+* Letting the user choose an element name in the dialog
+* Handling multiple stages
+* ...
+
+To learn about these mechanisms, you should take a look at the more sophisticated examples of our `Python API Examples` add-on, [documented here](../../python_examples/index.md).
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_checks.md.txt b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_checks.md.txt
new file mode 100644
index 0000000..0eb43d6
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_checks.md.txt
@@ -0,0 +1,50 @@
+# Scripted checks
+
+```{note}
+ This section assumes that you are familiar with the basic concept of Scripted elements. If not, take a look at the [Introduction](scripted_elements_introduction.md) and [Scripted actuals](scripted_actuals.md) sections.
+```
+## Introduction
+
+Scripted checks are a specialization of scripted elements to realize customized inspections in the GOM Software. Use checks if you want to display the deviation of certain properties of *existing* elements.
+
+## Writing a scripted check
+
+The script structure to create a scripted check is the same as for [Scripted actuals](scripted_actuals.md). However, there are some specialities:
+
+### Useful dialog widgets
+
+In most cases, you need to ask the user for the element to check, check naming or tolerance inputs. To this end, you can use the `Selection element`, `Element name`, `Unit` and `Tolerances` widgets:
+
+![](assets/scripted_check_widgets.jpg)
+
+### "Special" parameters
+
+For a successful integration with the native checks, unit and tolerance need to be set to the returned `params`.
+
+```python
+ params['tolerance'] = DIALOG.tolerances.value
+ params['unit'] = DIALOG.unit.value
+ params['abbreviation'] = 'ScrSca'
+```
+
+Furthermore, checks shall be assigned an `abbreviation`. This is the short form you'll see in the 3D view labels of the check, or in the result table.
+
+```{seealso}
+Detailed description of the [Scripted element API](../../python_api/scripted_elements_api.md).
+```
+
+## Types of scripted checks
+
+Currently, three types of scripted checks are supported. The `Python API Examples` add-on provides examples for all three. Click on the respective links to get to the example documentation.
+
+* Scripted scalar check: Check an element and assign a simple scalar value pair (nominal/actual) to it. See [Example: scripted_scalar_check](../../python_examples/scripted_checks/scripted_scalar_check.md).
+* Scripted curve check: Check an existing *curve* element and assign actual/nominal values for each point of the curve. See [Example: scripted_curve_check](../../python_examples/scripted_checks/scripted_curve_check.md).
+* Scripted surface check: Check an existing *mesh* element and assign deviation values for each point in the mesh. See [Example: scripted_surface_check](../../python_examples/scripted_checks/scripted_surface_check.md).
+
+% Special API functions used to handle checks.
+%
+% ## Special parameters of scripted checks
+%
+% * tolerances
+% * units
+% * ...
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_elements_introduction.md.txt b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_elements_introduction.md.txt
new file mode 100644
index 0000000..564e4e7
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_elements_introduction.md.txt
@@ -0,0 +1,88 @@
+# Introduction
+
+This documentation is intended to demonstrate the ability to create parametric elements in the GOM Software using custom python code.
+
+## Types
+
+A Script Element is always of a certain geometric type, like a point, surface curve, mesh etc. After creation, it can be used in the project identically to regular actual elements of the same type.
+Script Elements can depend on other elements, other elements can depend on script elements and they are recalculate if needed.
+
+There are currently two categories of scripted elements:
+
+* Scripted actual elements
+ * Point, Circle, Cylinder, ...
+* Scripted checks
+ * Scalar check, surface check, ...
+
+
+## Usage
+
+To create a scripted element, the general prodecure is as follows:
+
+1. Create a script in the script editor or using VS Code.
+2. Select the type of element that is created by this script in the script properties.
+3. Write your script code in a certain structure (see [Code structure](#code-structure)).
+
+### Set element creation type
+
+```{image} assets/script_properties_dialog.png
+:align: right
+:width: 150
+```
+You can set different properties to a script in the script editor. For scripted elements, the "Element creation" section provides drop-down menus to select the element type.
+
+Right-click (or double click) on an editable script in the script editor
+Enable element creation, e.g. "Actual element"
+Select the desired element type, e.g. "Circle"
+Each element type requires the script to provide for certain values of specific data types, which are defined in the [Scripted Elements API Specification](../../python_api/scripted_elements_api.md).
+
+### Code structure
+
+The script must contain two special functions as entry points for the gom application. One is responsible for creating a user interface, the other one for computing the element data.
+
+```python
+# -*- coding: utf-8 -*-
+import gom
+
+def dialog(context, params):
+ # [...]
+ # show dialog, fill param map, ...
+ # [...]
+ return params
+
+def calculation(context, params):
+ # [...]
+ # read params, perform calculation, set results
+ # [...]
+ return is_computation_valid # (True/False)
+```
+
+**The `dialog` function**
+
+The dialog function will be invoked, when the command is firstly run (from the menu or from the script editor) or when editing a created element using "Edit creation parameters". Most commonly, you would create a script dialog and show it to the user, who can then select the desired parameters for element creation.
+
+The dialog function can initiate a preview calculation of the element to be created in the background.
+
+As a result of `dialog`, a parameter map that defines the *command parameters* of the created element is returned.
+
+```{seealso}
+For implementation details, see the corresponding part of the [Scripted Elements API Specification](../../python_api/scripted_elements_api.md#the-dialog-function).
+```
+
+**The `calculation` function**
+
+The calculation function will be invoked by the application, when the parameter map changes to recalculate necessary element values. This is usually the first time when the `dialog` function returns or if a preview calculation is triggered.
+
+In case the *command parameters* contain references to other elements of the project, these elements are regarded as dependencies. Consequently, the `calculation` is triggered as well when one of the dependencies changed.
+This approach is called *parametric element creation*.
+
+At the end of the calculation, the results have to be set to `context.result`. This member of the function's `context` parameter can hold result data for each project stage. You can get all available project stages with `context.stages`. The type of result you have to assign for a successful element creation is dependent on which type of element you want to create, e.g. setting *(x, y, z)* values for a scripted point element.
+
+```{seealso}
+For implementation details, see the corresponding part of the [Scripted Elements API Specification](../../python_api/scripted_elements_api.md#the-calculation-function).
+```
+
+## Next steps
+
+To understand how Scripted elements work in practice, head over to the next chapter of [Scripted Actual Elements](scripted_actuals.md).
+
diff --git a/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_elements_toc.md.txt b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_elements_toc.md.txt
new file mode 100644
index 0000000..be1a1e1
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/scripted_elements/scripted_elements_toc.md.txt
@@ -0,0 +1,14 @@
+# Scripted elements
+
+The following how-tos will introduce the concept of scripted elements, i.e. elements of the GOM Software that are created by calculation logic written in Python.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :titlesonly:
+
+ scripted_elements_introduction
+ scripted_actuals
+ scripted_checks
+ tokens_on_scripted_elements
+```
diff --git a/2022-new-headings-intros/_sources/howtos/scripted_elements/tokens_on_scripted_elements.md.txt b/2022-new-headings-intros/_sources/howtos/scripted_elements/tokens_on_scripted_elements.md.txt
new file mode 100644
index 0000000..3f973b6
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/scripted_elements/tokens_on_scripted_elements.md.txt
@@ -0,0 +1,63 @@
+# Tokens on scripted elements
+
+```{note}
+ This section assumes that you are familiar with the basic concept of Scripted elements. If not, take a look at the [Introduction](scripted_elements_introduction.md), [Scripted actuals](scripted_actuals.md) and [Scripted checks](scripted_checks.md) sections.
+```
+## Introduction
+
+This page describes how user-defined tokens can be set to user-defined elements (UDEs).
+
+## Instructions
+
+### How user-defined tokens are set
+
+In the calculation function that generated the results, the `context.data[]` field can be read and written.
+
+In the following example, a volume defects element was created with following snippet inside the `calculation()` function:
+
+``` Python
+# Simulating user-defined token data
+ids = np.array ([ i for i in range (166])
+for s in context.stages:
+ context.data[s] = { "ude_defect_ids" : ids, "ude_test_string" : "hello world" }
+```
+
+Generally, the `context.data[]` field can be used to store intermediate data between the `dialog()` and the `calc()` function, e.g. if you – for preview reasons – pre-calculated some values, you can reuse them in the calc() function.
+
+Starting with SW2021 (Final) however, if you set the `context.data[s]` to hold a Python dictionary – i.e. a key-value map – for each stage `s`, then this data will be interpreted as 'token' data. These are generally data entities set to a GOM element, which can be retrieved using a key-string (the token).
+
+With this user-defined token mechanism, you are free to set any data structure as token data to the element you are creating as UDE, as long as it is serializable by the GOM scripting framework. You can use therefore: basic Python data types, numpy arrays, the GOM data types such as GOM.Vec3D, and finally lists and dictionaries of the previously mentioned types.
+
+In the example given above, we create a numpy array with IDs, one for each defect, and set this together with an exemplary test string as token data to the element.
+
+```{note}
+**Note: Naming of user-defined tokens**
+
+⚠️ The keys in the key-value map of user-defined tokens **must** start with the prefix `ude_`. If this is not the case, the token will not be set.
+```
+
+### Usage of user-defined tokens in scripts
+
+Let's see how this data can be retrieved after the element was successfully created:
+
+1. Open the script editor and create a new script. In the new script, press "F2" or right-click → Insert → Element Value.
+
+ In the appearing dialog, search for the volume defects element, and you will find the user-defined data in the "User-defined keywords" section.
+
+ ![](assets/user_defined_tokens-1.png)
+
+ For simple data types, you will get a preview (see Screenshot). For more complex types, including numpy arrays, there is no preview. The further usage works nevertheless.
+
+2. If you click "OK", the syntax how to retrieve the data is inserted in your new script. Of course, it is also possible to obtain the data from the element, if you have got a reference to it in a dialog selector or similar.
+
+3. You can now use the data in follow-up scripts.
+
+ ![](assets/user_defined_tokens-2.png)
+
+### Usage in user-defined checks
+
+Just as all other tokens on the element, you can access the data in user-defined checks.
+
+For simple data types, this is straightforward. To make this work for indexed data, as in the example of "defect_ids", you have to make sure that the array data you set to the token has the same length as the indices of the element.
+
+In the example above, the defect element gets 166 meshes, which will result in indices from 0 to 165.
diff --git a/2022-new-headings-intros/_sources/howtos/testing_addons/testing_addons.md.txt b/2022-new-headings-intros/_sources/howtos/testing_addons/testing_addons.md.txt
new file mode 100644
index 0000000..1141224
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/testing_addons/testing_addons.md.txt
@@ -0,0 +1,85 @@
+# Testing add-ons
+
+```{note}
+You can use the `Python API Examples` add-on, which you can find in the store, as an example how to include tests in your add-on.
+```
+## Why testing?
+
+Testing your add-on is a crucial step for maintainability, especially when dealing with multiple software versions or updates. As manually testing your add-on is often tedious and time consuming, this how-to focuses on how to include **automated tests** in your add-on.
+
+Automated tests are important when writing add-ons in Python because they help to ensure the code is running correctly and efficiently. Furthermore, they can be used to ensure that the code is compatible with different versions of the GOM Software, as well as on different machines. Finally, automated tests can be used to improve the overall performance of the add-on, as well as to ensure it meets the user’s requirements.
+
+## File structure
+
+```{note}
+The following structure is currently **recommended** and should serve you as a best-practice example. In upcoming SW-Versions, this structure might become **mandatory** for automatic test discovery to work.
+```
+
+The file and folder structure of add-on tests is similar to the *pyTest*s [Conventions for Python test discovery](https://docs.pytest.org/en/7.2.x/explanation/goodpractices.html#conventions-for-python-test-discovery). We recommend:
+
+* put all python test scripts in a **separate `tests` directory** of your add-ons top-level directory.
+* name test scripts **starting with `test_`** and contain **functions with the prefix `test_`**.
+
+ ![](file_structure.jpg)
+
+You may additionally include a script at the top-level that executes all of your tests (`run_tests.py` in the screenshot).
+
+## Writing a test script
+
+The following steps are required to write a new test script. The example code is taken from the `Python API Examples` add-on, which you can find in the store.
+
+1. Create a test script: Create a Python file with the convention test_*.py.
+ (Example: `PythonApiExamples/tests/test_data_interfaces_check_results`)
+
+2. Import the module or package to be tested: Import the module or package that you want to test.
+
+ ```python
+ # Importing the example we want to test
+ import PythonApiExamples.examples.data_interfaces.check_results_data_array as example
+ ```
+
+ For this to work properly, the code that you want to test needs to be structured in functions as well. In this case, there are several functions in the `check_results_data_arrray` script, like `get_single_result_value()`, which will be called later (see step 3).
+ For more details, see also: [How the examples are structured](../../python_examples/index.md#how-the-examples-are-structured).
+
+3. Write test functions: Write test functions named with prefix `test_` that define expected behavior.
+
+ ```python
+ def test_check_results ():
+ # Setup test project
+ open_project('gom_part_test_project')
+ test_element = gom.app.project.inspection['Surface comparison 1']
+
+ # Test definition
+ expected_single_value = 2.0495047569274902
+ actual_result_value = example.get_single_result_value(test_element)
+
+ assert actual_result_value == expected_single_value
+ ```
+
+4. Define which tests to run when the script itself is executed. Then run the test script.
+ ```python
+ # Test execution
+ if __name__ == '__main__':
+ test_check_results()
+ ```
+
+5. Check the results: Check the results of the test execution and make sure they match the expected behavior.
+
+## Running all tests
+
+To run all tests, it is recommended to create a wrapper script that includes the calls to the test scripts. You can invoke calls to the test scripts using the command `gom.script.userscript.`, which will execute the script as if run separately using the script editor. The `` is to be replaced with a string desribing the location of the test script, whereas double underscores (`__`) indicate subdirectories.
+
+```python
+import gom
+#
+# Run tests
+#
+gom.script.userscript.PythonApiExamples__tests__test_data_interfaces_check_results ()
+gom.script.userscript.PythonApiExamples__tests__test_... #...
+gom.script.userscript.PythonApiExamples__tests__test_... #...
+
+# Done
+print ("ALL TESTS PASSED!")
+```
+
+In case of (unhandled) assertion errors, this script will stop and show the error message. `ALL TESTS PASSED` is printed otherwise.
diff --git a/2022-new-headings-intros/_sources/howtos/using_vscode_editor/using_vscode_editor.md.txt b/2022-new-headings-intros/_sources/howtos/using_vscode_editor/using_vscode_editor.md.txt
new file mode 100644
index 0000000..c2829aa
--- /dev/null
+++ b/2022-new-headings-intros/_sources/howtos/using_vscode_editor/using_vscode_editor.md.txt
@@ -0,0 +1,228 @@
+# Using Visual Studio Code as an add-on editor
+
+## Setup
+
+### Installation
+
+1. Installation
+ * Install the extension directly from the Visual Studio Code extension tab or from the marketplace.
+ * VSCode version 1.64 or higher is needed for this to work properly.
+
+ ![](assets/extension.png)
+
+2. Configure connection
+
+ * Ensure that the python API preferences in the GOM software are set up properly
+
+ ![](assets/setup2.png)
+
+ * Ensure that the python API settings are correct in VSCode and are matching these in the GOM software:
+
+ ![](assets/setup4.png)
+
+### Connecting
+
+1. Have a GOM software running as a host
+2. In the VSCode status bar, the connection status is displayed:
+
+ ![](assets/connecting1.png)
+
+3. Press onto the "GOM host: Disconnected" status entry to connect to the host application.
+4. After the connection has been established,
+ * the connection status will reflect that and
+ * the GOM softwares add-on editor content is mirrored and displayed in VSCode:
+
+ ![](assets/connecting2.png)
+
+## Editing
+
+### Creating scripts
+
+1. Select 'New GOM script' from the file explorers right mouse menu.
+2. Enter unique name for that script.
+
+ ![](assets/editing1.png)
+
+
+### Executing scripts
+
+1. Select script to execute in the VSCode explorer.
+ * The script can either reside in the mirrored application scripting database or be a local file from any other workspace location.
+2. Select "Run script in GOM host" from the editors toolbar
+3. The script outputs will be shown in the "debug console".
+
+ ![](assets/editing2.png)
+
+### Recording commands
+
+1. Select the script to record commands into to show it in the editor.
+2. In that editor, select "Record commands" from the editor toolbar.
+3. Execute commands in the GOM application
+ * The executed commands will be recorded in the currently edited VSCode script.
+ * In addition, the "GOM script commands" subsection of the output tab shows a log of the executed commands.
+
+ ![](assets/recording1.png)
+
+4. For recording into a different position of the script, set the cursor to that line first or while recording.
+5. Press "Record commands" again to stop command recording.
+
+### Inserting elements
+
+> Elements in the GOM applications are represented by 'element references' in the script. These are python expressions which, when executed, return a reference to that element.
+
+1. When connected to a GOM application host, select the 'Elements' in the explorer view.
+ * There, all elements in the project are listed.
+2. Set editor cursor to the place the element should be into inserted into.
+3. Select "Insert element into editor" from the top toolbar of the 'Elements' tab
+ * You will get an 'element reference', an expression which, when, executed, returns the element referenced.
+
+ ![](assets/inserting_elements.png)
+
+### Inserting keywords
+
+> A keyword is an attribute used to query an element property. Various element attributes are existing depending on the element type.
+
+1. Insert an element reference in the script as mentioned above.
+2. After the element reference, press '.' to insert a point
+ * A selection menu opens presenting the available keywords for that element
+
+ ![](assets/inserting_keywords.png)
+
+## Debugging
+
+### Start debugging
+
+1. Prepare debugged script as usual by setting breakpoints etc.
+
+ ![](assets/debugging1.png)
+
+2. Start debugger by selecting "Debug script in GOM host" from the editor toolbar
+
+ ![](assets/debugging2.png)
+
+3. Full VSCode debugging functionality can be used now, including
+
+ ![](assets/debugging3.png)
+
+ * breakpoints and triggered breaks,
+ * step over/in/out,
+ * tracebacks,
+ * variable inspection etc.
+
+## User defined script dialogs
+
+```{note}
+User defined script dialogs cannot be edited graphically in VSCode at the moment. Instead, a application based script dialog can be opened. A connection to a running application must be presetn for that purpose.
+```
+
+### Create new user defined script dialog
+
+1. Select "GOM Scripting: Insert new user defined script dialog" from the command selector or from the right mouse menu while editing the script the dialog should be inserted into.
+
+ ![](assets/userdialog1.png)
+
+2. Choose a name for the dialog file which will then be created.
+
+ ![](assets/userdialog2.png)
+
+3. The edited script will contain the necessary dialog commands then and a separate dialog definition file (*.gdlg) has been created.
+
+ ![](assets/userdialog3.png)
+
+4. Select the dialog definition file to open the
+
+ ![](assets/userdialog4.png)
+
+5. When the script is executed, the user defined script dialog is displayed.
+
+ ![](assets/userdialog5.png)
+
+### Edit user defined script dialog
+
+1. Edit script dialog file (*.gdlg) can be edited either in JSON format directly (possible, but not recommended) or by opening the script dialog editor in the connected application:
+
+ ![](assets/userdialog6.png)
+
+2. The application will then open the script dialog editor. After closing it again, the edited *.gdlg file will be adapted accordingly.
+
+ ![](assets/userdialog7.png)
+
+```{note}
+Due to an unsolved bug, the script editor window might open below the VSCode window or on another display in some multi display settings. There is a hint box as indicator that the script editor windows has been opened at all.
+
+![](assets/userdialog8.png)
+```
+
+## FAQ
+
+### Configuration
+
+#### How do I set a shortcut to toggle the recording mode ?
+
+* Select the "Keyboard Shortcuts" properties from the configurations menu:
+
+ ![](assets/toggle_recording_1.png)
+
+* Assign the command "GOM Scripting: Toggle recording" to a key:
+
+ ![](assets/toggle_recording_2.png)
+
+* The 'when' clause determines when the command is available. The correct 'when' clause here ist:
+
+ resourceLangId == python && scriptingHostConnected
+
+* If necessary, existing command bindings to that key can be removed here, too:
+
+ ![](assets/toggle_recording_3.png)
+
+#### How do I set shortcuts for starting the current script in the GOM host ?
+
+* See above for the general process.
+* The relevant commands here are:
+ * 'GOM Scripting: Run script in GOM host': Start the script.
+ * 'GOM Scripting: Debug script in GOM host': Start the script with debugger attached.
+* F9 / CTRL + F9 might be valid keys for that.
+
+### Script editing
+
+#### Can I use local workspaces from disk instead of the application script database for my project ?
+
+* Yes.
+* You can add arbitrary folders to the workspace and edit and starts scripts from right there.
+* A limitation is that environments and packages cannot yet be handled by VSCode. As a workaround, the edited external folder can be added to the internal script editor, so that it can be processed from there:
+
+ ![](assets/script_editing_1.png)
+
+### Dialog editing
+
+#### I cannot edit all aspects of the user defined script dialogs in visual studio code ?
+
+* The user defined script editor is under development and probably still missing various features.
+* Workaround:
+ * Create the dialog in VSCode. If features are missing...
+
+ ![](assets/dialog_editing_1.png)
+
+ * ...continue editing the dialog in the build-in script editor.
+
+ ![](assets/dialog_editing_2.png)
+
+### Troubleshooting
+
+#### When using IntelliSense completion, the keyword list stalls
+
+* When using the '.' or a hotkey to access the list of possible completions, a tooltip displays 'Loading...' but nothing happens:
+
+ ![](assets/keyword_list_1.png)
+
+* This bug is caused by the 'Microsoft Python' extension in connection with the script database filesystem.
+* There is currently no fix, so disabling this extension is the only way here. This does not affect most python editor features:
+
+ ![](assets/keyword_list_2.png)
+
+#### When starting both the application and a script from within Visual Studio Code, crashes can happen
+
+* This is more a GOM internal issue. When developing application code and script code at the same time from the same VSCode instance, this can happen.
+* The parallel debugging session (application and scripting) seem to be the problem.
+* Workaround: Do not start GOM application via the VSCode launcher, but e.g. from a command prompt.
+
diff --git a/2022-new-headings-intros/_sources/index.md.txt b/2022-new-headings-intros/_sources/index.md.txt
new file mode 100644
index 0000000..9e97a7f
--- /dev/null
+++ b/2022-new-headings-intros/_sources/index.md.txt
@@ -0,0 +1,73 @@
+---
+myst:
+ html_meta:
+ "description": "Introduction to the Python API for extending GOM Inspect 2022 with Packages/Add-ons"
+ "keywords": "Metrology, GOM Inspect, Python API, GOM API, Scripting, Packages, Add-ons, How-tos"
+---
+# GOM Inspect Add-On Development Documentation
+
+Welcome to the GOM Inspect Add-On development documentation. With Add-Ons, you will be able to customize and extend the functionality of your GOM Inspect software.
+You can include several template configurations from the software, as well as completely new workflows programmed in python.
+
+```{note}
+This documentation is still under development. Expect bookmarks to sub-sites to change.
+```
+
+```{important}
+Creating add-ons is a rather advanced topic, so you should be familiar with the basic inspection concept of the GOM Software beforehand. New to GOM Inspect? This free course teaches you the basics:
+
+[(eLearning) 780 Starter Training GOM Inspect](https://training.gom.com/home/LearningPath/7265)
+
+Or, depending on your application, you might be interested in the specific starter trainings for [GOM Volume Inspect](https://training.gom.com/home/LearningPath/7280), [GOM Correlate](https://training.gom.com/home/LearningPath/7282), or [GOM Blade Inspect](https://training.gom.com/home/LearningPath/7281).
+
+```
+
+If you are new to add-ons, we recommend following our how-to guides to get you started.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :caption: How-to Guides
+
+ howtos/environments_for_python_scripts/environments_for_python_scripts
+ howtos/python_api_introduction/python_api_introduction
+ howtos/python_api_introduction/script_dialogs_introduction
+ howtos/python_api_introduction/creating_wizard_dialogs
+ howtos/python_api_introduction/using_script_resources
+ howtos/scripted_elements/scripted_elements_toc
+ howtos/adding_workspaces_to_packages/adding_workspaces_to_packages
+ howtos/using_vscode_editor/using_vscode_editor
+ howtos/localization/localization
+ howtos/testing_addons/testing_addons
+```
+
+
+If you already know how to create an add-on and now you are interested in python programming in GOM Inspect, take a look at our collection of Python examples.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :caption: Python API Examples
+ :titlesonly:
+
+ python_examples/index
+ python_examples/data_interfaces
+ python_examples/dialog_widgets
+ python_examples/misc
+ python_examples/script_icons
+ python_examples/script_resources
+ python_examples/scripted_actuals
+ python_examples/scripted_checks
+```
+
+Available API functions are documented in the Specification.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 2
+ :caption: Python API Specification
+
+ python_api/python_api
+ python_api/scripted_elements_api
+ python_api/resource_api
+```
diff --git a/2022-new-headings-intros/_sources/python_api/python_api.md.txt b/2022-new-headings-intros/_sources/python_api/python_api.md.txt
new file mode 100644
index 0000000..4c7c747
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_api/python_api.md.txt
@@ -0,0 +1,208 @@
+---
+myst:
+ html_meta:
+ "description": "GOM Inspect 2022 Add-on Python API Specification"
+ "keywords": "Metrology, GOM Inspect, Python API, GOM API, Scripting, Packages, Add-ons, Specification, Documentation"
+---
+# GOM Inspect Python API documentation
+
+Welcome to the GOM Inspect Python API documentation. Here you can find a detailed documentation of a subset of the Add-on programming specification. Please bear in mind, that recording commands with the script editor can be used to add new functions to your script.
+
+```{important}
+The now preliminary API is currently under heavy development and will change massively in the near future.
+```
+
+## Image processing
+
+Image related functions can be used to query images from the measurements of a project. This is not done directly, but via an 'image acquisition' object which acts as a proxy between the image storing data structured and the functions which can be used to process the image data.
+
+Terminology:
+
+* 'point': 3D coordinate in the project.
+* 'pixel': 2D coordinate in an image.
+
+### gom.api.project
+
+```{py:function} gom.api.project.get_image_aquisition (measurement, camera, stages)
+
+Generate a list of image acquisition objects which can be used as input for image processing functions.
+
+:API version: 1
+:param measurement: Measurement the image is to be queried from
+:type measurement: Reference
+:param camera: Identifier for the camera which contributed to the measurement. Valid values are:
+ * 'left camera': Left camera in a two camera system or the only existing camera in a single camera system
+ * 'right camera': Right camera in a two camera system
+ * 'photogrammetry': Photogrammery (TRITOP) camera
+:type camera: str
+:param stages: (*Optional*) Indices of the stages for which an image acquisition object is to be generated.
+:type stages: list [int]
+:return: List of image acquisition objects which can be used by image processing functions. The number of objects matches the number of stage indices in the stages parameter of the function call.
+:rtype: List [Reference]
+```
+
+**Example**
+
+```
+measurement = gom.app.project.measurement_series['Deformation series'].measurements['D1']
+stage = gom.app.project.stages['Stage 1']
+point = gom.app.project.actual_elements['Point 1'].coordinate
+
+left = gom.api.project.get_image_acquisition (measurement, 'left camera', [stage.index])[0]
+right = gom.api.project.get_image_acquisition (measurement, 'right camera', [stage.index])[0]
+```
+
+### gom.api.imaging
+
+```{py:function} gom.api.imaging.compute_pixels_from_point (point_and_image_acquisition)
+
+Compute pixel coordinates from point coordinates
+
+:API version: 1
+:param point_and_image_acquisition: List of pairs where each entry describes a point coordinate plus the image acquisition object which should be used to compute the matching image pixel.
+:type point_and_image_acquisition: List
+:return: List of image pixels where each entry is the result of projecting the point via the associated image acquisition structure into the image. The pixel coordinate system center is located in the upper left corner.
+:rtype: List
+```
+
+**Example**
+
+```
+measurement = gom.app.project.measurement_series['Deformation series'].measurements['D1']
+stage = gom.app.project.stages['Stage 1']
+point = gom.app.project.actual_elements['Point 1'].coordinate
+
+left = gom.api.project.get_image_acquisition (measurement, 'left camera', [stage.index])[0]
+right = gom.api.project.get_image_acquisition (measurement, 'right camera', [stage.index])[0]
+
+p = gom.api.imaging.compute_pixels_from_point ([(point, left), (point, right)])
+
+print (p)
+```
+```
+[gom.Vec2d (1031.582008690226, 1232.4155555222544), gom.Vec2d (1139.886626169376, 1217.975608783256)]
+```
+
+```{py:function} gom.api.imaging.compute_point_from_pixels ([[pixel_and_image acquisition]], use_calibration)
+
+Compute point coordinate from pixel coordinates
+
+:API version: 1
+:param pixel_and_image_acquisition: List of pairs where each entry describes a pixel image coordinate plus the image acquisition object which should be used to compute the matching point.
+:type pixel_and_image_acquisition: List
+:param use_calibration: If set, the information from the calibration is used to compute the point. Project must provide a calibration for that case.
+:type use_calibration: bool
+:return: List of lists of (pixel, residuum) where each entry is the result of projecting the point via the associated image acquisition structure into the image. The pixel coordinate system center is located in the upper left corner.
+:rtype: List
+```
+
+```
+measurement = gom.app.project.measurement_series['Deformation 1'].measurements['D1']
+stage = gom.app.project.stages[0]
+point = gom.app.project.actual_elements['Start Point 1'].coordinate
+
+left = gom.api.project.get_image_acquisition (measurement, 'left camera', [stage.index])[0]
+
+p = gom.api.imaging.compute_point_from_pixels ([[(gom.Vec2d (10, 10), left)]], False)
+
+print (p)
+```
+```
+[[gom.Vec3d (-638.2453100625158, 1627.6169782583584, 0.0), 0.0]]
+```
+
+```{py:function} gom.api.imaging.compute_epipolar_line (image_acquisition_1, [pixel_and_image_acquisition]_2, max_distance)
+
+Compute epipolar line coordinates
+
+:API version: 1
+:param image_aquisition_1: Handle of the image acquisition the epipolar line should be found in.
+:type image_aquisition_1: List
+:param pixel_and_image_aquisition_2: List of pairs where each entry describes a pixel image coordinate plus the image acquisition object which should be used to compute the matching point. The image acquisition object here. is the "other" acquisition providing the pixels used to find the matching epipolar lines in the image_acquisition_1 object.
+:type pixel_and_image_aquisition_2: List
+:param max_distance: Maximum search distance in mm.
+:type max_distance: double
+:return: List of epipolar line coordinates, each one consisting of a list of image pixels.
+:rtype: List
+```
+
+```
+stage = gom.app.project.stages['Stage 1']
+point = gom.app.project.actual_elements['Point 1'].coordinate
+
+left = gom.api.project.get_image_acquisition (measurement, 'left camera', [stage.index])[0]
+right = gom.api.project.get_image_acquisition (measurement, 'right camera', [stage.index])[0]
+
+l = gom.api.imaging.compute_epipolar_line (left, [(gom.Vec2d (1617, 819), right)], 10.0)
+
+print (l)
+```
+```
+[[gom.Vec2d (4.752311764226988, 813.7915394509045), gom.Vec2d (10.749371580282741, 813.748887458453), gom.Vec2d (16.73347976996274, 813.706352662515), ...]]
+```
+
+## Checks
+
+Functions used to handle checks.
+
+### gom.api.scripted_checks_util
+
+```{py:function} gom.api.scripted_checks_util.is_scalar_checkable (element)
+
+Test if the referenced element is suitable for inspection with a scalar check.
+
+:API version: 1
+:param element: Element to be checked
+:type element: Reference
+:return: True' if the given element s suitable for inspection with a scalar check.
+:rtype: bool
+```
+
+```
+element = gom.app.project.inspection['Point 1']
+state = gom.api.scripted_checks_util.is_scalar_checkable (element)
+print (state)
+```
+```
+True
+```
+
+```{py:function} gom.api.scripted_checks_util.is_surface_checkable (element)
+
+Test if the referenced element is suitable for inspection with a surface check.
+
+:API version: 1
+:param element: Element to be checked
+:type element: Reference
+:return: True' if the given element s suitable for inspection with a surface check.
+:rtype: bool
+```
+
+```
+element = gom.app.project.inspection['Point 1']
+state = gom.api.scripted_checks_util.is_surface_checkable (element)
+print (state)
+```
+```
+True
+```
+
+```{py:function} gom.api.scripted_checks_util.is_curve_checkable (element)
+
+Test if the referenced element is suitable for inspection with a curve check.
+
+:API version: 1
+:param element: Element to be checked
+:type element: Reference
+:return: True' if the given element s suitable for inspection with a curve check.
+:rtype: bool
+```
+
+```
+element = gom.app.project.inspection['Point 1']
+state = gom.api.scripted_checks_util.is_curve_checkable (element)
+print (state)
+```
+```
+True
+```
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_api/resource_api.md.txt b/2022-new-headings-intros/_sources/python_api/resource_api.md.txt
new file mode 100644
index 0000000..84a34a9
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_api/resource_api.md.txt
@@ -0,0 +1,80 @@
+# gom.Resource API
+
+## Summmary
+
+The `gom.Resource` API can be used to access binary data of files included in an add-on's scripts folder.
+
+```{seealso}
+For a description of the general concept, see [Using script resources](../howtos/python_api_introduction/using_script_resources.md).
+
+For examples, see [Examples of category `script_resources`](../python_examples/script_resources.md).
+```
+
+## Class definition
+
+```{eval-rst}
+.. py:class:: gom.Resource
+
+ This module represents the Resource class. A utility to access resource data using relative paths and shared memory.
+
+ .. py:staticmethod:: Resource.list()
+
+ Lists all resources
+
+ :returns: List of resources
+
+ .. py:staticmethod:: Resource.cleanup()
+
+ Closing all dangling resources (API call to free memory on C++ side)
+
+ .. py:method:: __init__(path)
+
+ Constructor
+
+ :param path: Qualified name of the resource
+
+ .. py:method:: isLoaded()
+
+ Check if the resource is loaded
+
+ :returns: True if the resource is loaded, False otherwise
+
+ .. py:method:: close()
+
+ Release resource from shared memory
+
+ .. py:method:: open(size=0)
+
+ Open the resource in shared memory
+
+ .. py:method:: exists()
+
+ Check if the resource exists
+
+ :returns: True if the resource exists, False otherwise
+
+ .. py:method:: byteSize()
+
+ Get the size of the resource in bytes
+
+ :returns: The size of the resource in bytes
+
+ .. py:method:: keepInMemory()
+
+ Keep the resource in memory
+
+ .. py:method:: save(size=0)
+
+ Save the resource
+
+ :param size: Size of the resource
+ :returns: True if the save was successful, False otherwise
+
+ .. py:method:: saveAsUserResource(new_path, overwrite=True)
+
+ Save the resource to a new path
+
+ :param new_path: New path to save the resource
+ :param overwrite: True to overwrite existing files, False to not overwrite
+
+```
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_api/scripted_elements_api.md.txt b/2022-new-headings-intros/_sources/python_api/scripted_elements_api.md.txt
new file mode 100644
index 0000000..3aa0f24
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_api/scripted_elements_api.md.txt
@@ -0,0 +1,397 @@
+# Scripted elements API
+
+This reference describes functions and data structures necessary for the implementation of "scripted elements".
+
+```{seealso}
+If you don't know about the concept yet, take a look at the [Scripted elements introduction](../howtos/scripted_elements/scripted_elements_introduction.md).
+```
+
+## The `dialog` function
+
+💡 **Notes:**
+
+* The main purpose of this function is to use display a script dialog and allow the user to enter element parameters.
+* All tokens of other elements can be accessed within this function.
+
+### Signature
+
+```python
+def dialog(context, params):
+```
+
+
+#### Parameter `context`
+
+The context contains the following members:
+
+| Name | Role | Remarks |
+| -------------------------- | -------------------------------------------------- | -------------------------------------------------------------- |
+| .data | UDE data storage access | see "calculate" Function |
+| .stages | Current stage | List containing stage index of current stage |
+| .total_stages | Number of stages | Valid stage indices are 0 to total_stages - 1 |
+| .calc | Function to calculate preview | See below |
+| .result | Directly set preview | see "calculate" Function |
+| .is_new_element | Flag if element creation | True on (edit) creation, false on recalc |
+| .name | Name of created element | Read/write attribute Ignored on recalc and script execution |
+| .error | Last error text from preview calculation | Empty if no error occurred |
+| .edit_element | Reference to edited element | Only available during element editing |
+| .recalc_element | Reference to element used in project recalculation | |
+
+#### Parameter `params`
+
+The params contain a map of parameter values. It is only filled on element edit and contains the current parameters of the element.
+
+#### Return value
+
+The function must return a map containing the new element parameters.
+
+If no map is returned the edit/creation is regarded as aborted by the user.
+
+### Calculating a preview
+
+To calculate a preview, the `context.calc()` function can be invoked. It takes the following parameters:
+
+| Name | Role |
+| ----------------- | ---------------------------------------------------------------------------------- |
+| params | A map of parameters to be used for preview calculation |
+| stages | Optional: A list of stage indices to calculate a preview in |
+| dialog | Optional: A script dialog to message when preview calculation was successful. The dialog event handler will receive the event string 'calculated' |
+
+A call to this function will return immediately. The calculation is invoked asynchronously in a separate python instance.
+
+## The `calculation` function
+
+💡 **Notes:**
+* It is not possible to call script commands or read tokens from within this function. (Do not call `gom.app.project....`)
+* The function should loop over all stages to be calculated and set a computation result for each stage.
+
+### Signature
+
+```python
+def calculation(context, params):
+```
+
+#### Parameter `context`
+
+The context contains the following members:
+
+| Name | Role | Remarks |
+| ------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------- |
+| .data[stage] | UDE data storage access | see below |
+| .stages | Current indices | List containing stage indices to calculate |
+| .total_stages | Number of stages | Valid stage indices are 0 to total_stages - 1 |
+| .result[stage] | Directly set preview | see below |
+| .is_new_element | Flag if element creation | True on (edit) creation, false on recalc |
+| .name | Name of created element | Read/write attribute Ignored on recalc and script execution |
+| .error[stage] | Used to assign an error text | Will set the element to not computed in the given stage |
+| .edit_element | Reference to edited element | Only available during element editing |
+| .recalc_element | Reference to element being computed | Only available during non-interactive calculation |
+| .progress_stages_computing | Number of stages which have started to compute | Used to display progress information |
+| .progress_stages_total | Number of stages which have to be computed | Used to display progress information |
+
+##### Attribute `context.data[]`
+
+The context.data is a list allowing to read or write additional data. The list is indexed with a stage index. The additional data is stored within the project, so the gom application must be able to serialize the provided data.
+
+```Python
+context.data[0] = value
+value = context.data[0]
+```
+
+##### Attribute `context.result[]`
+
+This is a write only list used to set computation results. The context.result[] should be set for each stage index listed in context.stages.
+
+The format to write must match the type of the script element. For available result types, see [Scripted actuals - Return values](#scripted-actuals---return-values) and [Scripted checks - Return values](#scripted-checks---return-values).
+
+#### Return value
+
+On success the function must return True, otherwise False.
+
+% `context`: ...
+
+## Scripted actuals - Return values
+
+### Point
+
+:Element Type: Plain 3D point
+:Result: Point coordinate
+
+```{code-block} python
+result = (x,y,z)
+result = gom.Vec3D
+```
+
+### Distance
+
+:Element Type: Two point distance
+:Result: Start and end point of distance
+
+```{code-block} python
+result = { 'point1': (x,y,z), 'point2': (x,y,z) }
+result = { 'point1': gom.Vec3D, 'point2': gom.Vec3D }
+```
+
+### Value Element
+
+:Element Type: Plain value (only real values supported)
+:Result: any double value
+
+```{code-block} python
+result = x
+```
+
+### Circle
+
+:Element Type: 2D Circle with direction
+:Result: A center point, direction vector and radius (double)
+
+```{code-block} python
+result = { 'center' : gom.Vec3D, 'direction' : gom.Vec3D, 'radius' : double }
+```
+
+### Curve
+
+:Element Type: 3D polyline
+:Result: A curve can be made up by an array of subcurves. Each subcurve is a polyline. A closed curve will be created, if first point = last point.
+
+```{code-block} python
+result = [ { 'points': [gom.Vec3D, gom.Vec3D, ...] } ]
+```
+
+### Surface Curve
+
+:Element Type: 3D polyline with normals
+:Result: Like a curve with additional normal data, i.e. each surface curve can be made up by an array of subcurves.
+
+% ```{code-block} python
+% # This does not work!
+% result = [ { 'points': [ gom.Vec3D, gom.Vec3D, ... ], 'normals': [(x,y,z)] } ]
+% ```
+
+% :::{caution}
+% **Workaround:** set the result to
+```{code-block} python
+result = {
+ 'default': [
+ {'points': [gom.Vec3d, gom.Vec3d, ...], 'normals': [gom.Vec3d, gom.Vec3d, ...]},
+ {...},
+ ...
+ ]
+}
+```
+% :::
+
+### Section
+
+:Element Type: 3D polyline with normals
+:Result: Parameters 'plane', 'cylinder' and 'cone' are optional. They denote the creation geometry. You can only use one of them. Argument is a corresponding trait.
+
+```{code-block} python
+result = {
+ 'curves': [{'points': [(x, y, z), ...], 'normals': [(x, y, z), ...]}, ...],
+ 'plane' : {'normal' : (x, y, z), 'distance' : float},
+ 'cylinder': ...,
+ 'cone' : ...
+}
+```
+
+### Point Cloud
+
+:Element Type: Set of 3D points
+:Result: A set of points. The 'normals 'attribute is optional.
+
+```{code-block} python
+result = { 'points' : [ gom.Vec3D, gom.Vec3D, ... ] , 'normals' : [ gom.Vec3D, gom.Vec3D, ... ] }
+```
+
+### Surface
+
+:Element Type: Mesh
+:Result: Defines a triangulation. The vertices attribute points defines all points. The triangle attribute defines triangles between these points using indices into the vertex list.
+
+```{code-block} python
+result = { 'vertices': [ (x,y,z) ], 'triangles': [ (v0,v1,v2) ] }
+```
+
+### Cone
+
+:Element Type: Cone
+:Result: Accepts any Cone Trait
+
+```{code-block} python
+result = {'default' : {'point1': gom.Vec3d, 'radius1': float, 'point2': gom.Vec3d, 'radius2': float} }
+```
+
+% see SW2024-2241
+:::{caution}
+Due to the internal represenstation of a Cone Element, the direction of the vector `point1` -> `point2` is always from the smaller to the larger circle (`radius1` < `radius2`).
+
+If you specify `radius1` > `radius2` in the creation parameters, [`point1`; `radius1`] and [`point2`; `radius2`] are swapped automatically.
+:::
+
+### Cylinder
+
+:Element Type: Cylinder
+:Result: Accepts any Cylinder Trait
+
+% ```{code-block} python
+% result = Reference
+%
+% # This does not work!
+% result = { 'point': gom.Vec3d, 'radius': float, 'direction': gom.Vec3d, 'inner' : bool }
+%```
+
+% :::{caution}
+% **Workaround:** set the result to
+```{code-block} Python
+result = Reference
+
+result = {'default' : {'point': gom.Vec3d, 'radius': float, 'direction': gom.Vec3d, 'inner' : bool} }
+```
+% :::
+
+% See https://jira.gom.com/browse/AD-163
+% ### Plane
+%
+%:Element Type: Plane
+%:Result: Accepts any Plane Trait
+%
+%% ```{code-block} python
+%% result = Reference
+%%
+%% # This does not work!
+%% result = { 'point1': gom.Vec3d, 'radius1': float, 'point2': gom.Vec3d, 'radius2': float }
+%% ```
+%
+%% :::{caution}
+%% The creation of planes currently does not work.
+%%
+%% **Workaround:** set the result to
+%```{code-block} python
+%result = Reference
+%
+%result = {'default' : {'distance': gom.Vec3d, 'normal': gom.Vec3d} }
+%```
+%:::
+
+### Volume defects
+
+:Element Type: Volume defects
+:Result: A list of meshes defined by vertices and triangles.The vertices attribute is a [python array] – one entry for each defect – of numpy arrays (np.array) of Vec3d.
The triangle attribute defines triangles between the points of each mesh using indices to the vertex lists.
The 'outer_hull' parameter can optionally be set to a reference of a mesh element of the project. This mesh will be copied and used as an outer hull for the defect element. **Alternatively**, 'outer_hull_vertices' and 'outer_hull_triangles' can be given as explicit outer hull mesh definition.
+
+```{code-block} python
+result = {
+ 'vertices': [ np.array((x,y,z), (x,y,z), ... ), np.array((x,y,z), (x,y,z), ...), ... ],
+ 'triangles': [ np.array((v0,v1,v2), (v0,v1,v2), ... ), np.array((v0,v1,v2), (v0,v1,v2), ...), ... ],
+ 'outer_hull' : gom.Reference # optional OR
+ 'outer_hull_vertices': np.array((x,y,z),...), 'outer_hull_triangles': np.array((v0,v1,v2),...)
+}
+```
+
+### 2D Volume Defects
+
+:Element Type: 2D volume defects element of curves
needed for the P201 package
+:Result: Requires a list/array of lists/arrays of Vec3ds.
A list of points represents the polygon (curve) of one 2d volume defect. The list of lists of points represents all 2d volume defects that shall be included in the element.
+
+```{code-block} python
+result = {
+ 'curves': [ [gom.Vec3d, gom.Vec3d, ...],
+ [gom.Vec3d, gom.Vec3d, ...],
+ ... ]
+}
+```
+
+### Volume
+
+:Element Type: New volume data
+:Result: Accepts a numpy array with voxel data and a transformation.
The numpy array's shape denotes the resulting volume shape. The 'dtype' can be one of (UINT16, BYTE, INT16, INT16, INT32, UINT32, FLOAT, DOUBLE).
The transformation can be a gom.Mat4x4 (affine transformation) or a gom.Vec3d (scaling along x/y/z axis only)
+
+```{code-block} python
+result = { 'voxel_data' : np.array (), 'transformation' : (gom.Mat4x4 | gom.Vec3d) }
+```
+
+### Volume material map
+
+:Element Type: Attach material labels to volume element
+:Result: Creates a new volume element copy with attached material labels.
First parameter is a numpy array of type UINT8 of the size of the volume. The values are the material index per voxel. Background has Index 0.
The second parameter is a list of floating point grey values that are the representative grey values of the background and the materials.
The third parameter is a reference to the volume element, to which material labels should be attached.
+
+```{code-block} python
+result = {
+ 'material_labels_draft' : np.array (),
+ 'material_grey_values_draft' : [background, material 1, ...],
+ 'volume_reference_draft' : Reference
+}
+```
+
+### Volume Section
+
+:Element Type: Volume Section
+:Result: Accepts a numpy array with pixel data and a transformation.
The numpy array's shape denotes the resulting volume section shape. The 'dtype' must be `numpy.float32`.
The transformation is a gom.Mat4x4 (affine transformation)
+
+```{code-block} python
+result = { 'pixel_data' : np.array (), 'transformation' : gom.Mat4x4 }
+```
+
+% New in SW2023
+%### Volume Region
+%
+%:Element Type: Volume Region
+%:Result: Accepts a numpy array of the region data. The 'dtype' must be UINT_8. This array can be smaller than the volume grid.
The offset parameter defines %the location of the first voxel in the numpy array of the volume region.
This scripted element requires specifying a reference to a volume element. This can %be a volume or linked volume element.%
+
+%```{code-block} python
+%result = {
+% 'volume_element': Reference,
+% 'offset': gom.Vec3d,
+% 'data': np.array ()
+%}
+%```
+
+% ### Element type: Point
+
+% ```{py:function} context.result[s]
+%
+% Test if the referenced element is suitable for inspection with a scalar check.
+%
+% :API version: 1
+% :param element: Element to be checked
+% :type element: Reference
+% :return: True' if the given element s suitable for inspection with a scalar check.
+% :rtype: bool
+% ```
+
+## Scripted checks - Return values
+
+Scripted Checks extend the concept of scripted actual elements to be able to calculate custom inspections based on python scripts.
+
+### Supported Element Types
+
+The following element types are currently supported:
+
+
+### Scalar
+
+:Element Type: Scalar check: A single scalar value is assigned to an element
+:Result: A nominal and actual double value are set, and a reference to element which was checked.
+
+```{code-block} python
+result = {"nominal" : double, "actual" : double, "reference" : gom.Reference }
+```
+
+### Scalar Surface
+
+:Element Type: Surface check: A scalar deviation value is assigned to each point of a mesh.
+:Result: A list of deviation values for each point of a mesh. The mesh is also set as "reference" parameter.
The number of points of the mesh and the "deviation_values" array must match.
+
+```{code-block} python
+result = { "deviation_values" : np.array(dtype=np.float32), "reference" : gom.Reference }
+```
+
+### Scalar Curve
+
+:Element Type: Curve check: A scalar deviation value is assigned to each point on a curve.
+:Result: A list of nominal and actual values for each point of a curve. The deviation values are calculated automatically as a difference between both.
The curve is also set as "reference" parameter.
The number of points of the curve and the value arrays must match.
+
+```{code-block} python
+result = { "actual_values" : double, 'nominal_values': double, "reference" : gom.Reference}
+```
diff --git a/2022-new-headings-intros/_sources/python_examples/data_interfaces.md.txt b/2022-new-headings-intros/_sources/python_examples/data_interfaces.md.txt
new file mode 100644
index 0000000..2e72d53
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/data_interfaces.md.txt
@@ -0,0 +1,15 @@
+# data_interfaces
+
+This is a collection of examples to access element properties and data.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ data_interfaces/*
+```
+
+```{seealso} How-to: [Access element properties and data](../howtos/python_api_introduction/python_api_introduction.md#access-element-properties)
+```
diff --git a/2022-new-headings-intros/_sources/python_examples/data_interfaces/check_results_data_array.md.txt b/2022-new-headings-intros/_sources/python_examples/data_interfaces/check_results_data_array.md.txt
new file mode 100644
index 0000000..699e71e
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/data_interfaces/check_results_data_array.md.txt
@@ -0,0 +1,28 @@
+# check_results_data_array
+
+![](check_results_data_array.jpg)
+
+## Short description
+
+This example demonstrates two ways of accessing result data from checks using the element properties and data interfaces.
+
+## Highlights
+
+Basically, if you have obtained an `gom.Reference` element reference, e.g. by selecting an element by name (`gom.app.project.inspection['Surface comparison 1']`), you can access the results of the check:
+
+1. **By evaluating an expression**
+
+ `single_scalar_value = element.get ('result_dimension[0].deviation')`
+
+* simple for single values
+* works without using `numpy` library
+
+2. **By the data interface of this element using the `.data` token**
+
+ `scalars = np.array (element.data.result_dimension.deviation)`
+
+* gets large datasets of all stages very efficiently
+
+## Related
+
+* How-to: [Access element properties and data](../../howtos/python_api_introduction/python_api_introduction.md#access-element-properties)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/data_interfaces/volume_section_image_data.md.txt b/2022-new-headings-intros/_sources/python_examples/data_interfaces/volume_section_image_data.md.txt
new file mode 100644
index 0000000..fcf0384
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/data_interfaces/volume_section_image_data.md.txt
@@ -0,0 +1,30 @@
+# volume_section_image_data
+
+![](volume_section_image.jpg)
+
+## Short description
+
+This example demonstrates how to access the image data of a volume section.
+
+## Highlights
+
+There are two output formats available.
+
+1. **The raw image data**
+
+ This is essentially the same as getting a slice of the volume. Data type and value are the same as the volume the section belongs to.
+
+ `raw_image = np.array (element.data.raw)`
+
+2. **The rendered image**
+
+ This yields the the image as rendered for the 3D view.
+
+ `rgb_image = np.array (element.data.rgb)`
+
+ This image is in RGBA format. Therefore you'll get the array shape of (1, 305, 295, 4). 1 project stage, 305x295 pixels, and 4 pixel values (RGBA).
+ You can use this image also for processing with other libraries. The screenshot above shows the image opened with `Pillow`.
+
+## Related
+
+* How-to: [Access element properties and data](../../howtos/python_api_introduction/python_api_introduction.md#access-element-properties)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/dialog_widgets.md.txt b/2022-new-headings-intros/_sources/python_examples/dialog_widgets.md.txt
new file mode 100644
index 0000000..d3d3b06
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/dialog_widgets.md.txt
@@ -0,0 +1,17 @@
+# dialog_widgets
+
+This is a collection of examples to create and handle script dialogs for user interaction.
+
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ dialog_widgets/*
+```
+
+
+```{seealso} How-to: [Using Script Dialogs](../howtos/python_api_introduction/script_dialogs_introduction.md)
+```
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/dialog_widgets/dropdown_widget.md.txt b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/dropdown_widget.md.txt
new file mode 100644
index 0000000..26fad9b
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/dropdown_widget.md.txt
@@ -0,0 +1,21 @@
+# dropdown_widget_dynamic
+
+![](dropdown_widget.jpg)
+
+## Short description
+
+This basic example shows how to use the dropdown widget and how define items at script runtime.
+
+## Highlights
+
+Suppose you have created a script dialog that contains a `Selection -> Selection element` widget with a widget name `list`.
+
+Then, you can define the items of this dropdown menu by script:
+
+```python
+DIALOG.list.items = ['yes', 'we', 'can']
+```
+
+## Related
+
+* How-to: [Using Script Dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.md.txt b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.md.txt
new file mode 100644
index 0000000..ec01e00
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.md.txt
@@ -0,0 +1,36 @@
+# explorer_selected_elements_in_dialog
+
+
+![](explorer_selected_elements_in_dialog.jpg)
+
+## Short description
+
+Sometimes you might want to get the list of elements currently selected in the element explorer. This example shows how to do so, e.g. in a script dialog.
+
+## Highlights
+
+You can get all elements of a certain category by using a `gom.ElementSelection`. Then you can iterate over this list to check which ones are currently selected.
+
+```python
+actual_elements = gom.ElementSelection ({'category': ['key', 'elements', 'part', gom.app.project.parts['Part'], 'explorer_category', 'actual']})
+selected_actuals = [element.name for element in actual_elements if element.is_selected]
+```
+
+```{hint}
+As the `gom.ElementSelection`s get pretty lengthy, it is advised to generate these expressions using the "Script Object" explorer (`F2`). Select a category of elements and directly click "OK" to insert a corresponding selection expression.
+
+![Script object explorer image](explorer_selected_elements_script_explorer.jpg)
+```
+
+In the example, an exemplary selection of elements is also triggered by the script:
+
+```python
+example_selection = [gom.app.project.actual_elements['Plane 1'], gom.app.project.actual_elements['Plane X +0.00 mm']]
+gom.script.explorer.apply_selection (selection=example_selection)
+```
+
+
+## Related
+
+* How-to: [Python API Introduction](../../howtos/python_api_introduction/python_api_introduction.md)
+* How-to: [Using Script Dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/dialog_widgets/unit_dialog_event_handler.md.txt b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/unit_dialog_event_handler.md.txt
new file mode 100644
index 0000000..e0748a4
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/unit_dialog_event_handler.md.txt
@@ -0,0 +1,36 @@
+# unit_dialog_event_handler
+
+![](unit_dialog_event_handler.jpg)
+
+## Short description
+
+This basic example demonstrates how to use an event handler on a script dialog to set the unit to multiple widgets.
+
+## Highlights
+
+After creating a dialog with `gom.script.sys.create_user_defined_dialog`, you can **set an event handler** to this dialog. In this simple case, the `unit` property of a decimal input widget and a tolerance widget are set according to what the user selected in the `DIALOG.unit` widget:
+
+```python
+if widget == DIALOG.unit:
+ DIALOG.input.unit = DIALOG.unit.value
+ DIALOG.tolerances.unit = DIALOG.unit.value
+```
+Another interesting part of this example is the corresponding **test**. In `addon_tests/test_dialog_widgets_unit_dialog` is shown how a very basic testing of the event_handler can be realized:
+
+```python
+DIALOG=example.setup_dialog()
+# Generating some events to test the event_handler
+unit_widget = DIALOG.unit
+unit_widget.value = "FORCE"
+
+# Test if the event_handler correctly links widget values
+DIALOG.handler(unit_widget)
+assert (DIALOG.input.unit == "FORCE")
+assert (DIALOG.tolerances.unit == "FORCE")
+```
+
+This usage of the `DIALOG.handler` function mimics the user-interaction of changing the value of the `unit` widget manually to `"FORCE"`.
+
+## Related
+
+* How-to: [Using Script Dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/dialog_widgets/widget_visibility.md.txt b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/widget_visibility.md.txt
new file mode 100644
index 0000000..53668a3
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/dialog_widgets/widget_visibility.md.txt
@@ -0,0 +1,24 @@
+# widget_visibility
+
+![](widget_visibility_off.jpg) ![](widget_visibility_on.jpg)
+
+## Short description
+
+This example shows how to use a dialog event handler to turn on/off widget visibilities.
+
+## Highlights
+
+The example dialog was designed to contain a simple text label symbolizing the main content. Below, you find a "More" section consisting of a title, toggle button and a second text label.
+The second label's visibility is changed (toggled) by the button.
+
+```python
+def dialog_event_handler (widget):
+ # [...]
+ if widget == DIALOG.button:
+ DIALOG.label_bottom.visible = not DIALOG.label_bottom.visible
+```
+
+
+## Related
+
+* How-to: [Using Script Dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/index.md.txt b/2022-new-headings-intros/_sources/python_examples/index.md.txt
new file mode 100644
index 0000000..cf29536
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/index.md.txt
@@ -0,0 +1,74 @@
+Added metadata:
+---
+myst:
+ html_meta:
+ "description": "Examples for using the GOM Inspect 2023 Add-on Python API"
+ "keywords": "Metrology, GOM Inspect, Python API, GOM API, Scripting, Packages, Add-ons, Examples"
+---
+# Overview
+
+Welcome to the GOM Inspect Python API Examples. Here you can find the documentation of the examples which are provided by the
+`Python API Examples` Add-On. You can reuse and adapt these code examples to your specific use case and learn the best-practices we recommend.
+
+## How the examples are structured
+
+You will find example scripts in a corresponding category folder, e.g. `data_interfaces`, `dialog_widgets`, etc.
+
+The folders of the example scripts correspond to the chapters of this documentation.
+Many of the examples have the following structure:
+
+```python
+
+def function1 ():
+
+
+def function2 ():
+ # -------------------------------------------------------------------------
+
+ # -------------------------------------------------------------------------
+
+[...]
+
+if __name__ == '__main__':
+ [...]
+ something = function1()
+ something2 = function2()
+ [...]
+
+```
+
+The most important spots of the example are marked with `# ------` comments in the code.
+
+Overall, this structure seems to be a little bit too complex for simple examples.
+The same result could be achieved by directly writing the `` in the script without separating it into functions.
+*However, this has a reason*. The functions `function1` and `function2` can be tested from another test script.
+You are highly encouraged to use this modular approach as well, to keep your code testable and reusable.
+
+If you are interested in testing add-ons (which you should be), learn more in our [Testing Add-Ons How-To](../howtos/testing_addons/testing_addons.md).
+
+## Example projects
+
+Most of the example scripts rely on a certain project file to be loaded. The add-on already contains these projects, and some examples load them automatically when it is possible (E.g. in the `if __name__ == '__main__'` block).
+
+Sometimes it is necessary to load projects manually. You can do this easily using the `setup_project.py` script.
+
+The following project files are included:
+
+| Project name | Description |
+| --------------------- | ------------------------------------------------------------------------- |
+| gom_part_test_project | Simple optically measured part with a CAD, mesh and some basic inspection |
+| volume_test_part | A small test volume for CT related inspections |
+
+## Examples by topic
+
+| Folder | Description |
+| --------------------------------------- | ------------------------------------------------------------ |
+| [data_interfaces](data_interfaces.md) | Access to data of GOM "elements" |
+| [dialog_widgets](dialog_widgets.md) | Examples how use custom dialogs and handle user input events |
+| [misc](misc.md) | Miscellaneous examples |
+| [script_icons](script_icons.md) | Set icons for scripts or buttons |
+| [script_resources](script_resources.md) | How to access binary data of your add-on (resources) |
+| [scripted_actuals](scripted_actuals.md) | Building actual elements with custom python code |
+| [scripted_checks](scripted_checks.md) | Building custom checks with python code |
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/misc.md.txt b/2022-new-headings-intros/_sources/python_examples/misc.md.txt
new file mode 100644
index 0000000..aa1c28e
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/misc.md.txt
@@ -0,0 +1,16 @@
+# misc
+
+This is a collection of examples that don't fit in any other category.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ misc/*
+```
+
+
+```{seealso} How-to: [Using Script Dialogs](../howtos/python_api_introduction/script_dialogs_introduction.md)
+```
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/misc/dialog_reopen_example.md.txt b/2022-new-headings-intros/_sources/python_examples/misc/dialog_reopen_example.md.txt
new file mode 100644
index 0000000..92504bd
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/misc/dialog_reopen_example.md.txt
@@ -0,0 +1,46 @@
+# dialog_reopen_example
+
+![](dialog_reopen_example.jpg)
+
+## Short description
+
+This examples demonstrates, how a dialog can be closed from its own handler, just to be opened again.
+
+```{warning}
+There are very rare occasions, where you should need this. Use this approach only, if you know what you are doing.
+```
+
+## Highlights
+
+The approach consists of two steps. First, declare a guard variable that yields `True` if the dialog should be reopened.
+
+```python
+[...]
+reopen = True
+while reopen:
+ gom.script.sys.show_user_defined_dialog (dialog=DIALOG)
+```
+
+The example dialog contains a button to close/reopen the dialog (see top image). One of the few use cases could be, that you need to adapt the `filter` property of an `Selection element` widget after some dialog interaction, which can only be done when the dialog is closed.
+
+To achieve this, the dialog event handler is used:
+
+```python
+def dialog_event_handler (widget):
+ global reopen
+ if str(widget) == "initialize":
+ reopen = False
+ if widget == DIALOG.button:
+ gom.script.sys.close_user_defined_dialog (dialog=DIALOG)
+ gom.script.sys.delay_script (time=1) # Do stuff while dialog is closed
+ reopen = True
+```
+
+```{warning}
+Never reopen the dialog directly from its own handler to prevent getting undefined behaviour.
+```
+
+
+## Related
+
+* How-to: [Using Script Dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/script_icons.md.txt b/2022-new-headings-intros/_sources/python_examples/script_icons.md.txt
new file mode 100644
index 0000000..3e8bc65
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/script_icons.md.txt
@@ -0,0 +1,12 @@
+# script_icons
+
+This is a collection of examples regarding script icons.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ script_icons/*
+```
diff --git a/2022-new-headings-intros/_sources/python_examples/script_icons/script_icon_from_file.md.txt b/2022-new-headings-intros/_sources/python_examples/script_icons/script_icon_from_file.md.txt
new file mode 100644
index 0000000..9800cea
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/script_icons/script_icon_from_file.md.txt
@@ -0,0 +1,28 @@
+# script_icon_from_file
+
+![](menu_icon_lightbg.jpg)
+
+
+## Short description
+
+This is a small example to show how an icon can be set to a script, whereas the icon itself resides in the add-on as a resource.
+
+```{note}
+This example is meant as addition to the information given in how-to: [Adding workspaces to packages - Icon guidelines](../../howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.md#icon-guidelines).
+```
+
+## Highlights
+
+Normally, the icon can be set using the "Script properties" dialog accessible by right-click in the Script Editor of the GOM Software.
+
+However, using VS Code or another text editor, the corresponding `.metainfo` files of the scripts can be edited directly. If you have icon files within your add-on, you can directly enter the relative path to the icon in the `"icon"` property.
+
+![](script_icon_from_file.jpg)
+
+If you use this approach, and follow our [icon guidelines](../../howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.md#icon-guidelines), the icons get inverted in dark themes automatically.
+
+![](menu_icon_darkbg.jpg)
+
+## Related
+
+* How-to: [Adding workspaces to packages](../../howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/script_resources.md.txt b/2022-new-headings-intros/_sources/python_examples/script_resources.md.txt
new file mode 100644
index 0000000..7197996
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/script_resources.md.txt
@@ -0,0 +1,12 @@
+# script_resources
+
+This is a collection of examples demonstrating how to use binary data (resources) in your scripts.
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ script_resources/*
+```
diff --git a/2022-new-headings-intros/_sources/python_examples/script_resources/resource_api_example.md.txt b/2022-new-headings-intros/_sources/python_examples/script_resources/resource_api_example.md.txt
new file mode 100644
index 0000000..75e5b95
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/script_resources/resource_api_example.md.txt
@@ -0,0 +1,37 @@
+# resource_api_example
+
+![](script_resources.jpg)
+## Short description
+
+A simple example showing the usage of script resources.
+
+## Highlights
+
+The example shows how to list available resources:
+```python
+gom.Resource.list()
+```
+
+Then, depending on whether a resource is found (by name), this resource is read or created with the content `Hello World`.
+
+```python
+res = gom.Resource("test_resource.txt")
+ if (res.exists ()):
+ print ("Resource found with content: ", get_resource_content(res))
+ else:
+ string_bytes = b"Hello World"
+ create_resource_with_content ("test_resource.txt", string_bytes)
+ print ("Resource created with content:", string_bytes)
+```
+
+Output:
+```
+> Resource found with content: b'Hello World'
+```
+
+For details on how to read and write resource data, see the related documentation below.
+
+## Related
+
+* [How to: Using script resources](../../howtos/python_api_introduction/using_script_resources.md)
+* [`gom.Resource` API Definition](../../python_api/resource_api.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_actuals.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_actuals.md.txt
new file mode 100644
index 0000000..8fe1d5f
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_actuals.md.txt
@@ -0,0 +1,16 @@
+# scripted_actuals
+
+This is a collection of examples of scripted actual elements.
+
+```{seealso}
+For an introduction to scripted (actual) elements, see the [introduction to scripted elements](../howtos/scripted_elements/scripted_elements_introduction.md) and [How-to: Scripted actuals](../howtos/scripted_elements/scripted_actuals.md).
+```
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ scripted_actuals/*
+```
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_actuals/offset_point_simple.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/offset_point_simple.md.txt
new file mode 100644
index 0000000..79e6acf
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/offset_point_simple.md.txt
@@ -0,0 +1,12 @@
+# offset_point_simple
+
+![](../../howtos/scripted_elements/assets/scripted_actual_explorer.jpg)
+
+## Short description
+
+```{note}
+This is a basic example meant to introduce you to the concept of scripted actual elements. Therefore, head over to the [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md) for the documentation of this example.
+```
+## Related
+
+* [offset_point_v2](offset_point_v2.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_actuals/offset_point_v2.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/offset_point_v2.md.txt
new file mode 100644
index 0000000..a4e87de
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/offset_point_v2.md.txt
@@ -0,0 +1,127 @@
+# offset_point_v2
+
+![](offset_point_v2.jpg)
+## Short description
+
+This example is an extension of the `offset_point_simple` example, which has been discussed in the general [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md#example-simple-offset-point).
+It shows how to enhance user experience using preview calculation and error handling.
+
+## Highlights
+
+### Preview calculation
+
+From many of the built-in commands of the GOM Software, you know the calculation of a preview element during the creation dialog. This means, you can already see the calculation result in the 3D view, while tweaking some parameters in the dialog.
+
+To achieve this behaviour in a scripted element, you need to set up an event handler for the dialog (see also: [How-to: Using script dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)).
+
+
+```{code-block} python
+---
+linenos:
+---
+def dialog_event_handler (widget):
+ # No treatment of system events
+ if str(widget) == 'system':
+ return
+ # If preview calculation returned with error
+ if str(widget) == 'error':
+ DIALOG.control.status = context.error
+ return
+ # If preview calculation was successful
+ if str(widget) == 'calculated':
+ DIALOG.control.status = ''
+ DIALOG.control.ok.enabled = True
+ return
+
+ # All other changes in the dialog --> calculate preview
+ params['x'] = DIALOG.i_x.value;
+ params['y'] = DIALOG.i_y.value;
+ params['z'] = DIALOG.i_z.value;
+ params['base'] = DIALOG.point.value
+ context.name = DIALOG.name.value
+ DIALOG.control.ok.enabled = False
+ context.calc(params=params, dialog=DIALOG)
+
+DIALOG.handler = dialog_event_handler
+```
+
+The event handler function is to be defined taking one argument. This argument will be a handle to the cause (the event) triggering the handler. This can be a string message or a handle to a specific widget of the dialog. We'll come back to this in a second
+
+The handler function shown above basically reads the current set of parameters from the `DIALOG` to the `params` array (lines 16-19). In this case, the offset values and base point. Then, the preview calculation is started using the special functional `context.calc`, which is a function handle taking the set of `params` and a reference to the dialog triggering the preview (line 22).
+
+
+```{attention}
+Only call `context.calc(...)` from a script dialog's *event handler* function, **NOT** from the scripted element's `dialog` function itself.
+```
+
+The handler is applied to the dialog in the `dialog` function of the scripted element, just before the dialog is shown to the user (line 23).
+
+### Status and error handling
+
+Using the dialog's event handler, we can also make the dialog responsive to successful or failed preview calculations. Therefore, the `DIALOG.control.ok.enabled` can be used to control the enabledness of the dialog's OK button.
+
+In line 21, the OK button is disabled before preview calculation is started.
+
+Furthermore, the scripted element framework provides two special event triggers: `error` and `calculated`, which are sent on failing/success of the `calculation` function to the dialog referenced in the `context.calc` call.
+
+In this case, we set a potential error message of a failed calcualtion to the dialogs error indicator (line 7), or enable the OK button and reset the error indicator in case of a successful calculation (lines 11-12).
+
+
+### Stageful `calculation` and error handling
+
+Above, we discussed changes applied to the scripted element's `dialog` function. Now, let's take a look at the `calculation` function.
+
+```{code-block} python
+---
+linenos:
+---
+def calculation(context, params):
+ valid_results=False
+ # Calculating all available stages
+ for stage in context.stages:
+ # Access element properties with error handling
+ try:
+ base = params['base'].in_stage[stage].center_coordinate
+ context.result[stage] = (base.x + params['x'], base.y + params['y'], base.z + params['z'])
+ context.data[stage] = { "ude_mykey" : 123456 }
+ except Exception as error:
+ context.error[stage] = str(error)
+ else:
+ valid_results=True
+ return valid_results
+```
+
+The first noticeable difference to the *offset_point_simple* example is the calculation over all *stages* of the project, whose indices can be obtained using `context.stages` (line 4).
+
+```{seealso}
+If you are not familiar with the concept of *stages*, get an impression in our [Starter Training](https://training.gom.com/course/277348/module/788965).
+```
+
+Second, the [access of element properties](../../howtos/python_api_introduction/python_api_introduction.md#access-element-properties) is also respecting the current stage using the `.in_stage` mechanism (line 7).
+
+Third, you can see that the calculation is surrounded by a `try/except` block that catches potential errors and sets arising error messages to `context.error`. This examples catches all exceptions in a very basic way. In a real-world application, you should distinguish several types of exceptions you'd expect and set meaningful error messages. The `context.error` message is then handled in the dialog as discussed above (see [Status and error handling](#status-and-error-handling)).
+
+### Storing generic element data
+
+You can observe an assignment to the `context.data` member (line 9). If you assign a dictionary (map) to this data structure, you can save *user-defined tokens* to the scripted element. These are key/value pairs that can hold generic information you might to retrieve in consecutive scripts or checks that reference the created scripted element.
+
+```{note}
+Keys of *user-defined tokens* need to start with `ude_`. For more information, see the [Scripted elements API documentation](../../python_api/scripted_elements_api.md).
+```
+
+After element creation of such an offset point with name "Offset point 1", you could access this data again like:
+```python
+import gom
+
+print (gom.app.project.actual_elements['Offset point 1'].ude_mykey)
+```
+Output:
+```
+> 123456
+```
+
+
+## Related
+
+* [Example: offset_point_simple](offset_point_simple.md)
+* [How-to: Using script dialogs](../../howtos/python_api_introduction/script_dialogs_introduction.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_actuals/scripted_element_progress.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/scripted_element_progress.md.txt
new file mode 100644
index 0000000..36c0eaf
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/scripted_element_progress.md.txt
@@ -0,0 +1,27 @@
+# scripted_element_progress
+
+![](scripted_element_progress_preview.jpg)
+
+![](scripted_element_progress_computation.jpg)
+## Short description
+
+This examples demonstrates how to show progress information to the user while calcualting a scripted element.
+## Highlights
+
+The scripted element itself is not of interest here, as it is rather meaningless: a point that will always be created at *(1,0,0)*.
+To showcase the display of calculation progress, a loop with 100 steps containing a `sleep` call to simulate computation are performed in the `calculation` function:
+
+```python
+def calculation (context, params):
+ context.progress_stages_total = limit
+ for i in range(limit):
+ context.progress_stages_computing = i
+ time.sleep (0.1)
+
+ # [...]
+```
+To indicate progress, you need to set `context.progress_stages_total` to the amount of steps you expect to compute. This can but not has to be the number of stages in trend projects. You can also set any arbitrary number. As soon as you set `context.progress_stages_computing`, the progress will be indicated in the bottom are of the application (see top screenshot).
+
+## Related
+
+* How-to: [Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_actuals/trimesh_deform_mesh.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/trimesh_deform_mesh.md.txt
new file mode 100644
index 0000000..9ac46b9
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_actuals/trimesh_deform_mesh.md.txt
@@ -0,0 +1,67 @@
+# trimesh_deform_mesh
+
+![](trimesh_deform_mesh.jpg)
+## Short description
+
+This example demonstrates how to generate a custom surface element using a scripted element. The example script accesses mesh information from an existing mesh in the project and adds a random deformation to each point.
+
+Finally, the result is transfered back to the GOM Software, where an actual surface element is created.
+
+## Highlights
+
+The dialog was created using the script dialog editor and contains an "Element selection" widget to let the user choose which mesh to deform.
+
+### Dialog: Element filter
+
+In the script, a filter function is implemented to populate the "Element selection" widget only with elements of a certain type. To this end, the widget's type property is first set to "User-defined script function".
+
+![](trimesh_deform_mesh_dialog.jpg)
+
+Then, in the script, the filter property is set to the following function:
+
+```python
+def element_filter(element):
+ try:
+ if element.type in ['mesh','cad_body']:
+ return True
+ except Exception as e:
+ pass
+ return False
+
+ DIALOG.selected_element.filter = element_filter
+```
+
+Furthermore, the dialog contains a name widget with a default name set for the result element and a decimal widget to let the user choose the magnitude of deformation.
+
+
+### Calculation: Mesh deformation with `trimesh`
+
+The logic of mesh deformation happens in the calculation function. Here, the stored parameters are read from the 'params' array and used to perform the calculation.
+
+The access to the mesh data is done via numpy arrays that can be retrieved by an elements data interface. This interface is accessible by the `.data` property and yields the results usually for all stages. Using `[s]` as a subscript gives the data for stage `s`.
+
+```python
+ vertices = np.array (selected_element.data.coordinate)[s]
+ triangles = np.array (selected_element.data.triangle)[s]
+
+ # Creating a mesh in 3rd party library "trimesh"
+ mesh = trimesh.Trimesh (vertices, triangles)
+
+ # Using the deformation algorithm of trimesh
+ deformed = trimesh.permutate.noise (mesh, deformation)
+
+ # Converting to target dtypes
+ deformed_vertices = deformed.vertices
+ deformed_faces = np.array (deformed.faces, dtype=np.int32)
+
+ # Setting the result to transfer back to the GOM Software
+ context.result[s] = { 'vertices': deformed_vertices, 'triangles': deformed_faces }
+```
+
+In this case, we retrieve the vertices and triangles of the selected mesh.
+To deform the mesh, we then apply some noise to the data using [trimesh's noise permutator](https://trimsh.org/trimesh.permutate.html#trimesh.permutate.noise). We finally transform our results into the supported formats and set the results of this stage in the `context.result[s]` variable.
+
+
+## Related
+
+* How-to: [Python API introduction - Element data interfaces](../../howtos/python_api_introduction/python_api_introduction.md#element-data-interfaces)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_checks.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_checks.md.txt
new file mode 100644
index 0000000..8e00c82
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_checks.md.txt
@@ -0,0 +1,16 @@
+# scripted_checks
+
+This is a collection of examples of scripted check elements.
+
+```{seealso}
+For an introduction to scripted checks, see the [How-to: Scripted checks](../howtos/scripted_elements/scripted_checks.md).
+```
+
+```{eval-rst}
+.. toctree::
+ :maxdepth: 1
+ :glob:
+ :caption: Examples of this category
+
+ scripted_checks/*
+```
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_curve_check.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_curve_check.md.txt
new file mode 100644
index 0000000..c486283
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_curve_check.md.txt
@@ -0,0 +1,72 @@
+# scripted_curve_check
+
+![](scripted_curve_check.jpg)
+
+## Short description
+
+This example demonstrates how to create a scalar curve check by a script. Also, the usage of custom coordinate systems in scripted checks is shown.
+
+## Highlights
+
+First of all, we need to check if the element selected by the user by the `DIALOG.slct_element` widget is suitable for being checked with a curve check. You can implement your own filter for that, but you can also use the API convenience function for that purpose, which only allow "curve-like" elements:
+
+```python
+DIALOG.slct_element.filter = gom.api.scripted_checks_util.is_curve_checkable
+```
+
+To allow calculation in a custom coordinate system (one that exists in the project), a second `Selection element` widget is inserted in the dialog, here named `cs`. In the `dialog` function, its value is saved to the element parameters. In case of no selected coordinate system, the viewing coordinate system is used.
+
+```python
+def dialog (context, params):
+ # [...]
+ params['coordinate_system'] = DIALOG.cs.value
+ if params['coordinate_system'] is None:
+ params['coordinate_system'] = gom.app.project.view_csys
+```
+
+Having this *reference* to a coordinate system, we can use the API function `scripted_checks_util.get_cs_transformation_4x4` to get a 4x4 matrix for computation.
+
+During the computation for all stages, we then apply this (affine) transformation using the dot product.
+
+```python
+def calculation (context, params):
+ # [...]
+ trafo_matrices = np.array (gom.api.scripted_checks_util.get_cs_transformation_4x4 (params["coordinate_system"]))
+ # [...]
+
+ # Apply coordinate transformation to all vertices if necessary
+ if trafo_matrices is not None:
+ stage_trafo = trafo_matrices[s]
+ stage_vertices = (np.dot(stage_trafo[0:3, 0:3], stage_vertices.T) + stage_trafo[:3,3:]).T
+
+ # The result of this stage to be filled
+ actual_result = np.zeros (stage_vertices.shape[0])
+ nominal_result = np.random.rand (stage_vertices.shape[0])
+
+ for i in range (stage_vertices.shape[0]):
+ point = gom.Vec3d (stage_vertices[i][0], stage_vertices[i][1], stage_vertices[i][2])
+
+ # ----------------------------------------------------
+ # --- insert your calculation for each vertex here ---
+ # ----------------------------------------------------
+ actual_result[i] = point.y
+ # ----------------------------------------------------
+```
+
+Finally, the result is to be set. For each point of the referenced curve, a nominal and actual value is needed. Therefore, the result takes the following form, where `actual_result` and `nominal_result` are vectors with the same length (number of curve points).
+
+```python
+result = { "actual_values" : actual_result, "reference" : element, 'nominal_values': nominal_result }
+```
+
+In this case, the result is just the `y` coordinate of each point to easily see the correctness of the results including a given transformation.
+
+Using the example project `gom_part_test_project` and the viewing coordinate system, you get the screenshot shown on top. However, if you select the coordinate system `Cylinder 1|Plane 1|Origin`, you can see the transformation in effect:
+
+![](scripted_curve_check_cs.jpg)
+
+
+## Related
+
+* [How-to: Scripted checks](../../howtos/scripted_elements/scripted_checks.md)
+* [Scripted Element API](../../python_api/scripted_elements_api.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_scalar_check.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_scalar_check.md.txt
new file mode 100644
index 0000000..30d20e2
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_scalar_check.md.txt
@@ -0,0 +1,52 @@
+# scripted_scalar_check
+
+![](scripted_scalar_check.jpg)
+
+## Short description
+
+This example shows how to create a scalar check by script. A scalar check is the most basic check, as it assigns a scalar value to an element. Nearly all elements you can find in the software can be checked like this.
+
+```{note}
+A scripted check has a lot in common with the scripted actual elements. Therefore, the identical mechanisms and concepts will not be explained here. See [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md) if you are not already familiar with the concept of scripted elements.
+```
+
+## Highlights
+
+First of all, we need to check if the element selected by the user by the `DIALOG.slct_element` widget is suitable for being checked with a scalar check. You can implement your own filter for that, but you can also use the API convenience function for that purpose:
+
+```python
+DIALOG.slct_element.filter = gom.api.scripted_checks_util.is_scalar_checkable
+```
+
+As you can assign a scalar value to all common element types, this filter allows all element types available in the *element explorer*.
+
+Furthermore, as described in the [How-to: Scripted checks](../../howtos/scripted_elements/scripted_checks.md), the special parameters for scripted checks are also assigned in the `dialog` function. For ease of use, the respective dialog widgets are used, so we only need to assign the widgets' values to the parameters array.
+
+```python
+def dialog (context, params):
+ # [...]
+ params['tolerance'] = DIALOG.tolerances.value
+ params['unit'] = DIALOG.unit.value
+ params['abbreviation'] = 'ScrSca'
+```
+
+In the calculation function, there is not much calculation but just an exemplary assignment of scalar values to the result. For the scripted `Scalar check`, the result dictionary needs to contain `"nominal"` and `"actual"` members, as well as a reference to the element which is checked.
+
+
+```python
+def calculation (context, params):
+ # [...]
+ for s in context.stages:
+ actual_result = 1.0
+ nominal_result = 2.0
+
+ context.result[s] = {"nominal" : nominal_result,
+ "actual" : actual_result,
+ "reference" : element }
+ return True
+```
+
+## Related
+
+* [How-to: Scripted checks](../../howtos/scripted_elements/scripted_checks.md)
+* [Scripted Element API](../../python_api/scripted_elements_api.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_surface_check.md.txt b/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_surface_check.md.txt
new file mode 100644
index 0000000..91c19e7
--- /dev/null
+++ b/2022-new-headings-intros/_sources/python_examples/scripted_checks/scripted_surface_check.md.txt
@@ -0,0 +1,35 @@
+# scripted_surface_check
+
+![](scripted_surface_check.jpg)
+
+## Short description
+
+This example demonstrates how to create a scalar surface check by a script. Also, the usage of custom coordinate systems and element preview in scripted checks is shown.
+
+## Highlights
+
+First of all, we need to check if the element selected by the user by the `DIALOG.slct_element` widget is suitable for being checked with a surface check. You can implement your own filter for that, but you can also use the API convenience function for that purpose, which only allow "mesh-like" elements:
+
+```python
+DIALOG.slct_element.filter = gom.api.scripted_checks_util.is_surface_checkable
+```
+
+The usage of custom coordinate systems is the same as described in the [scripted_curve_check](scripted_curve_check.md) example.
+
+Finally, the result is to be set. For each point of the referenced mesh, a deviation value is needed. Therefore, the result takes the following form, where `deviation_result` is a vector with length equal to number of mesh points.
+
+```python
+result = { "deviation_values" : deviation_result , "reference" : element }
+```
+
+As in the [scripted_curve_check](scripted_curve_check.md) example, the result for each point is just the respective `y` coordinate to easily see the correctness of the results including a given transformation.
+
+Using the example project `gom_part_test_project` and the viewing coordinate system, you get the screenshot shown on top. However, if you select the coordinate system `Cylinder 1|Plane 1|Origin`, you can see the transformation in effect:
+
+![](scripted_surface_check_cs.jpg)
+
+
+## Related
+
+* [How-to: Scripted checks](../../howtos/scripted_elements/scripted_checks.md)
+* [Scripted Element API](../../python_api/scripted_elements_api.md)
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/_sphinx_javascript_frameworks_compat.js b/2022-new-headings-intros/_static/_sphinx_javascript_frameworks_compat.js
new file mode 100644
index 0000000..8141580
--- /dev/null
+++ b/2022-new-headings-intros/_static/_sphinx_javascript_frameworks_compat.js
@@ -0,0 +1,123 @@
+/* Compatability shim for jQuery and underscores.js.
+ *
+ * Copyright Sphinx contributors
+ * Released under the two clause BSD licence
+ */
+
+/**
+ * small helper function to urldecode strings
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
+ */
+jQuery.urldecode = function(x) {
+ if (!x) {
+ return x
+ }
+ return decodeURIComponent(x.replace(/\+/g, ' '));
+};
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+ if (typeof s === 'undefined')
+ s = document.location.search;
+ var parts = s.substr(s.indexOf('?') + 1).split('&');
+ var result = {};
+ for (var i = 0; i < parts.length; i++) {
+ var tmp = parts[i].split('=', 2);
+ var key = jQuery.urldecode(tmp[0]);
+ var value = jQuery.urldecode(tmp[1]);
+ if (key in result)
+ result[key].push(value);
+ else
+ result[key] = [value];
+ }
+ return result;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+ function highlight(node, addItems) {
+ if (node.nodeType === 3) {
+ var val = node.nodeValue;
+ var pos = val.toLowerCase().indexOf(text);
+ if (pos >= 0 &&
+ !jQuery(node.parentNode).hasClass(className) &&
+ !jQuery(node.parentNode).hasClass("nohighlight")) {
+ var span;
+ var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.className = className;
+ }
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling));
+ node.nodeValue = val.substr(0, pos);
+ if (isInSVG) {
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ var bbox = node.parentElement.getBBox();
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute('class', className);
+ addItems.push({
+ "parent": node.parentNode,
+ "target": rect});
+ }
+ }
+ }
+ else if (!jQuery(node).is("button, select, textarea")) {
+ jQuery.each(node.childNodes, function() {
+ highlight(this, addItems);
+ });
+ }
+ }
+ var addItems = [];
+ var result = this.each(function() {
+ highlight(this, addItems);
+ });
+ for (var i = 0; i < addItems.length; ++i) {
+ jQuery(addItems[i].parent).before(addItems[i].target);
+ }
+ return result;
+};
+
+/*
+ * backward compatibility for jQuery.browser
+ * This will be supported until firefox bug is fixed.
+ */
+if (!jQuery.browser) {
+ jQuery.uaMatch = function(ua) {
+ ua = ua.toLowerCase();
+
+ var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
+ /(webkit)[ \/]([\w.]+)/.exec(ua) ||
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
+ /(msie) ([\w.]+)/.exec(ua) ||
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
+ [];
+
+ return {
+ browser: match[ 1 ] || "",
+ version: match[ 2 ] || "0"
+ };
+ };
+ jQuery.browser = {};
+ jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
+}
diff --git a/2022-new-headings-intros/_static/basic.css b/2022-new-headings-intros/_static/basic.css
new file mode 100644
index 0000000..7577acb
--- /dev/null
+++ b/2022-new-headings-intros/_static/basic.css
@@ -0,0 +1,903 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+div.section::after {
+ display: block;
+ content: '';
+ clear: left;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+ word-wrap: break-word;
+ overflow-wrap : break-word;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox form.search {
+ overflow: hidden;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+ float: left;
+ width: 80%;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+ float: left;
+ width: 20%;
+ border-left: none;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+
+img {
+ border: 0;
+ max-width: 100%;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li p.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ list-style-type: none;
+}
+
+table.indextable > tbody > tr > td > ul {
+ padding-left: 0em;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- domain module index --------------------------------------------------- */
+
+table.modindextable td {
+ padding: 2px;
+ border-collapse: collapse;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+div.body {
+ min-width: 360px;
+ max-width: 800px;
+}
+
+div.body p, div.body dd, div.body li, div.body blockquote {
+ -moz-hyphens: auto;
+ -ms-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+caption:hover > a.headerlink,
+p.caption:hover > a.headerlink,
+div.code-block-caption:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, figure.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, figure.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, figure.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+img.align-default, figure.align-default, .figure.align-default {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-default {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar,
+aside.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+ clear: right;
+ overflow-x: auto;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+nav.contents,
+aside.topic,
+div.admonition, div.topic, blockquote {
+ clear: left;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+nav.contents,
+aside.topic,
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- content of sidebars/topics/admonitions -------------------------------- */
+
+div.sidebar > :last-child,
+aside.sidebar > :last-child,
+nav.contents > :last-child,
+aside.topic > :last-child,
+div.topic > :last-child,
+div.admonition > :last-child {
+ margin-bottom: 0;
+}
+
+div.sidebar::after,
+aside.sidebar::after,
+nav.contents::after,
+aside.topic::after,
+div.topic::after,
+div.admonition::after,
+blockquote::after {
+ display: block;
+ content: '';
+ clear: both;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.align-default {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table caption span.caption-number {
+ font-style: italic;
+}
+
+table caption span.caption-text {
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+th > :first-child,
+td > :first-child {
+ margin-top: 0px;
+}
+
+th > :last-child,
+td > :last-child {
+ margin-bottom: 0px;
+}
+
+/* -- figures --------------------------------------------------------------- */
+
+div.figure, figure {
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.figure p.caption, figcaption {
+ padding: 0.3em;
+}
+
+div.figure p.caption span.caption-number,
+figcaption span.caption-number {
+ font-style: italic;
+}
+
+div.figure p.caption span.caption-text,
+figcaption span.caption-text {
+}
+
+/* -- field list styles ----------------------------------------------------- */
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.field-name {
+ -moz-hyphens: manual;
+ -ms-hyphens: manual;
+ -webkit-hyphens: manual;
+ hyphens: manual;
+}
+
+/* -- hlist styles ---------------------------------------------------------- */
+
+table.hlist {
+ margin: 1em 0;
+}
+
+table.hlist td {
+ vertical-align: top;
+}
+
+/* -- object description styles --------------------------------------------- */
+
+.sig {
+ font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+}
+
+.sig-name, code.descname {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+.sig-name {
+ font-size: 1.1em;
+}
+
+code.descname {
+ font-size: 1.2em;
+}
+
+.sig-prename, code.descclassname {
+ background-color: transparent;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.sig-paren {
+ font-size: larger;
+}
+
+.sig-param.n {
+ font-style: italic;
+}
+
+/* C++ specific styling */
+
+.sig-inline.c-texpr,
+.sig-inline.cpp-texpr {
+ font-family: unset;
+}
+
+.sig.c .k, .sig.c .kt,
+.sig.cpp .k, .sig.cpp .kt {
+ color: #0033B3;
+}
+
+.sig.c .m,
+.sig.cpp .m {
+ color: #1750EB;
+}
+
+.sig.c .s, .sig.c .sc,
+.sig.cpp .s, .sig.cpp .sc {
+ color: #067D17;
+}
+
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+:not(li) > ol > li:first-child > :first-child,
+:not(li) > ul > li:first-child > :first-child {
+ margin-top: 0px;
+}
+
+:not(li) > ol > li:last-child > :last-child,
+:not(li) > ul > li:last-child > :last-child {
+ margin-bottom: 0px;
+}
+
+ol.simple ol p,
+ol.simple ul p,
+ul.simple ol p,
+ul.simple ul p {
+ margin-top: 0;
+}
+
+ol.simple > li:not(:first-child) > p,
+ul.simple > li:not(:first-child) > p {
+ margin-top: 0;
+}
+
+ol.simple p,
+ul.simple p {
+ margin-bottom: 0;
+}
+
+aside.footnote > span,
+div.citation > span {
+ float: left;
+}
+aside.footnote > span:last-of-type,
+div.citation > span:last-of-type {
+ padding-right: 0.5em;
+}
+aside.footnote > p {
+ margin-left: 2em;
+}
+div.citation > p {
+ margin-left: 4em;
+}
+aside.footnote > p:last-of-type,
+div.citation > p:last-of-type {
+ margin-bottom: 0em;
+}
+aside.footnote > p:last-of-type:after,
+div.citation > p:last-of-type:after {
+ content: "";
+ clear: both;
+}
+
+dl.field-list {
+ display: grid;
+ grid-template-columns: fit-content(30%) auto;
+}
+
+dl.field-list > dt {
+ font-weight: bold;
+ word-break: break-word;
+ padding-left: 0.5em;
+ padding-right: 5px;
+}
+
+dl.field-list > dd {
+ padding-left: 0.5em;
+ margin-top: 0em;
+ margin-left: 0em;
+ margin-bottom: 0em;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd > :first-child {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dl > dd:last-child,
+dl > dd:last-child > :last-child {
+ margin-bottom: 0;
+}
+
+dt:target, span.highlighted {
+ background-color: #fbe54e;
+}
+
+rect.highlighted {
+ fill: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa;
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+.classifier:before {
+ font-style: normal;
+ margin: 0 0.5em;
+ content: ":";
+ display: inline-block;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+pre, div[class*="highlight-"] {
+ clear: both;
+}
+
+span.pre {
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ -webkit-hyphens: none;
+ hyphens: none;
+ white-space: nowrap;
+}
+
+div[class*="highlight-"] {
+ margin: 1em 0;
+}
+
+td.linenos pre {
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ display: block;
+}
+
+table.highlighttable tbody {
+ display: block;
+}
+
+table.highlighttable tr {
+ display: flex;
+}
+
+table.highlighttable td {
+ margin: 0;
+ padding: 0;
+}
+
+table.highlighttable td.linenos {
+ padding-right: 0.5em;
+}
+
+table.highlighttable td.code {
+ flex: 1;
+ overflow: hidden;
+}
+
+.highlight .hll {
+ display: block;
+}
+
+div.highlight pre,
+table.highlighttable pre {
+ margin: 0;
+}
+
+div.code-block-caption + div {
+ margin-top: 0;
+}
+
+div.code-block-caption {
+ margin-top: 1em;
+ padding: 2px 5px;
+ font-size: small;
+}
+
+div.code-block-caption code {
+ background-color: transparent;
+}
+
+table.highlighttable td.linenos,
+span.linenos,
+div.highlight span.gp { /* gp: Generic.Prompt */
+ user-select: none;
+ -webkit-user-select: text; /* Safari fallback only */
+ -webkit-user-select: none; /* Chrome/Safari */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* IE10+ */
+}
+
+div.code-block-caption span.caption-number {
+ padding: 0.1em 0.3em;
+ font-style: italic;
+}
+
+div.code-block-caption span.caption-text {
+}
+
+div.literal-block-wrapper {
+ margin: 1em 0;
+}
+
+code.xref, a code {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+span.eqno a.headerlink {
+ position: absolute;
+ z-index: 1;
+}
+
+div.math:hover a.headerlink {
+ visibility: visible;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/css/badge_only.css b/2022-new-headings-intros/_static/css/badge_only.css
new file mode 100644
index 0000000..c718cee
--- /dev/null
+++ b/2022-new-headings-intros/_static/css/badge_only.css
@@ -0,0 +1 @@
+.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Bold.woff b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Bold.woff
new file mode 100644
index 0000000..6cb6000
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Bold.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Bold.woff2 b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Bold.woff2
new file mode 100644
index 0000000..7059e23
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Bold.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Regular.woff b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Regular.woff
new file mode 100644
index 0000000..f815f63
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Regular.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Regular.woff2 b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Regular.woff2
new file mode 100644
index 0000000..f2c76e5
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/Roboto-Slab-Regular.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.eot b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..e9f60ca
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.eot differ
diff --git a/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.svg b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000..855c845
--- /dev/null
+++ b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.svg
@@ -0,0 +1,2671 @@
+
+
+
+
+Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016
+ By ,,,
+Copyright Dave Gandy 2016. All rights reserved.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.ttf b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..35acda2
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.ttf differ
diff --git a/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.woff b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..400014a
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.woff2 b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.woff2
new file mode 100644
index 0000000..4d13fc6
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/fontawesome-webfont.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-bold-italic.woff b/2022-new-headings-intros/_static/css/fonts/lato-bold-italic.woff
new file mode 100644
index 0000000..88ad05b
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-bold-italic.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-bold-italic.woff2 b/2022-new-headings-intros/_static/css/fonts/lato-bold-italic.woff2
new file mode 100644
index 0000000..c4e3d80
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-bold-italic.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-bold.woff b/2022-new-headings-intros/_static/css/fonts/lato-bold.woff
new file mode 100644
index 0000000..c6dff51
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-bold.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-bold.woff2 b/2022-new-headings-intros/_static/css/fonts/lato-bold.woff2
new file mode 100644
index 0000000..bb19504
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-bold.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-normal-italic.woff b/2022-new-headings-intros/_static/css/fonts/lato-normal-italic.woff
new file mode 100644
index 0000000..76114bc
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-normal-italic.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-normal-italic.woff2 b/2022-new-headings-intros/_static/css/fonts/lato-normal-italic.woff2
new file mode 100644
index 0000000..3404f37
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-normal-italic.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-normal.woff b/2022-new-headings-intros/_static/css/fonts/lato-normal.woff
new file mode 100644
index 0000000..ae1307f
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-normal.woff differ
diff --git a/2022-new-headings-intros/_static/css/fonts/lato-normal.woff2 b/2022-new-headings-intros/_static/css/fonts/lato-normal.woff2
new file mode 100644
index 0000000..3bf9843
Binary files /dev/null and b/2022-new-headings-intros/_static/css/fonts/lato-normal.woff2 differ
diff --git a/2022-new-headings-intros/_static/css/theme.css b/2022-new-headings-intros/_static/css/theme.css
new file mode 100644
index 0000000..19a446a
--- /dev/null
+++ b/2022-new-headings-intros/_static/css/theme.css
@@ -0,0 +1,4 @@
+html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*!
+ * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block}
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/doctools.js b/2022-new-headings-intros/_static/doctools.js
new file mode 100644
index 0000000..d06a71d
--- /dev/null
+++ b/2022-new-headings-intros/_static/doctools.js
@@ -0,0 +1,156 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Base JavaScript utilities for all Sphinx HTML documentation.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+"use strict";
+
+const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
+ "TEXTAREA",
+ "INPUT",
+ "SELECT",
+ "BUTTON",
+]);
+
+const _ready = (callback) => {
+ if (document.readyState !== "loading") {
+ callback();
+ } else {
+ document.addEventListener("DOMContentLoaded", callback);
+ }
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const Documentation = {
+ init: () => {
+ Documentation.initDomainIndexTable();
+ Documentation.initOnKeyListeners();
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS: {},
+ PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
+ LOCALE: "unknown",
+
+ // gettext and ngettext don't access this so that the functions
+ // can safely bound to a different name (_ = Documentation.gettext)
+ gettext: (string) => {
+ const translated = Documentation.TRANSLATIONS[string];
+ switch (typeof translated) {
+ case "undefined":
+ return string; // no translation
+ case "string":
+ return translated; // translation exists
+ default:
+ return translated[0]; // (singular, plural) translation tuple exists
+ }
+ },
+
+ ngettext: (singular, plural, n) => {
+ const translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated !== "undefined")
+ return translated[Documentation.PLURAL_EXPR(n)];
+ return n === 1 ? singular : plural;
+ },
+
+ addTranslations: (catalog) => {
+ Object.assign(Documentation.TRANSLATIONS, catalog.messages);
+ Documentation.PLURAL_EXPR = new Function(
+ "n",
+ `return (${catalog.plural_expr})`
+ );
+ Documentation.LOCALE = catalog.locale;
+ },
+
+ /**
+ * helper function to focus on search bar
+ */
+ focusSearchBar: () => {
+ document.querySelectorAll("input[name=q]")[0]?.focus();
+ },
+
+ /**
+ * Initialise the domain index toggle buttons
+ */
+ initDomainIndexTable: () => {
+ const toggler = (el) => {
+ const idNumber = el.id.substr(7);
+ const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
+ if (el.src.substr(-9) === "minus.png") {
+ el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
+ toggledRows.forEach((el) => (el.style.display = "none"));
+ } else {
+ el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
+ toggledRows.forEach((el) => (el.style.display = ""));
+ }
+ };
+
+ const togglerElements = document.querySelectorAll("img.toggler");
+ togglerElements.forEach((el) =>
+ el.addEventListener("click", (event) => toggler(event.currentTarget))
+ );
+ togglerElements.forEach((el) => (el.style.display = ""));
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
+ },
+
+ initOnKeyListeners: () => {
+ // only install a listener if it is really needed
+ if (
+ !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
+ !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
+ )
+ return;
+
+ document.addEventListener("keydown", (event) => {
+ // bail for input elements
+ if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+ // bail with special keys
+ if (event.altKey || event.ctrlKey || event.metaKey) return;
+
+ if (!event.shiftKey) {
+ switch (event.key) {
+ case "ArrowLeft":
+ if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
+
+ const prevLink = document.querySelector('link[rel="prev"]');
+ if (prevLink && prevLink.href) {
+ window.location.href = prevLink.href;
+ event.preventDefault();
+ }
+ break;
+ case "ArrowRight":
+ if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
+
+ const nextLink = document.querySelector('link[rel="next"]');
+ if (nextLink && nextLink.href) {
+ window.location.href = nextLink.href;
+ event.preventDefault();
+ }
+ break;
+ }
+ }
+
+ // some keyboard layouts may need Shift to get /
+ switch (event.key) {
+ case "/":
+ if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
+ Documentation.focusSearchBar();
+ event.preventDefault();
+ }
+ });
+ },
+};
+
+// quick alias for translations
+const _ = Documentation.gettext;
+
+_ready(Documentation.init);
diff --git a/2022-new-headings-intros/_static/documentation_options.js b/2022-new-headings-intros/_static/documentation_options.js
new file mode 100644
index 0000000..b57ae3b
--- /dev/null
+++ b/2022-new-headings-intros/_static/documentation_options.js
@@ -0,0 +1,14 @@
+var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+ VERSION: '',
+ LANGUAGE: 'en',
+ COLLAPSE_INDEX: false,
+ BUILDER: 'html',
+ FILE_SUFFIX: '.html',
+ LINK_SUFFIX: '.html',
+ HAS_SOURCE: true,
+ SOURCELINK_SUFFIX: '.txt',
+ NAVIGATION_WITH_KEYS: false,
+ SHOW_SEARCH_SUMMARY: true,
+ ENABLE_SEARCH_SHORTCUTS: true,
+};
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/favicon.png b/2022-new-headings-intros/_static/favicon.png
new file mode 100644
index 0000000..d7b5d1e
Binary files /dev/null and b/2022-new-headings-intros/_static/favicon.png differ
diff --git a/2022-new-headings-intros/_static/file.png b/2022-new-headings-intros/_static/file.png
new file mode 100644
index 0000000..a858a41
Binary files /dev/null and b/2022-new-headings-intros/_static/file.png differ
diff --git a/2022-new-headings-intros/_static/jquery.js b/2022-new-headings-intros/_static/jquery.js
new file mode 100644
index 0000000..c4c6022
--- /dev/null
+++ b/2022-new-headings-intros/_static/jquery.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML=" ",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML=" ";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML=" ",y.option=!!ce.lastChild;var ge={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML=" ",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/js/html5shiv.min.js b/2022-new-headings-intros/_static/js/html5shiv.min.js
new file mode 100644
index 0000000..cd1c674
--- /dev/null
+++ b/2022-new-headings-intros/_static/js/html5shiv.min.js
@@ -0,0 +1,4 @@
+/**
+* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+*/
+!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML=" ",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/js/theme.js b/2022-new-headings-intros/_static/js/theme.js
new file mode 100644
index 0000000..1fddb6e
--- /dev/null
+++ b/2022-new-headings-intros/_static/js/theme.js
@@ -0,0 +1 @@
+!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap(""),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(' '),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
+ }
+}
+
diff --git a/2022-new-headings-intros/_static/minus.png b/2022-new-headings-intros/_static/minus.png
new file mode 100644
index 0000000..d96755f
Binary files /dev/null and b/2022-new-headings-intros/_static/minus.png differ
diff --git a/2022-new-headings-intros/_static/plus.png b/2022-new-headings-intros/_static/plus.png
new file mode 100644
index 0000000..7107cec
Binary files /dev/null and b/2022-new-headings-intros/_static/plus.png differ
diff --git a/2022-new-headings-intros/_static/pygments.css b/2022-new-headings-intros/_static/pygments.css
new file mode 100644
index 0000000..84ab303
--- /dev/null
+++ b/2022-new-headings-intros/_static/pygments.css
@@ -0,0 +1,75 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #f8f8f8; }
+.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #008000; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #9C6500 } /* Comment.Preproc */
+.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+.highlight .gr { color: #E40000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #008400 } /* Generic.Inserted */
+.highlight .go { color: #717171 } /* Generic.Output */
+.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #008000 } /* Keyword.Pseudo */
+.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #B00040 } /* Keyword.Type */
+.highlight .m { color: #666666 } /* Literal.Number */
+.highlight .s { color: #BA2121 } /* Literal.String */
+.highlight .na { color: #687822 } /* Name.Attribute */
+.highlight .nb { color: #008000 } /* Name.Builtin */
+.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.highlight .no { color: #880000 } /* Name.Constant */
+.highlight .nd { color: #AA22FF } /* Name.Decorator */
+.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #0000FF } /* Name.Function */
+.highlight .nl { color: #767600 } /* Name.Label */
+.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #19177C } /* Name.Variable */
+.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mb { color: #666666 } /* Literal.Number.Bin */
+.highlight .mf { color: #666666 } /* Literal.Number.Float */
+.highlight .mh { color: #666666 } /* Literal.Number.Hex */
+.highlight .mi { color: #666666 } /* Literal.Number.Integer */
+.highlight .mo { color: #666666 } /* Literal.Number.Oct */
+.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
+.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
+.highlight .sc { color: #BA2121 } /* Literal.String.Char */
+.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
+.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
+.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
+.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
+.highlight .sx { color: #008000 } /* Literal.String.Other */
+.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
+.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
+.highlight .ss { color: #19177C } /* Literal.String.Symbol */
+.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #0000FF } /* Name.Function.Magic */
+.highlight .vc { color: #19177C } /* Name.Variable.Class */
+.highlight .vg { color: #19177C } /* Name.Variable.Global */
+.highlight .vi { color: #19177C } /* Name.Variable.Instance */
+.highlight .vm { color: #19177C } /* Name.Variable.Magic */
+.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/2022-new-headings-intros/_static/searchtools.js b/2022-new-headings-intros/_static/searchtools.js
new file mode 100644
index 0000000..97d56a7
--- /dev/null
+++ b/2022-new-headings-intros/_static/searchtools.js
@@ -0,0 +1,566 @@
+/*
+ * searchtools.js
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for the full-text search.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+"use strict";
+
+/**
+ * Simple result scoring code.
+ */
+if (typeof Scorer === "undefined") {
+ var Scorer = {
+ // Implement the following function to further tweak the score for each result
+ // The function takes a result array [docname, title, anchor, descr, score, filename]
+ // and returns the new score.
+ /*
+ score: result => {
+ const [docname, title, anchor, descr, score, filename] = result
+ return score
+ },
+ */
+
+ // query matches the full name of an object
+ objNameMatch: 11,
+ // or matches in the last dotted part of the object name
+ objPartialMatch: 6,
+ // Additive scores depending on the priority of the object
+ objPrio: {
+ 0: 15, // used to be importantResults
+ 1: 5, // used to be objectResults
+ 2: -5, // used to be unimportantResults
+ },
+ // Used when the priority is not in the mapping.
+ objPrioDefault: 0,
+
+ // query found in title
+ title: 15,
+ partialTitle: 7,
+ // query found in terms
+ term: 5,
+ partialTerm: 2,
+ };
+}
+
+const _removeChildren = (element) => {
+ while (element && element.lastChild) element.removeChild(element.lastChild);
+};
+
+/**
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
+ */
+const _escapeRegExp = (string) =>
+ string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+
+const _displayItem = (item, searchTerms) => {
+ const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
+ const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
+ const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
+ const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
+ const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
+
+ const [docName, title, anchor, descr, score, _filename] = item;
+
+ let listItem = document.createElement("li");
+ let requestUrl;
+ let linkUrl;
+ if (docBuilder === "dirhtml") {
+ // dirhtml builder
+ let dirname = docName + "/";
+ if (dirname.match(/\/index\/$/))
+ dirname = dirname.substring(0, dirname.length - 6);
+ else if (dirname === "index/") dirname = "";
+ requestUrl = docUrlRoot + dirname;
+ linkUrl = requestUrl;
+ } else {
+ // normal html builders
+ requestUrl = docUrlRoot + docName + docFileSuffix;
+ linkUrl = docName + docLinkSuffix;
+ }
+ let linkEl = listItem.appendChild(document.createElement("a"));
+ linkEl.href = linkUrl + anchor;
+ linkEl.dataset.score = score;
+ linkEl.innerHTML = title;
+ if (descr)
+ listItem.appendChild(document.createElement("span")).innerHTML =
+ " (" + descr + ")";
+ else if (showSearchSummary)
+ fetch(requestUrl)
+ .then((responseData) => responseData.text())
+ .then((data) => {
+ if (data)
+ listItem.appendChild(
+ Search.makeSearchSummary(data, searchTerms)
+ );
+ });
+ Search.output.appendChild(listItem);
+};
+const _finishSearch = (resultCount) => {
+ Search.stopPulse();
+ Search.title.innerText = _("Search Results");
+ if (!resultCount)
+ Search.status.innerText = Documentation.gettext(
+ "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
+ );
+ else
+ Search.status.innerText = _(
+ `Search finished, found ${resultCount} page(s) matching the search query.`
+ );
+};
+const _displayNextItem = (
+ results,
+ resultCount,
+ searchTerms
+) => {
+ // results left, load the summary and display it
+ // this is intended to be dynamic (don't sub resultsCount)
+ if (results.length) {
+ _displayItem(results.pop(), searchTerms);
+ setTimeout(
+ () => _displayNextItem(results, resultCount, searchTerms),
+ 5
+ );
+ }
+ // search finished, update title and status message
+ else _finishSearch(resultCount);
+};
+
+/**
+ * Default splitQuery function. Can be overridden in ``sphinx.search`` with a
+ * custom function per language.
+ *
+ * The regular expression works by splitting the string on consecutive characters
+ * that are not Unicode letters, numbers, underscores, or emoji characters.
+ * This is the same as ``\W+`` in Python, preserving the surrogate pair area.
+ */
+if (typeof splitQuery === "undefined") {
+ var splitQuery = (query) => query
+ .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
+ .filter(term => term) // remove remaining empty strings
+}
+
+/**
+ * Search Module
+ */
+const Search = {
+ _index: null,
+ _queued_query: null,
+ _pulse_status: -1,
+
+ htmlToText: (htmlString) => {
+ const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
+ htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
+ const docContent = htmlElement.querySelector('[role="main"]');
+ if (docContent !== undefined) return docContent.textContent;
+ console.warn(
+ "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
+ );
+ return "";
+ },
+
+ init: () => {
+ const query = new URLSearchParams(window.location.search).get("q");
+ document
+ .querySelectorAll('input[name="q"]')
+ .forEach((el) => (el.value = query));
+ if (query) Search.performSearch(query);
+ },
+
+ loadIndex: (url) =>
+ (document.body.appendChild(document.createElement("script")).src = url),
+
+ setIndex: (index) => {
+ Search._index = index;
+ if (Search._queued_query !== null) {
+ const query = Search._queued_query;
+ Search._queued_query = null;
+ Search.query(query);
+ }
+ },
+
+ hasIndex: () => Search._index !== null,
+
+ deferQuery: (query) => (Search._queued_query = query),
+
+ stopPulse: () => (Search._pulse_status = -1),
+
+ startPulse: () => {
+ if (Search._pulse_status >= 0) return;
+
+ const pulse = () => {
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ Search.dots.innerText = ".".repeat(Search._pulse_status);
+ if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
+ };
+ pulse();
+ },
+
+ /**
+ * perform a search for something (or wait until index is loaded)
+ */
+ performSearch: (query) => {
+ // create the required interface elements
+ const searchText = document.createElement("h2");
+ searchText.textContent = _("Searching");
+ const searchSummary = document.createElement("p");
+ searchSummary.classList.add("search-summary");
+ searchSummary.innerText = "";
+ const searchList = document.createElement("ul");
+ searchList.classList.add("search");
+
+ const out = document.getElementById("search-results");
+ Search.title = out.appendChild(searchText);
+ Search.dots = Search.title.appendChild(document.createElement("span"));
+ Search.status = out.appendChild(searchSummary);
+ Search.output = out.appendChild(searchList);
+
+ const searchProgress = document.getElementById("search-progress");
+ // Some themes don't use the search progress node
+ if (searchProgress) {
+ searchProgress.innerText = _("Preparing search...");
+ }
+ Search.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (Search.hasIndex()) Search.query(query);
+ else Search.deferQuery(query);
+ },
+
+ /**
+ * execute search (requires search index to be loaded)
+ */
+ query: (query) => {
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const titles = Search._index.titles;
+ const allTitles = Search._index.alltitles;
+ const indexEntries = Search._index.indexentries;
+
+ // stem the search terms and add them to the correct list
+ const stemmer = new Stemmer();
+ const searchTerms = new Set();
+ const excludedTerms = new Set();
+ const highlightTerms = new Set();
+ const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
+ splitQuery(query.trim()).forEach((queryTerm) => {
+ const queryTermLower = queryTerm.toLowerCase();
+
+ // maybe skip this "word"
+ // stopwords array is from language_data.js
+ if (
+ stopwords.indexOf(queryTermLower) !== -1 ||
+ queryTerm.match(/^\d+$/)
+ )
+ return;
+
+ // stem the word
+ let word = stemmer.stemWord(queryTermLower);
+ // select the correct list
+ if (word[0] === "-") excludedTerms.add(word.substr(1));
+ else {
+ searchTerms.add(word);
+ highlightTerms.add(queryTermLower);
+ }
+ });
+
+ if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
+ localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
+ }
+
+ // console.debug("SEARCH: searching for:");
+ // console.info("required: ", [...searchTerms]);
+ // console.info("excluded: ", [...excludedTerms]);
+
+ // array of [docname, title, anchor, descr, score, filename]
+ let results = [];
+ _removeChildren(document.getElementById("search-progress"));
+
+ const queryLower = query.toLowerCase();
+ for (const [title, foundTitles] of Object.entries(allTitles)) {
+ if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
+ for (const [file, id] of foundTitles) {
+ let score = Math.round(100 * queryLower.length / title.length)
+ results.push([
+ docNames[file],
+ titles[file] !== title ? `${titles[file]} > ${title}` : title,
+ id !== null ? "#" + id : "",
+ null,
+ score,
+ filenames[file],
+ ]);
+ }
+ }
+ }
+
+ // search for explicit entries in index directives
+ for (const [entry, foundEntries] of Object.entries(indexEntries)) {
+ if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
+ for (const [file, id] of foundEntries) {
+ let score = Math.round(100 * queryLower.length / entry.length)
+ results.push([
+ docNames[file],
+ titles[file],
+ id ? "#" + id : "",
+ null,
+ score,
+ filenames[file],
+ ]);
+ }
+ }
+ }
+
+ // lookup as object
+ objectTerms.forEach((term) =>
+ results.push(...Search.performObjectSearch(term, objectTerms))
+ );
+
+ // lookup as search terms in fulltext
+ results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
+
+ // let the scorer override scores with a custom scoring function
+ if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
+
+ // now sort the results by score (in opposite order of appearance, since the
+ // display function below uses pop() to retrieve items) and then
+ // alphabetically
+ results.sort((a, b) => {
+ const leftScore = a[4];
+ const rightScore = b[4];
+ if (leftScore === rightScore) {
+ // same score: sort alphabetically
+ const leftTitle = a[1].toLowerCase();
+ const rightTitle = b[1].toLowerCase();
+ if (leftTitle === rightTitle) return 0;
+ return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
+ }
+ return leftScore > rightScore ? 1 : -1;
+ });
+
+ // remove duplicate search results
+ // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
+ let seen = new Set();
+ results = results.reverse().reduce((acc, result) => {
+ let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
+ if (!seen.has(resultStr)) {
+ acc.push(result);
+ seen.add(resultStr);
+ }
+ return acc;
+ }, []);
+
+ results = results.reverse();
+
+ // for debugging
+ //Search.lastresults = results.slice(); // a copy
+ // console.info("search results:", Search.lastresults);
+
+ // print the results
+ _displayNextItem(results, results.length, searchTerms);
+ },
+
+ /**
+ * search for object names
+ */
+ performObjectSearch: (object, objectTerms) => {
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const objects = Search._index.objects;
+ const objNames = Search._index.objnames;
+ const titles = Search._index.titles;
+
+ const results = [];
+
+ const objectSearchCallback = (prefix, match) => {
+ const name = match[4]
+ const fullname = (prefix ? prefix + "." : "") + name;
+ const fullnameLower = fullname.toLowerCase();
+ if (fullnameLower.indexOf(object) < 0) return;
+
+ let score = 0;
+ const parts = fullnameLower.split(".");
+
+ // check for different match types: exact matches of full name or
+ // "last name" (i.e. last dotted part)
+ if (fullnameLower === object || parts.slice(-1)[0] === object)
+ score += Scorer.objNameMatch;
+ else if (parts.slice(-1)[0].indexOf(object) > -1)
+ score += Scorer.objPartialMatch; // matches in last name
+
+ const objName = objNames[match[1]][2];
+ const title = titles[match[0]];
+
+ // If more than one term searched for, we require other words to be
+ // found in the name/title/description
+ const otherTerms = new Set(objectTerms);
+ otherTerms.delete(object);
+ if (otherTerms.size > 0) {
+ const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
+ if (
+ [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
+ )
+ return;
+ }
+
+ let anchor = match[3];
+ if (anchor === "") anchor = fullname;
+ else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
+
+ const descr = objName + _(", in ") + title;
+
+ // add custom score for some objects according to scorer
+ if (Scorer.objPrio.hasOwnProperty(match[2]))
+ score += Scorer.objPrio[match[2]];
+ else score += Scorer.objPrioDefault;
+
+ results.push([
+ docNames[match[0]],
+ fullname,
+ "#" + anchor,
+ descr,
+ score,
+ filenames[match[0]],
+ ]);
+ };
+ Object.keys(objects).forEach((prefix) =>
+ objects[prefix].forEach((array) =>
+ objectSearchCallback(prefix, array)
+ )
+ );
+ return results;
+ },
+
+ /**
+ * search for full-text terms in the index
+ */
+ performTermsSearch: (searchTerms, excludedTerms) => {
+ // prepare search
+ const terms = Search._index.terms;
+ const titleTerms = Search._index.titleterms;
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const titles = Search._index.titles;
+
+ const scoreMap = new Map();
+ const fileMap = new Map();
+
+ // perform the search on the required terms
+ searchTerms.forEach((word) => {
+ const files = [];
+ const arr = [
+ { files: terms[word], score: Scorer.term },
+ { files: titleTerms[word], score: Scorer.title },
+ ];
+ // add support for partial matches
+ if (word.length > 2) {
+ const escapedWord = _escapeRegExp(word);
+ Object.keys(terms).forEach((term) => {
+ if (term.match(escapedWord) && !terms[word])
+ arr.push({ files: terms[term], score: Scorer.partialTerm });
+ });
+ Object.keys(titleTerms).forEach((term) => {
+ if (term.match(escapedWord) && !titleTerms[word])
+ arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
+ });
+ }
+
+ // no match but word was a required one
+ if (arr.every((record) => record.files === undefined)) return;
+
+ // found search word in contents
+ arr.forEach((record) => {
+ if (record.files === undefined) return;
+
+ let recordFiles = record.files;
+ if (recordFiles.length === undefined) recordFiles = [recordFiles];
+ files.push(...recordFiles);
+
+ // set score for the word in each file
+ recordFiles.forEach((file) => {
+ if (!scoreMap.has(file)) scoreMap.set(file, {});
+ scoreMap.get(file)[word] = record.score;
+ });
+ });
+
+ // create the mapping
+ files.forEach((file) => {
+ if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
+ fileMap.get(file).push(word);
+ else fileMap.set(file, [word]);
+ });
+ });
+
+ // now check if the files don't contain excluded terms
+ const results = [];
+ for (const [file, wordList] of fileMap) {
+ // check if all requirements are matched
+
+ // as search terms with length < 3 are discarded
+ const filteredTermCount = [...searchTerms].filter(
+ (term) => term.length > 2
+ ).length;
+ if (
+ wordList.length !== searchTerms.size &&
+ wordList.length !== filteredTermCount
+ )
+ continue;
+
+ // ensure that none of the excluded terms is in the search result
+ if (
+ [...excludedTerms].some(
+ (term) =>
+ terms[term] === file ||
+ titleTerms[term] === file ||
+ (terms[term] || []).includes(file) ||
+ (titleTerms[term] || []).includes(file)
+ )
+ )
+ break;
+
+ // select one (max) score for the file.
+ const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
+ // add result to the result list
+ results.push([
+ docNames[file],
+ titles[file],
+ "",
+ null,
+ score,
+ filenames[file],
+ ]);
+ }
+ return results;
+ },
+
+ /**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words.
+ */
+ makeSearchSummary: (htmlText, keywords) => {
+ const text = Search.htmlToText(htmlText);
+ if (text === "") return null;
+
+ const textLower = text.toLowerCase();
+ const actualStartPosition = [...keywords]
+ .map((k) => textLower.indexOf(k.toLowerCase()))
+ .filter((i) => i > -1)
+ .slice(-1)[0];
+ const startWithContext = Math.max(actualStartPosition - 120, 0);
+
+ const top = startWithContext === 0 ? "" : "...";
+ const tail = startWithContext + 240 < text.length ? "..." : "";
+
+ let summary = document.createElement("p");
+ summary.classList.add("context");
+ summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
+
+ return summary;
+ },
+};
+
+_ready(Search.init);
diff --git a/2022-new-headings-intros/_static/sphinx_highlight.js b/2022-new-headings-intros/_static/sphinx_highlight.js
new file mode 100644
index 0000000..aae669d
--- /dev/null
+++ b/2022-new-headings-intros/_static/sphinx_highlight.js
@@ -0,0 +1,144 @@
+/* Highlighting utilities for Sphinx HTML documentation. */
+"use strict";
+
+const SPHINX_HIGHLIGHT_ENABLED = true
+
+/**
+ * highlight a given string on a node by wrapping it in
+ * span elements with the given class name.
+ */
+const _highlight = (node, addItems, text, className) => {
+ if (node.nodeType === Node.TEXT_NODE) {
+ const val = node.nodeValue;
+ const parent = node.parentNode;
+ const pos = val.toLowerCase().indexOf(text);
+ if (
+ pos >= 0 &&
+ !parent.classList.contains(className) &&
+ !parent.classList.contains("nohighlight")
+ ) {
+ let span;
+
+ const closestNode = parent.closest("body, svg, foreignObject");
+ const isInSVG = closestNode && closestNode.matches("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.classList.add(className);
+ }
+
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ parent.insertBefore(
+ span,
+ parent.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling
+ )
+ );
+ node.nodeValue = val.substr(0, pos);
+
+ if (isInSVG) {
+ const rect = document.createElementNS(
+ "http://www.w3.org/2000/svg",
+ "rect"
+ );
+ const bbox = parent.getBBox();
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute("class", className);
+ addItems.push({ parent: parent, target: rect });
+ }
+ }
+ } else if (node.matches && !node.matches("button, select, textarea")) {
+ node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
+ }
+};
+const _highlightText = (thisNode, text, className) => {
+ let addItems = [];
+ _highlight(thisNode, addItems, text, className);
+ addItems.forEach((obj) =>
+ obj.parent.insertAdjacentElement("beforebegin", obj.target)
+ );
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const SphinxHighlight = {
+
+ /**
+ * highlight the search words provided in localstorage in the text
+ */
+ highlightSearchWords: () => {
+ if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
+
+ // get and clear terms from localstorage
+ const url = new URL(window.location);
+ const highlight =
+ localStorage.getItem("sphinx_highlight_terms")
+ || url.searchParams.get("highlight")
+ || "";
+ localStorage.removeItem("sphinx_highlight_terms")
+ url.searchParams.delete("highlight");
+ window.history.replaceState({}, "", url);
+
+ // get individual terms from highlight string
+ const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
+ if (terms.length === 0) return; // nothing to do
+
+ // There should never be more than one element matching "div.body"
+ const divBody = document.querySelectorAll("div.body");
+ const body = divBody.length ? divBody[0] : document.querySelector("body");
+ window.setTimeout(() => {
+ terms.forEach((term) => _highlightText(body, term, "highlighted"));
+ }, 10);
+
+ const searchBox = document.getElementById("searchbox");
+ if (searchBox === null) return;
+ searchBox.appendChild(
+ document
+ .createRange()
+ .createContextualFragment(
+ '' +
+ '' +
+ _("Hide Search Matches") +
+ "
"
+ )
+ );
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords: () => {
+ document
+ .querySelectorAll("#searchbox .highlight-link")
+ .forEach((el) => el.remove());
+ document
+ .querySelectorAll("span.highlighted")
+ .forEach((el) => el.classList.remove("highlighted"));
+ localStorage.removeItem("sphinx_highlight_terms")
+ },
+
+ initEscapeListener: () => {
+ // only install a listener if it is really needed
+ if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
+
+ document.addEventListener("keydown", (event) => {
+ // bail for input elements
+ if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+ // bail with special keys
+ if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
+ if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
+ SphinxHighlight.hideSearchWords();
+ event.preventDefault();
+ }
+ });
+ },
+};
+
+_ready(SphinxHighlight.highlightSearchWords);
+_ready(SphinxHighlight.initEscapeListener);
diff --git a/2022-new-headings-intros/genindex.html b/2022-new-headings-intros/genindex.html
new file mode 100644
index 0000000..5eeb8f3
--- /dev/null
+++ b/2022-new-headings-intros/genindex.html
@@ -0,0 +1,306 @@
+
+
+
+
+
+ Index — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+
Index
+
+
+
_
+ |
B
+ |
C
+ |
E
+ |
G
+ |
I
+ |
K
+ |
L
+ |
O
+ |
S
+
+
+
_
+
+
+
B
+
+
+
+ built-in function
+
+
+
+
+
+
+
C
+
+
+
E
+
+
+
G
+
+
+
+ gom.api.imaging.compute_epipolar_line()
+
+
+
+ gom.api.imaging.compute_pixels_from_point()
+
+
+
+ gom.api.imaging.compute_point_from_pixels()
+
+
+
+ gom.api.project.get_image_aquisition()
+
+
+
+
+
+ gom.api.scripted_checks_util.is_curve_checkable()
+
+
+
+ gom.api.scripted_checks_util.is_scalar_checkable()
+
+
+
+ gom.api.scripted_checks_util.is_surface_checkable()
+
+
+ gom.Resource (built-in class)
+
+
+
+
+
I
+
+
+
K
+
+
+
L
+
+
+
O
+
+
+
S
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.html b/2022-new-headings-intros/howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.html
new file mode 100644
index 0000000..620da31
--- /dev/null
+++ b/2022-new-headings-intros/howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.html
@@ -0,0 +1,457 @@
+
+
+
+
+
+
+ Adding workspaces to add-ons — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Adding workspaces to add-ons
+
+Abstract: An add-on can include a definition for a new workspace. ‘Inspection’ and ‘Reporting’ are examples for these workspaces. Although there is not UI based workspace editor yet, it is possible to create one nevertheless with some manual work.
+
+
+Workspaces
+
+
+Each GOM application does have a list of available workspace on the left side (1).
+Which workspaces are available depends on the available licenses and the installed add-ons.
+A workspace bundles commands etc. thematically. If, for example, the ‘inspection’ workspace is selected, the toolbar (2) and the view menu (3) above will show everything the user needs to inspect parts, while the ‘report’ workspace provides tool for report page creation.
+An add-on can add its own workspace. The ‘Blade CMM’ add-on, for example will provide tools for ‘Airfoil CMM data preparation’ - a feature, which is packaged and not provided by default because it is rather special.
+
+
+
+Adding workspaces to add-ons
+
+There is no UI based workspace editor yet, but workspace definitions can be added manually.
+
+
+An add-on is just a ZIP file with a different extension (.package) containing JSON based object definitions.
+It can be unpacked, edited and packaged again with a new workspace definition.
+
+
+Step 1: Unpack the add-on
+
+Use the tool of your choice to unpack the add-on file.
+We recommend 7-zip for that task, but every other zip tool will do the job, too.
+If you want to perform these tasks often, you can register your ZIP tool in the Windows “Choose default apps by file type” settings. Then, instead of unpacking and packing the add-on again for each edit, you can fiddle with the add-on content directly from the ZIP tool:
+
+
+
+
+
+Step 2: Edit the main package content file
+
+The file package.json contains a listing of the add-on content
+
+
+When editing the package.json file in an add-on, you will notice that all general add-on information is handled there.
+Among data like name and description, the package.json file contains a list of “content objects”.
+Every content object in the package.json file
+
+
+In the example, the “Blade CMM” add-on adds a workspace
+
+named “Airfoil CMM Data Preparation”
+which exact definition is provided in the add-on file object_0.json
+among other content like ‘import_templates’ and ‘scripts’.
+
+
+
+Example: package.json
+{
+ "author" : "Carl Zeiss GOM Metrology GmbH" ,
+ "description" : "System package 'Airfoil CMM Data Preparation'" ,
+ "uuid" : "cab03223-c3ca-4001-af23-23f6d07471cb" ,
+ ...
+ "content" : [
+ {
+ "displayname" : "Airfoil CMM Data Preparation" ,
+ "object" : "object_0.json" ,
+ "provider_id" : "workspace" ,
+ "resources" : [],
+ "content_id" : "711632f6-7444-4e66-bf21-00cdd153d535"
+ },
+ {
+ "displayname" : "import_cmm_xml.py" ,
+ "object" : "object_1.json" ,
+ "provider_id" : "import_templates" ,
+ "resources" : []
+ },
+ {
+ "displayname" : "Blade CMM" ,
+ "object" : "object_2.json" ,
+ "provider_id" : "scripts" ,
+ "resources" : [],
+ "content_id" : ":cab03223-c3ca-4001-af23-23f6d07471cb.Blade_CMM"
+ }
+ ],
+...
+}
+
+
+
+
+
+Step 3: Add a workspace definition file
+
+The object_xxx.json file contains the complete workspace definition
+
+
+Example: ‘object_0.json’ from the ‘Blade CMM’ add-on defining a workspace for airfoil CMM data preparation:
+{
+ "name" : "Airfoil CMM Data Preparation" ,
+ "uuid" : "711632f6-7444-4e66-bf21-00cdd153d535" ,
+ "content" : {
+ "color" : [
+ 170 ,
+ 93 ,
+ 30
+ ],
+ "recalc_section" : true ,
+ "alignment_section" : true ,
+ "sort_index" : "19" ,
+ "icon" : "cmd_mode_eval_blade_cmm" ,
+ "workflow_commands" : [
+ "sys.import_file" ,
+ "[separator]" ,
+ "userscript.Blade_CMM__ProjectSetup__Project_Setup" ,
+ "inspect.tb_create_blade_stylus_correction_cmd_group" ,
+ "primitive.create_fitting_plane_mp_none_draft" ,
+ "inspect.tb_create_profile_section_by_projection_cmd_group" ,
+ "[separator]" ,
+ "userscript.Blade_CMM__AutoPilot__AutoPilot"
+ ],
+ "default_visible_tabs" : [
+ "diagram" ,
+ "section_view" ,
+ "table" ,
+ "pip"
+ ]
+ }
+}
+
+
+
+“name”
+Workspace name as displayed in the workspaces tooltip.
+
+
+“uuid”
+A unique id which matches the “content id” field in the packages.json file.
+
+Please do not define the UUID manually, but use a UUID generator like Online UUID Generator to generate a fresh, truly unique one !
+
+
+
+“color”
+RGB color of the workspace toolbar background. This default may be overwritten by themes, so e.g. in dark theme the toolbar will be colored in rgb(51,51,51) always.
+
+
+“recalc_section”
+True, if the toolbar should contain a section for recalculation commands
+
+
+“alignment_section”
+True, if the toolbar should contain a section for alignment commands.
+
+
+“sort_index”
+Position of that workspace in the list of workspace. The default (no value given) will add the workspace to the end of the workspace list, which is often fine.
+
+
+“icon”
+The internal name of the icon file.
+
+It is currently possible only to select icons which are part of the GOM software distribution and which are not listed anywhere for the outside world. So this important field is of limited use now. But we will add a method to add custom icons just into that particular content definition file in the near future !
+
+In SW2022-0 and later only:
+
+Choose an icon file in one of the widely supported formats (png, jpg, …). We are using the Qt library functions to read image data, so you can have a look at the related Qt documentation to see the list of supported image formats.
+Install add-on Workspace editor tools and use the script in Scripting / Tools / Workspace editor to create a base64 encoded file of this icons data:
+
+
+Insert the resulting file content as a text item into the icon property:
+
+{
+ "name" : "Airfoil CMM Data Preparation" ,
+ "uuid" : "711632f6-7444-4e66-bf21-00cdd153d535" ,
+ "content" : {
+ ...
+ # The icon definition contains the content of the created encoding as string enclosed in '"'
+ "icon" : "x8Royf4mIiJq8v3YBiIj6IRvW1yr6DhnwUw45R0RErxcr+kREALZDBZvXLgYREdGZHBx1h4iIiIiI..." ,
+ ...
+}
+
+
+Some icon guidelines
+
+Use only black/white icons to match with the overall application style
+
+Black color: HEX (#333333), RGB (51,51,51)
+White color: HEX (#FFFFFF), RGB (255,255,255)
+
+
+Use image formats that support transparency (e.g. ‘.png’)
+Image size:
+
+preferably from 24x24 px (minimum, for script icons) to 64x64 px (recommended for workspace icons)
+Try NOT to use any form of compression
+
+
+Set the workspace (and scripts) icons to look good on a bright background
+
+Normally, this means just a black icon with transparent background
+To look good on darker background you have two options:
+
+You put a bright (white) padding around the icon, so it is still visible on dark backgrounds
+You let the software automatically invert the icon to white color. The icons will get autobrightened, if the icon contains ONLY the standard black color (see above), and no bright colors (Lightness > 127)
+
+
+
+
+Example
+
+
+(1) = Icon with padding, stays the same in all modes
+(2) = Icon in pure #333333 black, gets auto-brightened in dark modes
+
+
+
+
+
+“workflow_commands”
+Commands on the left side of the workspace toolbar. These command can either be
+
+the name of a “hardcoded” GOM command,
+the name of a script command (a command starting a python script)
+a special tag like ‘[separator]’ for a separator in the command toolbar.
+
+The command here will become entries in the toolbar from the left to the right. To get the name of the command, you can record it in the script editor and skip the ‘gom.script’ prefix:
+
+This works for scripts, too, if a script is executed from the ‘Scripts’ menu while the script editor is in recording mode.
+
+
+“sensor_commands”
+Commands on the right side of the workspace toolbar. Same principle as above.
+
+
+“default_visible_views”
+Views that are visible per default, e.g. adding “right_docking_area” shows the properties/toolbox window(star) on right side, which is collapsed by default. ( (star) as long as the default_view_layout_right_ isn’t changed). To investigate the name of the view to enter here, start script recording again and switch to that view in the applications UI. This will record a command containing that name:
+
+
+
+“default_visible_tabs”
+Views that are visible as tabs per default → these are still initially collapsed until adding them to “default_visible_views”.
+
+
+
+Step 4: Test your workspace
+
+
+
+
+Guidelines
+
+Icon guidelines
+
+SVG Format, with a page size of 16x16. E.g. Inkscape page template “Icon 16x16”
+Only use two colors:
+
+
+For proper appearance in dark themes:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/environments_for_python_scripts/environments_for_python_scripts.html b/2022-new-headings-intros/howtos/environments_for_python_scripts/environments_for_python_scripts.html
new file mode 100644
index 0000000..256ba3a
--- /dev/null
+++ b/2022-new-headings-intros/howtos/environments_for_python_scripts/environments_for_python_scripts.html
@@ -0,0 +1,281 @@
+
+
+
+
+
+
+ Environments for python scripts — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Environments for python scripts
+
+
Note
+
Script environments is available since software version 2022, revision 147326.
+
+
+
Important
+
New package with only scripts, which are not in environment, can not be created any more. Previous packages without environment can still be installed and executed, but can not be edited. If you want to export only scripts, please use “Export Script” (RMB on the script to export) or create a script environment and add the script in it.
+
+
+Creating an environment in the script editor
+
+
+
+Install / uninstall python packages
+
+Installation
+
+To install python packages to the created environment path: RMB on ①the environment folder or ②modules folder or ③modules.json file > Install Python Package
+
+
+To install python packages to the public/user local path: RMB on Public/User-defined scripts > Install Python Package or old version is also valid (old version) Menu > Scripting > Script Choice > Tools > Install Python Package
+The Installation can be done in two ways: network or local.
+
+Network
+
+The package list from network must be separated with a comma.
+To install the packages of the specific version, write the version after “==”. ex) numpy==1.22.0
+
+
+
+
+Local
+
+
+
+
+The explorer of the script editor and “modules.json” file are updated after installation.
+
+
+
+
+
+
+
+Writing and running a script in the environment
+
+
+
+Editing “modules.json” file
+
+“modules.json” file can be edited in the script editor.
+“wheelsfrom”: “local”: When creating a package that contains this environment, all wheel files of the required python packages for this environment are packaged together. When this environment being imported, required python packages are installed from the contained wheel files. Importing of this environment can be done offline.
+“wheelsfrom”: “network”: When creating a package that contains this environment, wheel files of the required python packages for this environment are NOT packaged together. When this environment being imported, required python packages are installed from network. Importing of this environment must be done online.
+
+
+
+
+
+Creating a package that contains environments
+
+Go to “Create Package” dialog.
+
+
+When creating package, now only environments can be added instead of scripts and python modules.
+More than one environment with a unique name can be packaged into a package.
+
+
+
+
+
+Editing the package that contains only script environments
+
+When editing package in the script editor, python packages can be installed and uninstalled in the environment.
+
+
+If editing is completed, the package can be saved in package manager.
+
+
+
+
+
+
+Editing the package that contains contents not in a script environment
+
+Packages that contain contents not in a script environment are called old-school packages.
+Old-school packages still exist and should be able to execute.
+Old-school packages should be updated when the script contents are modified.
+When editing old-school package in the script editor, all contents not in a script environment would be migrated automatically after a warning message.
+The python packages contained in the old-school package would be installed in the script environment automatically, too.
+
+
+Script editor
+
+
+
+Package manager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/localization/localization.html b/2022-new-headings-intros/howtos/localization/localization.html
new file mode 100644
index 0000000..0168af1
--- /dev/null
+++ b/2022-new-headings-intros/howtos/localization/localization.html
@@ -0,0 +1,328 @@
+
+
+
+
+
+
+ Localization of packages — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Localization of packages
+
+Writing translatable scripts
+
+User-defined script dialogs
+When adding a user defined script dialog to a script, since software version 2022 the resulting code is in JSON compatible format and will contain translation entries for all translatable texts automatically. The user does not have to care for these entries manually. They are kept consistently when the dialog is edited again and will lead to translation file entries (see below).
+DIALOG = gom . script . sys . create_user_defined_dialog ( dialog = {
+ "content" : [
+ [
+ {
+ "columns" : 1 ,
+ "monospace" : False ,
+ "name" : "log" ,
+ "rows" : 1 ,
+ "save_dialog_title" : {
+ "id" : "" ,
+ "text" : "Save Log File" ,
+ "translatable" : True
+ },
+ "scroll_automatically" : True ,
+ "show_save" : False ,
+ "tooltip" : {
+ "id" : "" ,
+ "text" : "" ,
+ "translatable" : True
+ },
+ ...
+ )
+
+
+
+
+Text in scripts
+Texts in script have to be tagged as translatable via using the tr ()
function. During translation file generation, these texts will be processed and later replaced at runtime with the available translations.
+ print (tr ('This text will be translated'))
+
+
+
+
+
+Translating scripts
+
+Generating translatable XLIFF files
+💡 Scripts are using standard XLIFF files to access translations in different languages.
+
+Install package ‘Internationalization’
+
+
+
+Switch package into ‘Edit’ mode
+
+
+
+Execute script ‘Update XLIFF files’
+
+
+Execute script ‘Update XLIFF files’ from package ‘Internationalization’.
+Select the package with the translations which shall be generated or updated (1)
+Set the comma separated list of language identifiers for which translation files will be generated (2)
+Check the displayed number of translated texts for plausibility (3)
+Press ‘Update’ (4) to generate translatable XLIFF files (4)
+
+
+Afterwards, the package’s XLIFF translatable files will be present in the package’s languages folder:
+
+
+
+
+
+Translate XLIFF files
+
+Export the XLIFF files via ‘Export Resource…’ on the right mouse menu.
+Translate the XLIFF files. This can be done either manually or by importing them into a translation software, possibly via a translation service provider.
+Import the XLIFF files back into the package via ‘Import Resource…’ on the right mouse menu.
+
+<ns0:xliff xmlns:ns0= "urn:oasis:names:tc:xliff:document:1.1" version= "1.1" >
+ <file original= "DL_ANALYSIS_01_curve_based.py" datatype= "py" source-language= "en" target-language= "de" >
+ <group restype= "x-gettext-domain" resname= "" >
+ <trans-unit id= "Save Log File" >
+ <source xml:space= "preserve" > Save Log File</source>
+ <target xml:space= "preserve" > Protokolldatei speichern</target>
+ </trans-unit>
+ <trans-unit id= "Curve inspection" >
+ <source xml:space= "preserve" > Curve inspection</source>
+ <target xml:space= "preserve" > Kurveninspektion</target>
+ </trans-unit>
+ <trans-unit id= "Processing..." >
+ <source xml:space= "preserve" > Processing...</source>
+ <target xml:space= "preserve" > In Bearbeitung...</target>
+ </trans-unit>
+ </group>
+ </file>
+</ns0:xliff>
+
+
+
+
+
+
+Switching package languages
+
+Enable language
+💡 The package language is the same as the globally set application language.
+
+Selecting an package/application language
+
+Select the appropriate language the the applications preferences dialog.
+
+
+If a matching XLIFF file is present in an package, the translations from this file are used automatically.
+This might require an application restart due to caching issues.
+
+
+
+
+
+FAQ
+
+Is there a shortcut for exporting/importing the XLIFF files ?
+
+If there are quite many of these files and the process has to be done regularly, the resource files can be accessed right on file system.
+Each package in ‘Edit’ mode mirrors its content into %APPDATA%/gom/<version>/gom_package_scripts/<package id>
.
+The XLIFF files can be edited right there of copies/pasted from there as long as the package remains in ‘Edit’ mode.
+
+
+
+Are the translation entries persistent when updated via the ‘Update XLIFF files’ script ?
+
+As long as the original texts (the texts in the ‘id’ attribute of the ‘trans-unit’ tag of the XLIFF files) are not changing, already translated entries are left untouched and will persist.
+This is the case when the original text in the script does not change, like the text in a dialog button or the original text in a scripts ‘tr ()’ function.
+Can this scheme be automated, for example in a build queue ?
+The ‘Update XLIFF files’ script itself is designed to be interactive.
+But: The source is available and the logic within can be used as a base to implement a customized XLIFF files updater to automatic execution.
+The goal of the scheme is to have translated XLIFF files with a name scheme as shown above in the package’s ‘language’ directory.
+
+
+
+After the application language is set, the package is not displaying the translations for that language ?
+
+You might have to restart the application after switching the application language in the preferences.
+Please double check, too, if the package supports that specific language at all.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/python_api_introduction/creating_wizard_dialogs.html b/2022-new-headings-intros/howtos/python_api_introduction/creating_wizard_dialogs.html
new file mode 100644
index 0000000..6e50ed7
--- /dev/null
+++ b/2022-new-headings-intros/howtos/python_api_introduction/creating_wizard_dialogs.html
@@ -0,0 +1,440 @@
+
+
+
+
+
+
+ Creating wizard dialogs — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Creating wizard dialogs
+
+
+What is a wizard dialog
+A wizard dialog is a sequence of steps, which guides the user through a process flow. The wizard dialog has a back button to go to the previous step, a next button to proceed with the next step and a Close button to complete the wizard dialog. The wizards layout is created through the scripting dialog editor like any other dialog and its transition logic for going through the steps is specified by a handler function.
+💡 Note that it is only possible to change the content of the wizards’ widgets in the handler function. This means particularly, that it is not possible to remove or add widgets after the definition of the wizards’ layout.
+
+
+Creating a simple wizard dialog
+The screenshots below show a wizard with three steps, which will be created in this tutorial.
+
+
+The wizard has to following properties:
+
+The wizard’s layout consists of an image widget, a text widget, an input widget and the default wizard control elements (Next , Back , Close ).
+On script startup the dialog already contains the text and image for the first instruction set.
+If the Next or Back button is pressed, the corresponding instruction text and image must be displayed.
+To avoid loading the following images from an external source (which would have to be distributed together with the script), the images are encoded in dummy dialogs and read from these sources.
+The dummy dialogs are organized in an array.
+
+Firstly, the wizard dialog and a dummy dialog for each wizard step is created. A dummy dialog holds the content of the wizards widgets for its respective step. The screenshots above show these dummy dialogs.
+#
+# create main wizard dialog:
+#
+DIALOG = gom . script . sys . create_user_defined_dialog ( dialog = { '...' })
+
+#
+# Dummy dialogs containing the images of the corresponding steps encoded in JSON
+#
+STEP_1 = gom . script . sys . create_user_defined_dialog ( dialog = { '...' })
+
+STEP_2 = gom . script . sys . create_user_defined_dialog ( dialog = { '...' })
+
+STEP_3 = gom . script . sys . create_user_defined_dialog ( dialog = { '...' })
+
+STEP_4 = gom . script . sys . create_user_defined_dialog ( dialog = { '...' })
+
+#
+# The dummy dialogs are organized in an array for a simple step transition logic
+#
+steps = [ STEP_1 , STEP_2 , STEP_3 , STEP_4 ]
+
+
+Note that the wizard dialog and the dummy dialogs have to be non-blocking dialogs. Note also, that the content of STEP_1 and DIALOG are identically. This is necessary, since the content of DIALOG will be overridden in the handler function. Let us create the handler function for managing the step transition:
+count = 0
+
+#
+# handler function for step transition
+#
+def handler_func ( widget ):
+ global count
+
+ # save input to dummy dialog:
+ steps [ count ] . noteInput . value = DIALOG . noteInput . value
+
+ #
+ # 'next' button has been pressed
+ #
+ if widget == DIALOG . control . next :
+ if count + 1 < len ( steps ):
+ count += 1
+ DIALOG . noteInput . value = steps [ count ] . noteInput . value
+ DIALOG . text . text = steps [ count ] . text . text
+ DIALOG . image . data = steps [ count ] . image . data
+
+ #
+ # 'prev' button has been pressed
+ #
+ elif widget == DIALOG . control . prev :
+ if count > 0 :
+ count -= 1
+ DIALOG . noteInput . value = steps [ count ] . noteInput . value
+ DIALOG . text . text = steps [ count ] . text . text
+ DIALOG . image . data = steps [ count ] . image . data
+
+ #
+ # Update enabled state of the dialog control elements
+ #
+ DIALOG . control . prev . enabled = count > 0
+ DIALOG . control . next . enabled = count + 1 < len ( steps )
+ DIALOG . control . close . enabled = count + 1 >= len ( steps )
+
+
+Note that noteInput
is the object name of the text entry field assigned within the scripting dialog editor.
+Finally we register the handler function to the dialog and display the wizard dialog:
+DIALOG . handler = handler_func
+RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+
+
+
+
+Changing the button text
+You can easily change the text of the Next and Back buttons:
+DIALOG . control . next . text = "randomButtonText"
+DIALOG . control . prev . text = "anotherRandomButtonText"
+
+
+
+
+Creating wizards with different layouts per step
+Despite the limitations mentioned above, you may use a different layout for each step in the wizard by using a more sophisticated step transition logic. Instead of changing the content of the displayed wizard dialog, you may display another wizard at each step. Let us go through the code necessary for doing that.
+First of all we have to define appropriate dialogs:
+DIALOG = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+STEP_2 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+STEP_3 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+STEP_4 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+
+This time, STEP_2, STEP_3 and STEP_4 won´t be simple dummy dialogs used as containers, they have to be wizard dialogs instead. Now let us define the handler function:
+steps = [ DIALOG , STEP_2 , STEP_3 , STEP_4 ]
+inputStrings = [ '' , '' , '' , '' ]
+current_step = - 1
+new_step = 0
+
+def handler_func ( widget ):
+ global current_step , new_step
+ global current_dialog
+
+ if widget == current_dialog . control . next :
+ if current_step + 1 < len ( steps ):
+ new_step = current_step + 1
+ gom . script . sys . close_user_defined_dialog ( dialog = current_dialog )
+ elif widget == current_dialog . control . prev :
+ if current_step > 0 :
+ new_step = current_step - 1
+ gom . script . sys . close_user_defined_dialog ( dialog = current_dialog )
+
+
+ current_dialog . control . prev . enabled = current_step > 0
+ current_dialog . control . next . enabled = current_step + 1 < len ( steps )
+ current_dialog . control . close . enabled = current_step + 1 >= len ( steps )
+
+
+The basic idea is to close the current dialog if the user hits the Next button to proceed to the next dialog step or the Back button to return to the previous one. The next code snippet will make it clear:
+while current_step != new_step :
+ current_step = new_step
+ current_dialog = steps [ current_step ]
+ current_dialog . handler = handler_func
+ RESULT = gom . script . sys . show_user_defined_dialog ( dialog = current_dialog )
+ inputStrings [ current_step ] = RESULT . noteInput
+
+
+The program will enter the while loop, if the the wizard step changed (or due to initialization) and launch a new dialog. As long as the user clicks Next or Back in the current dialog, the while loop won’t be left and “the” wizard will be displayed. If the user leaves the dialog through Close , the while loop will be left and “the” wizard terminates. noteInput
is the object name of the text entry field within the scripting dialog editor as before. Please note that the .value
suffix has to be omitted here.
+
+
+Final scripts
+The following scripts combine the code snippets above. The first one is the single layout wizard, the second one the multi layout wizard.
+
+Single Layout Wizard
+SingleLayoutWizard.py
+# -*- coding: utf-8 -*-
+
+# Script: SingleLayoutWizard.py
+
+import gom
+
+#
+# create main wizard dialog:
+#
+DIALOG = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+#
+# Dummy dialogs containing the images of the corresponding steps encoded in JSON
+#
+STEP_1 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+STEP_2 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+STEP_3 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+STEP_4 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+#
+# The dummy dialogs are organized in an array for a simple step transition logic
+#
+steps = [ STEP_1 , STEP_2 , STEP_3 , STEP_4 ]
+
+count = 0
+
+#
+# Registered handler function
+#
+def handler_func ( widget ):
+ global count
+
+ # save input to dummy dialog:
+ steps [ count ] . noteInput . value = DIALOG . noteInput . value
+
+ #
+ # 'next' button has been pressed
+ #
+ if widget == DIALOG . control . next :
+ if count + 1 < len ( steps ):
+ count += 1
+ DIALOG . noteInput . value = steps [ count ] . noteInput . value
+ DIALOG . text . text = steps [ count ] . text . text
+ DIALOG . image . data = steps [ count ] . image . data
+ #
+ # 'prev' button has been pressed
+ #
+ elif widget == DIALOG . control . prev :
+ if count > 0 :
+ count -= 1
+ DIALOG . noteInput . value = steps [ count ] . noteInput . value
+ DIALOG . text . text = steps [ count ] . text . text
+ DIALOG . image . data = steps [ count ] . image . data
+
+ #
+ # Update enabled state of the dialog control elements
+ #
+ DIALOG . control . prev . enabled = count > 0
+ DIALOG . control . next . enabled = count + 1 < len ( steps )
+ DIALOG . control . close . enabled = count + 1 >= len ( steps )
+
+DIALOG . handler = handler_func
+
+RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+
+# Access dialog input strings:
+print ( steps [ 0 ] . noteInput . value )
+print ( steps [ 1 ] . noteInput . value )
+print ( steps [ 2 ] . noteInput . value )
+print ( steps [ 3 ] . noteInput . value )
+
+
+
+
+Multi Layout Wizard
+MultiLayoutWizard.py
+# -*- coding: utf-8 -*-
+
+# Script: MultiLayoutWizard
+
+import gom
+
+DIALOG = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+STEP_2 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+STEP_3 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+STEP_4 = gom . script . sys . create_user_defined_dialog ( dialog = { ... Boring dialog definition ... })
+
+current_step = - 1
+new_step = 0
+steps = [ DIALOG , STEP_2 , STEP_3 , STEP_4 ]
+inputStrings = [ '' , '' , '' , '' ]
+
+def handler_func ( widget ):
+ global current_step , new_step
+ global current_dialog
+
+ if widget == current_dialog . control . next :
+ if current_step + 1 < len ( steps ):
+ new_step = current_step + 1
+ gom . script . sys . close_user_defined_dialog ( dialog = current_dialog )
+ elif widget == current_dialog . control . prev :
+ if current_step > 0 :
+ new_step = current_step - 1
+ gom . script . sys . close_user_defined_dialog ( dialog = current_dialog )
+
+
+ current_dialog . control . prev . enabled = current_step > 0
+ current_dialog . control . next . enabled = current_step + 1 < len ( steps )
+ current_dialog . control . close . enabled = current_step + 1 >= len ( steps )
+
+while current_step != new_step :
+ current_step = new_step
+ current_dialog = steps [ current_step ]
+ current_dialog . handler = handler_func
+ RESULT = gom . script . sys . show_user_defined_dialog ( dialog = current_dialog )
+ print ( RESULT . noteInput )
+ inputStrings [ current_step ] = RESULT . noteInput
+
+
+# Print out the acquired input:
+print ( inputStrings [ 0 ])
+print ( inputStrings [ 1 ])
+print ( inputStrings [ 2 ])
+print ( inputStrings [ 3 ])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/python_api_introduction/python_api_introduction.html b/2022-new-headings-intros/howtos/python_api_introduction/python_api_introduction.html
new file mode 100644
index 0000000..09a20f5
--- /dev/null
+++ b/2022-new-headings-intros/howtos/python_api_introduction/python_api_introduction.html
@@ -0,0 +1,527 @@
+
+
+
+
+
+
+ GOM Inspect Python API introduction — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+GOM Inspect Python API introduction
+Welcome to the GOM Inspect Python API introduction. This is your starting point into Add-on development for GOM Inspect. Here you find out what you can do with Add-ons, how they work and how you create them.
+See Introduction to Python Scripting if you are new to Python or the GOM Software Python interface.
+
+Creating projects
+You can create a new, empty project as follows:
+# Create a new project
+gom . script . sys . create_project ()
+
+
+
+
Note
+
💡 This way, a project in the default workflow (part-based) is created. For the legacy workflow (part-less), please refer to Legacy projects (part-less)
+
+
+
+Creating parts
+The evaluation elements are usually placed under a “part”. Accordingly, an empty part can be created as follows:
+# Creates a new part in your project with the name 'Part 1'
+PART_OBJECT = gom . script . part . create_new_part ( name = 'Part 1' )
+
+
+An existing part can be accessed via name or index in the new category:
+# Access the part object via name
+PART_OBJECT = gom . app . project . parts [ 'Part 1' ]
+
+# or via index
+PART_OBJECT = gom . app . project . parts [ 0 ]
+
+# you can access all parts via iterating over the parts attribute
+for p in gom . app . project . parts :
+ print ( p )
+
+
+
+
+Adding elements to a part
+If an actual mesh or CAD or elements are imported into a part project, different options are available. For scripting, the import is always separated into two different steps.
+
+Importing the elements into the Elements in clipboard
+Add the imported elements to a created part
+
+Example:
+gom . script . part . create_new_part ( name = 'Part 1' )
+
+# import element into 'Element in clipboard'
+gom . script . sys . import_g3d (
+ files = [ 'D:/gom_part.g3d' ],
+ import_mode = 'clipboard'
+)
+
+# Move it to a created part
+gom . script . part . add_elements_to_part (
+ delete_invisible_elements = True ,
+ elements = [ gom . app . project . clipboard . actual_elements [ 'gom_part' ]],
+ import_mode = 'new_elements' ,
+ part = gom . app . project . parts [ 'Part 1' ])
+
+
+In the same way, a CAD can be imported into a part project.
+Constructing new elements based on elements which already belong to a part are automatically added to that part.
+
+
+Accessing CAD and actual mesh
+A mesh element of a part can be accessed in the following ways:
+# This is usually the most elegant way and is recommended.
+# Replacing your mesh will keep the correct parametric if you use
+# the actual values reference (like formerly the 'Actual master' in the part-less workflow).
+PART_OBJECT = gom . app . project . parts [ 'Part 1' ]
+MESH_PROXY = gom . ActualReference ( PART_OBJECT )
+
+# If you really like to access the representing CAD Element (which is not always existing, e.g. for planning)
+# you can access this element via
+MESH_ELEMENT = gom . ActualReference ( PART_OBJECT ) . actual
+
+
+The CAD of a part can be addressed in the following ways:
+# This is usually the most elegant way and is recommended.
+# Replacing your CAD will keep the correct parametric if you use
+# the nominal values reference (like formerly the 'All CAD Group proxy' in the part-less workflow)
+PART_OBJECT = gom . app . project . parts [ 'Part 1' ]
+CAD_PROXY = gom . NominalReference ( PART_OBJECT )
+
+# If you really like to access the representing CAD Element (which is not always existing, e.g. for planning)
+# you can access this element via
+CAD_ELEMENT = gom . NominalReference ( PART_OBJECT ) . nominal
+
+
+
+
+Accessing an object’s part
+This information can be retrieved via an attribute of the object. Here is an example:
+PART_OBJECT = gom . app . project . inspection [ 'Point 1' ] . part
+
+
+
+
+Accessing all elements and alignments of a part
+One possibility is to iterate over all elements in the different categories (nominal, actual, inspection, alignments) and to check the part attribute. Usually, for most applications this can be achieved easier using an ElementSelection
(some elements are hidden and not listed, but usually you do not need access to these elements). Here is an example:
+for x in gom . ElementSelection ({ 'category' : [ 'key' , 'elements' , 'part' , gom . app . project . parts [ 'Part' ]]}):
+ print ( x )
+
+
+
+
+Accessing elements and alignments of Element in clipboard
+Also, these elements can be easily accessed via an ElementSelection
:
+for x in gom . ElementSelection ({ 'category' : [ 'key' , 'elements' , 'is_element_in_clipboard' , 'True' ]}):
+ print ( x )
+
+
+
+
+Alignments
+Alignments are still accessible via gom.app.project.alignments
(like in the legacy workflow). The same is valid for gom.app.project.nominal_elements
, gom.app.project.actual_elements
and gom.app.project.inspection
. You have to keep in mind that you will get all elements or alignments of all parts. You can use the part
token to establish to which part an alignment belongs to or you use an ElementSelection
(see examples above):
+for x in gom . ElementSelection ({ 'category' : [ 'key' , 'elements' , 'part' , gom . app . project . parts [ 'Part' ], 'explorer_category' , 'alignment' ]}):
+ print ( x )
+
+
+There is one special handling for multiple parts and scripting with the Original alignment . To distinguish these alignments for different parts, the scripting name contains the part name and is modified into:
+gom . app . project . alignments [ '<Name of the part>::Original alignment' ]
+
+
+
+
+Legacy projects (part-less)
+
+
Note
+
⚠️ You can skip this section unless you are dealing with legacy projects!
+
+As shown above, the following code creates a project in the part-based workflow, which allows to analyze multiple parts:
+# Create a project (default; part-based workflow)
+gom . script . sys . create_project ()
+
+# For compatibility, the kind of project can be stated explicitely:
+# Create a project (part-based workflow)
+gom . script . sys . create_project ( type = 2018 )
+
+
+You can still create a project in the legacy workflow, which is restricted to a single part:
+# Create a project (part-less workflow)
+# Note: This allows to analyze a single part only!
+gom . script . sys . create_project ( type = 2016 )
+
+
+Use the following code to determine the type of an existing project:
+if gom . app . project . is_part_project :
+ print ( 'Is part project: True' )
+else :
+ print ( 'Is part project: False' )
+
+
+In former projects, the CAD or the actual mesh have been accessed via their proxies:
+All CADGroup proxy
+Actual Master
+
+Measurement series and Measuring environment
+The access and information about the VMR, measuring setups and measurement series are much more separated in the part-based workflow as compared to the part-less workflow. New categories and ElementSelection
categories were introduced. If you have further questions regarding scripting purposes, please contact the ZEISS support.
+Here just the most important information follows. The measurements have their own category in the part-based workflow. A measurement can be accessed via the attribute measurement_series
and no longer via actual_elements
.
+MEASUREMENT = gom . app . project . measurement_series [ 'Scan 1' ]
+
+MEASUREMENTS = gom . ElementSelection ({ 'category' : [ 'key' , 'elements' , 'explorer_category' , 'measurements' , 'object_family' , 'measurement_series' ]})
+
+
+
+
+Reports
+Reports did not change so much in the part-based workflow. Reports are not assigned to a part, they show the situation of measurement series, VMR or multiple parts at the same time. Some slight changes must be taken into account: The keyword alignment
could now return names of more than one alignment (comma separated, i.e. a Python list) due to the fact that multiple parts (if visible in the report page) with their own alignment must be respected.
+
+
+CAD structure and contents
+For scripting with CADs in part-based projects, some additional information are necessary. Most importantly:
+Only one CAD Group per part is supported.
+
+The CAD Group (in a part-based workflow) supports now the access via an internal file structure to represent structures stored in CAD files like CATProduct . These entities are imported in the part-less workflow as separated CAD Groups .
+The following simple code examples show how to access bodies or files of a CAD Group.
+⚠️ Keep in mind: This access gives you information about the bodies or files. You can use this also for the deletion of bodies. Visibility operations are suppressed by intention. Usage for construction purposes is not recommended due to the fact that exchanging CAD structures would not work as expected.
+# this example code list all bodies of all CADs for all parts
+cad = filter ( lambda c : c . type == "cad" , gom . app . project . nominal_elements )
+for c in cad :
+ print ( c . name , c . type )
+ for b in c . bodies :
+ print ( b . name )
+
+
+This is an example to list files by cat_part
:
+cad = filter ( lambda c : c . type == "cad" , gom . app . project . nominal_elements )
+
+# for all cads in all parts list the file structure of each CAD of one part and furthermore all bodies of each file
+for c in cad :
+ print ( c . name )
+ print ( 'Number of files: ' + str ( len ( c . file )))
+ for file in c . file :
+ print ( file )
+ for b in file . bodies :
+ print ( ' {} ' . format ( b . name ))
+
+
+
+
+CAD assembly structure in the Elements in clipboard
+These information are usually not necessary for scripting. The most important fact is that the assembly structure does not represent our CAD structure. The assembly structure shows much more internal details.
+
+
+Script compatibility
+
+Actual master and All CAD Group proxy
+For the single part workflow old scripts using Actual Master and the All CAD Group proxy in creation commands should usually work.
+⚠️ Keep in mind: The functionality of these proxies is no longer present in the part-based workflow. Therefore functionalities like Define Actual Master will not work anymore. If the scripting tries to resolve the elements for the Actual Master a mapping takes place and the ActualValues-Reference of the unique part is returned. The same happens for the All CAD Group proxy and the NominalValues-Reference .
+
+
+Measurement series
+The script compatibility for the current measurement list is given in most cases. Normal information is usually accessible via the same attributes as before.
+
+
+Tesselate Geometrical Element
+The obsolete command gom.script.mesh.tesselate_geometrical_element
creates an element of type mesh.
+In the part-based workflow this command has been replaced with the command gom.script.primitive.tesselate_geometrical_element
, which creates elements of type surface.
+
+
+
+
+Access element properties
+The “elements” of the GOM Software, i.e. what you see in the element explorer of your project, hold several properties and data which you can access using the Python API.
+First of all, you need a reference to an element, which you can get either by using a script dialog or simply by referencing it by name.
+If you have installed the Python API Examples
add-on from the store and loaded the gom_part_test_project
(see the Python API Examples Documentation ), you can reference the mesh like this:
+mesh_element = gom . app . project . parts [ 'Part' ] . actual
+
+
+
+Explore available properties
+Once you have a reference to the element, you can access its properties using several keywords in the form element.<keyword>
.
+One way to inspect the available keys is by using the ‘Script Object’ explorer, which is available from the context menu -> Insert -> Element Value
or by shortcut F2
.
+
+You will find several keywords there, with a preview of the current value.
+If you click OK
, the complete call, including element reference by name, will be copied to your current script. If you already have a name reference, you can of course use this reference.
+mesh_element = gom . app . project . parts [ 'Part' ] . actual
+print ( mesh_element . area )
+
+
+Output:
+
+
+
+Element properties in VSCode
+Using Visual Studio Code, you can get auto-completion for the usable keywords directly in a pop-up.
+
+See Using VSCode Editor for details.
+
+
+Properties of different stages
+If you are using a multi-stage project, the approach as described above will always give you the element properties in the current stage. If you need access to properties in a different stage, you can use the in_stage[s]
modifier:
+mesh_element = gom . app . project . parts [ 'Part' ] . actual
+print ( mesh_element . in_stage [ 0 ] . area )
+
+
+Output:
+
+
+
Note
+
Stage indices start with index 0
.
+
+In this way, you can get simple properties of a different stage. If you need access to data of all stages at once, especially for larger data (like arrays of vertices), use “Data interfaces” as described below.
+
+
+
+Element data interfaces
+In a script, each element present in the application (project, inspection elements, reports, …) can be referenced by a named identifier. Each identifier consists of a type and some index, which can be a name or an integer number.
+
+Concept
+This is already the case for access via the data interface instead of the token interface: The returned value has the format (stages, <index dimensions>)
.
+
+
Example 1 - Mesh
+
# Mesh in 8 stage trend project with 238654 points, each with one (x, y, z) triple
+> print ( gom . app . project . parts [ 'Part' ] . actual . data . coordinate . shape )
+( 8 , 238654 , 3 )
+
+
+
+
+
Example 2 - Scalar value
+
# Single scalar value in a 8 stages trend project
+> print ( gom . app . project . inspection [ 'My Check' ] . data . result_dimension . deviation . shape )
+( 8 , 1 )
+
+
+
+
+
Example 3 - Image
+
# Image in 8 stage trend project with 4000x3000 pixels, each with one (r, g, b, a) tuple
+> print ( gom . app . project . measurement_list [ 'Scan' ] . measurement [ 'M1' ] . images [ 'Left camera' ] . data . rgb . shape )
+( 8 , 3000 , 4000 , 4 )
+
+
+
+⚠️ When accessing the image, the complete data set is not transferred immediately from C++ to Python! Instead this happens just in the moment when it is converted into a numpy array!
+
+
Example 4 - Transferring image data
+
# Fetch gom.Array with image data in all stages (not transferred !)
+> image = gom . app . project . measurement_list [ 'Scan' ] . measurement [ 'M1' ] . images [ 'Left camera' ] . data . rgb
+> print ( image . shape , type ( image ))
+( 8 , 3000 , 4000 , 4 ), gom . Array ()
+# 45 MB Image data if on stage, transferred in < 100 ms
+> data = np . array ( image [ 0 ])
+> print ( data . shape )
+( 3000 , 4000 , 4 )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/python_api_introduction/script_dialogs_introduction.html b/2022-new-headings-intros/howtos/python_api_introduction/script_dialogs_introduction.html
new file mode 100644
index 0000000..344e9c2
--- /dev/null
+++ b/2022-new-headings-intros/howtos/python_api_introduction/script_dialogs_introduction.html
@@ -0,0 +1,2514 @@
+
+
+
+
+
+
+ Using script dialogs — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Using script dialogs
+
+
+Creating dialogs
+
+
+Dialog designer
+
+User defined Dialogs can be inserted into the script using right mouse button ->”Insert / Dialog…”.
+
+
+When a new dialog is inserted, a dialog Template , the target location of the dialog configuration and the dialog Type can be selected.
+
+
+Some dialog Templates are provided by the system. Additional templates can be created by the user.
+The options for placing a dialog configuration (see section Create as in the window above) are
+
+The base filename of a dialog file is dialog.gdlg
, it can be renamed later. A dialog is stored as a JSON document internally.
+
+
+
Example: Script with separate dialog file
+
RESULT = gom . script . sys . execute_user_defined_dialog ( file = ':dialog.gdlg' )
+
+
+
+
+
Example: Script with embedded dialog
+
RESULT = gom . script . sys . execute_user_defined_dialog ( dialog = {
+ "content" : [
+ [
+ {
+ ...
+ }
+ ]
+ ],
+ "control" : {
+ "id" : "OkCancel"
+ },
+ "embedding" : "always_toplevel" ,
+ "position" : "automatic" ,
+ "size" : {
+ "height" : 155 ,
+ "width" : 198
+ },
+ "sizemode" : "automatic" ,
+ "style" : "" ,
+ "title" : {
+ "id" : "" ,
+ "text" : "Message" ,
+ "translatable" : True
+ }
+})
+
+
+
+
+The options for the dialog Type are
+
+Break dialog (script is blocked) - default
+Extendable break dialog (script is blocked)
+Info dialog (script continues)
+
+The dialog type is explained in section Executing dialogs
+
+Dialogs are designed using a GUI based Dialog Editor .
+
+
+
+
+
+Dialog layout
+
+
+Editing the grid
+💡 Editing the layout means changing the underlying grid.
+
+Because the underlying layout is a grid, the following actions are possible:
+
+
+
+Tool button
+Function
+
+
+
+
+Split selected cells vertically
+
+
+Split selected cells horizontally
+
+
+Merge selected cells
+
+
+
+
+Selected cells are marked with a red overlay.
+
+
+
+
+
+Spacers
+💡 Spacers are empty spaces extending in either horizontal or vertical direction.
+
+If a spacer is inserted into a cell, the cell claims the maximum available space in spacer direction.
+All other cells share the remaining space.
+
+
+
+
+
+
+Editing already created dialogs
+
+Creating a dialog leads to a script command with a dialog representation as JSON code, which can either be embedded or stored in an external dialog file (*.gdlg
).
+Double clicking onto the embedded dialog or the dialog file opens the Dialog Editor again.
+
+
+
+
+
+Executing dialogs
+
+
+Dialog commands
+
+Break dialog (execute
)
+
+
+Standard case of a dialog.
+The dialog is created and executed with a single command.
+The command blocks the script until the dialog is closed again.
+The dialog result is returned.
+
+
+RESULT = gom . script . sys . execute_user_defined_dialog ( dialog = {
+ "content" : [
+ [
+ {
+ "columns" : 1 ,
+ "name" : "label" ,
+ "rows" : 1 ,
+ "text" : {
+ "id" : "" ,
+ "text" : "Distance" ,
+ "translatable" : True
+ },
+ "tooltip" : {
+ "id" : "" ,
+ "text" : "" ,
+ "translatable" : True
+ },
+ "type" : "label" ,
+ "word_wrap" : False
+ },
+ {
+ "background_style" : "" ,
+ "columns" : 1 ,
+ "maximum" : 1000 ,
+ "minimum" : 0 ,
+ "name" : "inputDistance" ,
+ "precision" : 2 ,
+ "rows" : 1 ,
+ "tooltip" : {
+ "id" : "" ,
+ "text" : "" ,
+ "translatable" : True
+ },
+ "type" : "input::number" ,
+ "unit" : "" ,
+ "value" : 0
+ }
+ ]
+ ],
+ "control" : {
+ "id" : "OkCancel"
+ },
+ "embedding" : "always_toplevel" ,
+ "position" : "automatic" ,
+ "size" : {
+ "height" : 112 ,
+ "width" : 198
+ },
+ "sizemode" : "automatic" ,
+ "style" : "" ,
+ "title" : {
+ "id" : "" ,
+ "text" : "Distance" ,
+ "translatable" : True
+ }
+})
+
+
+
+
+
+Extendable break dialog (create
and show
)
+
+
+A dialog is created and executed by subsequent commands.
+This way, the created dialog can be modified by the script right before execution.
+
+
+
Creating and executing a dialog with two separate commands
+
# Create dialog, but do not execute it yet
+DIALOG = gom . script . sys . create_user_defined_dialog ( content = '...' )
+
+#
+# The dialog has been created. At this point of the script, the dialog handle DIALOG
+# can be used to access and configure dialog parts
+#
+
+# Execute dialog and fetch execution result
+RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+
+
+
+
+
+Info dialog (create
, open
and close
)
+
+
+In this mode, the script execution continues after the dialog has been opened.
+The sequence of commands is as follows:
+
+the create
command creates a dialog. The dialog can be configured now. Afterwards
+the open
command is issued to display the dialog. The script executing continues. At last
+the close
command closes the dialog again, if no closed manually by the user yet.
+
+
+
+💡 At script termination all open dialogs are closed automatically.
+
+
Non blocking configurable dialogs
+
# Create dialog but do not execute it yet
+DIALOG = gom . script . sys . create_user_defined_dialog ( content = '...' )
+
+#
+# The dialog has been created. At this point of the script, the dialog handle DIALOG
+# can be used to access and configure dialog parts
+#
+
+# Show dialog. The script execution continues.
+gom . script . sys . open_user_defined_dialog ( dialog = DIALOG )
+
+#
+# The dialog content can be modified here, the dialog is still open
+#
+DIALOG . title = 'Stufe 2'
+
+# Close dialog again
+gom . script . sys . close_user_defined_dialog ( dialog = DIALOG )
+
+
+
+
+
+
+Dialog results
+💡 The return value is an object with one property per interactive dialog widget containing its current value.
+
+The return value is an object containing all current values.
+Each dialog widget which can be changed by the script user writes its resulting value into this result object.
+The key for each widget is its object name, which is unique.
+
+
+#
+# Print whole dialog result. This is a result map with just one entry 'distance', named after
+# the unique name assigned to the spinbox.
+#
+print ( RESULT ) # Print whole result map
+# output: gom.dialog.DialogResult ('distance': 2.0, 'label': None)
+
+#
+# Print result for the element named 'distance'. This will lead to the spinbox content.
+#
+print ( RESULT . distance )
+# output: 2.0
+
+
+
+# Print content of the 'name' widget
+print ( RESULT . name )
+# output: Line 1
+
+# Print content of the widget named 'point1'. This can again be an element reference.
+print ( RESULT . point1 )
+# output: gom.ActualReference (gom.app.project.inspection['Point 5'])
+
+# Print content of the widget named 'point2'.
+print ( RESULT . point2 )
+# output: gom.ActualReference (gom.app.project.inspection['Point 6'])
+
+# construct a line with the user input. Therefore our dialog works similar to the 2-point line
+# construction dialog
+MCAD_ELEMENT = gom . script . primitive . create_line_by_2_points (
+ name = RESULT . name ,
+ point1 = RESULT . point1 ,
+ point2 = RESULT . point2 )
+
+
+💡 The type of the result depends on the specific widget.
+
+Custom results
+You can return custom results from dialogs using an optional parameter to the close_user_defined_dialog
-function. The following example produces ‘Yes’
+and ‘No’ results for the different buttons and ‘Cheater’ when the user uses the close button of the dialog.
+DIALOG = gom . script . sys . create_user_defined_dialog ( content = '...' )
+
+#
+# Event handler function called if anything happens inside of the dialog
+#
+def dialog_event_handler ( widget ):
+ if widget == DIALOG . button_yes :
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG , result = 'Yes' )
+ if widget == DIALOG . button_no :
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG , result = 'No' )
+
+DIALOG . handler = dialog_event_handler
+
+try :
+ RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+except gom . BreakError as e :
+ RESULT = 'Cheater'
+
+print ( 'RESULT' , RESULT )
+
+
+Please find the complete example here: dialog_yes_no.py
+
+
+
+
+Event handler functions
+
+Registering event handlers
+
+A function can be registered to the dialog called on value changed.
+Every time the user modified a dialog value, the handler function is called.
+The handler function is also called on application global signals, e.g. when application data has been changed. In these cases is the string 'system'
passed to the handler function. Those global signals are caused by changing the element selection or opening a project for example.
+The handler function can access dialog widget properties.
+The handler function is registered using the special attribute handler
.
+The prev and next buttons of a wizard dialog are the only control widgets, which trigger the event handler.
+
+
+
Dialog handler functions
+
DIALOG = gom . script . sys . create_user_defined_dialog ( content = 'dialog definition' )
+
+# Handler function registered to the dialog
+def handler_function ( widget ):
+ # Print information about the modified widget
+ print ( "Modified:" , str ( widget ))
+ # If the 'name' widget is empty, the 'ok' button is disabled.
+ if DIALOG . name . value == "" :
+ DIALOG . control . ok . enabled = False
+ else :
+ DIALOG . control . ok . enabled = True
+
+ if str ( widget ) == 'system' :
+ print ( "It is a global event." )
+ elif str ( widget ) == 'initialize' :
+ print ( "Dialog is displayed for the first time." )
+
+# Register dialog handler
+DIALOG . handler = handler_function
+
+# Execute dialog
+RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+
+
+
+A complete example with a handler function can be found in the file scriptingEditorExampleDialog.py . The argument passed to the event handler is either the dialog widget (e.g. a button) which triggered the event handler or a string. The following table lists all possible strings:
+
+
+Value
+Description
+
+
+
+‘system’
+Passed to the event handler in the case of a global event.
+
+‘timer’
+Passed to the event handler in the case of a global event.
+
+‘initialize’
+Passed to the event handler when the dialog is displayed for the first time.
+
+
+
+If the widget parameter is not a string, it represents a widget object. Note, that you cannot use the is
operator on these objects. Always use ==
and similar
+operators to compare the widget parameter:
+
+
Comparing widget parameters
+
def handler_function ( widget ):
+ ...
+ # compare widget using "==", using "is" will not work!
+ if widget == DIALOG . textInput :
+ if DIALOG . textInput . value == "" :
+ DIALOG . control . ok . enabled = False
+ else :
+ DIALOG . control . ok . enabled = True
+
+
+
+
+
+Closing dialogs from within the event handler
+💡 Dialogs can be closed from within event handlers.
+
+
+
Button event handler
+
def dialog_event_handler ( widget ):
+ if widget == DIALOG . button1 :
+ execute_func_1 ()
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG )
+ elif widget == DIALOG . button2 :
+ execute_func_2 ()
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG )
+ elif widget == DIALOG . button3 :
+ execute_func_3 ()
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG )
+
+
+
+⚠️ Right after the dialog has been closed its handle becomes invalid.
+This implies, that the event handler function must be written in a way that no dialog dependent code is executed after the dialog has been closed.
+
+
+Using a timer to activate the event handler
+Each DIALOG
has a special property named DIALOG.timer
. This timer property can be used to trigger the event handler registered to DIALOG
in
+certain time intervals. When the event handler is triggered by the timer, the string timer
is passed to it. The __doc__
-string of the timer gives information
+about its attributes:
+print ( DIALOG . timer . __doc__ )
+# output:
+# Timer
+#
+# Attributes:
+# enabled (boolean) - timer enabled
+# interval (integer) - timer interval [ms]
+
+
+💡 Please note that the timer is disabled by default.
+Example:
+
+
+
Button/Timer event handler
+
DIALOG = gom . script . sys . create_user_defined_dialog ( content = 'boring dialog definition' )
+
+#
+# Event handler function called if anything happens inside of the dialog
+#
+state = False
+def dialog_event_handler ( widget ):
+ global state
+ if widget == DIALOG . start :
+ DIALOG . timer . interval = DIALOG . interval . value * 1000
+ DIALOG . timer . enabled = True
+ DIALOG . start . enabled = False
+ DIALOG . stop . enabled = True
+ elif widget == DIALOG . stop :
+ DIALOG . timer . enabled = False
+ DIALOG . start . enabled = True
+ DIALOG . stop . enabled = False
+ elif widget == DIALOG . interval :
+ DIALOG . timer . interval = DIALOG . interval . value * 1000
+ elif widget == DIALOG . exit :
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG )
+ elif str ( widget ) == 'system' :
+ print ( "Its a system event." )
+ elif str ( widget ) == 'timer' :
+ print ( "Its a timer event. Let´s swap the image." )
+ state = not state
+
+ if state :
+ DIALOG . image . system_image = 'system_message_warning'
+ else :
+ DIALOG . image . system_image = 'system_message_question'
+
+DIALOG . handler = dialog_event_handler
+DIALOG . stop . enabled = False
+RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+
+
+
+The complete code of the example can be found here: timer.py .
+
+
+
+
+
+Wizards
+
+
+Wizards are dialogs with < Back and Next > buttons at the lower dialog edge.
+The script programmer is responsible for adding functionality to this layout.
+Wizards are not very versatile, but modifying the displayed texts and images is easily possible.
+
+⚠️ It is not possible to exchange widgets from within a dialog after the dialog has been created!
+Therefore Wizards only have simple options like exchange of images and texts in those containing elements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/python_api_introduction/using_script_resources.html b/2022-new-headings-intros/howtos/python_api_introduction/using_script_resources.html
new file mode 100644
index 0000000..df2f318
--- /dev/null
+++ b/2022-new-headings-intros/howtos/python_api_introduction/using_script_resources.html
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+ Using script resources — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Using script resources
+The term “resource” is used to describe any files in your scripts directories that are not python scripts (*.py
). You can use these files to include binary data such as images or other data like config files etc. in your add-ons.
+
+Importing resources
+The resources files in your scripts directory are automatically recognized as such. You can as well add (import) resources using the context menu of the script editor.
+
+
+
+Usage in scripts
+To get access to resource data in a script, the qualified name or relative path to the resource is needed.
+The qualified name starts with a :
followed by the top-level folder and the path to the resource, e.g. :PythonApiExamples/examples/script_resources/test_resource.txt
. You can also use a relative path to the currently executed script.
+
+
Hint
+
When using relative paths, the path is resolved to the script currently executed . This is not inevitably the script containing the gom.Resource
call. E.g., when you import a script (A) containing a gom.Resource
call in another script (B) and then execute the script (B), script (B) will be the currently executed one. In this case, usage of qualified names is advised.
+
+Suppose you created a script called resource_example.py
in a folder next to test_resource.txt
. In the script, you can read the data in the following way:
+res = gom . Resource ( "test_resource.txt" )
+if ( res . exists ()):
+ print ( res . open () . read ())
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/scripted_elements/scripted_actuals.html b/2022-new-headings-intros/howtos/scripted_elements/scripted_actuals.html
new file mode 100644
index 0000000..bb163ac
--- /dev/null
+++ b/2022-new-headings-intros/howtos/scripted_elements/scripted_actuals.html
@@ -0,0 +1,238 @@
+
+
+
+
+
+
+ Scripted actuals — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Scripted actuals
+
+Scripted actual elements (short: scripted actuals), are scripted elements that refer to the actual, e.g. measured state of a geometrical object. Therefore, they appear in the “Actual Element” category of the GOM Inspect Element Explorer.
+In this how-to, the creation of a very basic point element is presented to show how scripted actuals are developed by example.
+
+Example: Simple offset point
+Assume we want to create a scripted point. A point, whose position is just offsetted by a couple of millimeters from another point. Though the use of such element is clearly limited, it serves as an easy example on the general approach.
+As explained in the previous chapter, at first we select the element type in the script properties. For our offset-point, we naturally choose “Actual element” -> “Point”.
+
+Then, we write the code, which needs a dialog
and a calculation
function. Let’s begin with the dialog
function.
+
+dialog
+ 1 def dialog ( context , params ):
+ 2
+ 3 DIALOG = gom . script . sys . create_user_defined_dialog ( dialog = { < Dialog JSON code > })
+ 4
+ 5 if 'x' in params :
+ 6 DIALOG . i_x . value = params [ 'x' ]
+ 7 if 'base' in params :
+ 8 DIALOG . point . value = params [ 'base' ]
+ 9
+10 RESULT = gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+11
+12 params [ 'x' ] = DIALOG . i_x . value
+13 params [ 'base' ] = DIALOG . point . value
+14
+15 context . name = 'My scripted point'
+16 return params
+
+
+As you can see, the function takes the parameters context
and params
. Although the context
object has several members, for now we will only use it to set a name for our scripted element (line 15). The main objective of our dialog function is to fill the second parameter, the params
map (python type: dictionary).
+In this case, we want to ask the user on which point our offset-point should be based on, and by how much the point should be offset. We create a user dialog and in the dialog editor, we add two input widgets:
+
+
+It’s important to note the widgets’ “Object name”s, so we can adress them in the code. Second, it’s important to set the “Type” of the selection element widget to Any point
, so the user gets only the choice between elements that offer some point information.
+When finished with dialog creation, we have our desired JSON code, which we can use as a parameter for the gom.script.sys.create_user_defined_dialog
command (line 3). This gives as a DIALOG
handle, which we will use further.
+In case the dialog
function is called from “Edit creation parameters”, e.g the user wants to change parameters after the element was already created, the params
map is not empty. Instead, it holds the command parameters from the last creation. Hence, we should prefill our DIALOG’s widgets with the current values (see line 5 to 8). We can access the values of the widgets using the dialog handle and widgets’ object names: DIALOG.<widget name>.value
.
+Then, the dialog is shown to the user (line 10) and afterwards the results are collected (lines 12/13). After setting the element name, the parameters are returned. The framework then continues to call the calculation
function.
+
+
+calculation
+In most applications, the tricky part probably comes now, where you could solve complex mathematical problems to compute your final element values necessary.
+However, in this example, things are easy.
+1 def calculation ( context , params ):
+2
+3 base = params [ 'base' ] . center_coordinate
+4 context . result [ 0 ] = ( base . x + params [ 'x' ], base . y , base . z )
+5
+6 return True
+
+
+The parameters of the calculation
function are again context
and params
. From the params
, we can access the selected point element using params['base']
.
+What we get is a gom.Reference
to the element the user selected. We can now access the element’s properties , such as the center_coordinate
.
+Finally, we have to fill the context.result
member. Depending on the scripted element type we want to create, it takes different formats.
+As described in the Scripted elements API reference , a point element takes a coorinate tuple (x, y, z)
.
+The result for stage 0
(we ignore other stages for this example) is set in line 4. We return True
to indicate the computation went fine.
+
+
+Running the example
+That’s it! When we now run the example, the dialog appears, we can select base point and offset value.
+
+After clicking “OK”, a “My scripted point” element is created and visible in the explorer.
+
+
+
See also
+
The code of the example can also be found in the Python API Examples
add-on, which contains many more examples, along with Example documentation .
+
+
+
+
+Further reading
+Now you’ve grasped the basic concept of scripted actuals. However, there are some relevant topics missing to complete a fully-integrated experience of a scripted actual. E.g. you might have noticed that we did not cover:
+
+To learn about these mechanisms, you should take a look at the more sophisticated examples of our Python API Examples
add-on, documented here .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/scripted_elements/scripted_checks.html b/2022-new-headings-intros/howtos/scripted_elements/scripted_checks.html
new file mode 100644
index 0000000..a40b953
--- /dev/null
+++ b/2022-new-headings-intros/howtos/scripted_elements/scripted_checks.html
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+ Scripted checks — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Scripted checks
+
+
Note
+
This section assumes that you are familiar with the basic concept of Scripted elements. If not, take a look at the Introduction and Scripted actuals sections.
+
+
+Introduction
+Scripted checks are a specialization of scripted elements to realize customized inspections in the GOM Software. Use checks if you want to display the deviation of certain properties of existing elements.
+
+
+Writing a scripted check
+The script structure to create a scripted check is the same as for Scripted actuals . However, there are some specialities:
+
+
+“Special” parameters
+For a successful integration with the native checks, unit and tolerance need to be set to the returned params
.
+ params [ 'tolerance' ] = DIALOG . tolerances . value
+ params [ 'unit' ] = DIALOG . unit . value
+ params [ 'abbreviation' ] = 'ScrSca'
+
+
+Furthermore, checks shall be assigned an abbreviation
. This is the short form you’ll see in the 3D view labels of the check, or in the result table.
+
+
+
+
+Types of scripted checks
+Currently, three types of scripted checks are supported. The Python API Examples
add-on provides examples for all three. Click on the respective links to get to the example documentation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/scripted_elements/scripted_elements_introduction.html b/2022-new-headings-intros/howtos/scripted_elements/scripted_elements_introduction.html
new file mode 100644
index 0000000..05cfc5c
--- /dev/null
+++ b/2022-new-headings-intros/howtos/scripted_elements/scripted_elements_introduction.html
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+ Introduction — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Introduction
+This documentation is intended to demonstrate the ability to create parametric elements in the GOM Software using custom python code.
+
+Types
+A Script Element is always of a certain geometric type, like a point, surface curve, mesh etc. After creation, it can be used in the project identically to regular actual elements of the same type.
+Script Elements can depend on other elements, other elements can depend on script elements and they are recalculate if needed.
+There are currently two categories of scripted elements:
+
+Scripted actual elements
+
+
+Scripted checks
+
+
+
+
+
+Usage
+To create a scripted element, the general prodecure is as follows:
+
+Create a script in the script editor or using VS Code.
+Select the type of element that is created by this script in the script properties.
+Write your script code in a certain structure (see Code structure ).
+
+
+Set element creation type
+
+You can set different properties to a script in the script editor. For scripted elements, the “Element creation” section provides drop-down menus to select the element type.
+Right-click (or double click) on an editable script in the script editor
+Enable element creation, e.g. “Actual element”
+Select the desired element type, e.g. “Circle”
+Each element type requires the script to provide for certain values of specific data types, which are defined in the Scripted Elements API Specification .
+
+
+Code structure
+The script must contain two special functions as entry points for the gom application. One is responsible for creating a user interface, the other one for computing the element data.
+# -*- coding: utf-8 -*-
+import gom
+
+def dialog ( context , params ):
+ # [...]
+ # show dialog, fill param map, ...
+ # [...]
+ return params
+
+def calculation ( context , params ):
+ # [...]
+ # read params, perform calculation, set results
+ # [...]
+ return is_computation_valid # (True/False)
+
+
+The dialog
function
+The dialog function will be invoked, when the command is firstly run (from the menu or from the script editor) or when editing a created element using “Edit creation parameters”. Most commonly, you would create a script dialog and show it to the user, who can then select the desired parameters for element creation.
+The dialog function can initiate a preview calculation of the element to be created in the background.
+As a result of dialog
, a parameter map that defines the command parameters of the created element is returned.
+
+The calculation
function
+The calculation function will be invoked by the application, when the parameter map changes to recalculate necessary element values. This is usually the first time when the dialog
function returns or if a preview calculation is triggered.
+In case the command parameters contain references to other elements of the project, these elements are regarded as dependencies. Consequently, the calculation
is triggered as well when one of the dependencies changed.
+This approach is called parametric element creation .
+At the end of the calculation, the results have to be set to context.result
. This member of the function’s context
parameter can hold result data for each project stage. You can get all available project stages with context.stages
. The type of result you have to assign for a successful element creation is dependent on which type of element you want to create, e.g. setting (x, y, z) values for a scripted point element.
+
+
+
+
+Next steps
+To understand how Scripted elements work in practice, head over to the next chapter of Scripted Actual Elements .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/scripted_elements/scripted_elements_toc.html b/2022-new-headings-intros/howtos/scripted_elements/scripted_elements_toc.html
new file mode 100644
index 0000000..40495f8
--- /dev/null
+++ b/2022-new-headings-intros/howtos/scripted_elements/scripted_elements_toc.html
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+ Scripted elements — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Scripted elements
+The following how-tos will introduce the concept of scripted elements, i.e. elements of the GOM Software that are created by calculation logic written in Python.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/scripted_elements/tokens_on_scripted_elements.html b/2022-new-headings-intros/howtos/scripted_elements/tokens_on_scripted_elements.html
new file mode 100644
index 0000000..5430125
--- /dev/null
+++ b/2022-new-headings-intros/howtos/scripted_elements/tokens_on_scripted_elements.html
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+ Tokens on scripted elements — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Tokens on scripted elements
+
+
+Introduction
+This page describes how user-defined tokens can be set to user-defined elements (UDEs).
+
+
+Instructions
+
+How user-defined tokens are set
+In the calculation function that generated the results, the context.data[]
field can be read and written.
+In the following example, a volume defects element was created with following snippet inside the calculation()
function:
+# Simulating user-defined token data
+ids = np . array ([ i for i in range ( 166 ])
+for s in context . stages :
+ context . data [ s ] = { "ude_defect_ids" : ids , "ude_test_string" : "hello world" }
+
+
+Generally, the context.data[]
field can be used to store intermediate data between the dialog()
and the calc()
function, e.g. if you – for preview reasons – pre-calculated some values, you can reuse them in the calc() function.
+Starting with SW2021 (Final) however, if you set the context.data[s]
to hold a Python dictionary – i.e. a key-value map – for each stage s
, then this data will be interpreted as ‘token’ data. These are generally data entities set to a GOM element, which can be retrieved using a key-string (the token).
+With this user-defined token mechanism, you are free to set any data structure as token data to the element you are creating as UDE, as long as it is serializable by the GOM scripting framework. You can use therefore: basic Python data types, numpy arrays, the GOM data types such as GOM.Vec3D, and finally lists and dictionaries of the previously mentioned types.
+In the example given above, we create a numpy array with IDs, one for each defect, and set this together with an exemplary test string as token data to the element.
+
+
Note
+
Note: Naming of user-defined tokens
+
⚠️ The keys in the key-value map of user-defined tokens must start with the prefix ude_
. If this is not the case, the token will not be set.
+
+
+
+Usage of user-defined tokens in scripts
+Let’s see how this data can be retrieved after the element was successfully created:
+
+Open the script editor and create a new script. In the new script, press “F2” or right-click → Insert → Element Value.
+In the appearing dialog, search for the volume defects element, and you will find the user-defined data in the “User-defined keywords” section.
+
+For simple data types, you will get a preview (see Screenshot). For more complex types, including numpy arrays, there is no preview. The further usage works nevertheless.
+
+If you click “OK”, the syntax how to retrieve the data is inserted in your new script. Of course, it is also possible to obtain the data from the element, if you have got a reference to it in a dialog selector or similar.
+You can now use the data in follow-up scripts.
+
+
+
+
+
+Usage in user-defined checks
+Just as all other tokens on the element, you can access the data in user-defined checks.
+For simple data types, this is straightforward. To make this work for indexed data, as in the example of “defect_ids”, you have to make sure that the array data you set to the token has the same length as the indices of the element.
+In the example above, the defect element gets 166 meshes, which will result in indices from 0 to 165.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/testing_addons/testing_addons.html b/2022-new-headings-intros/howtos/testing_addons/testing_addons.html
new file mode 100644
index 0000000..d02b8ca
--- /dev/null
+++ b/2022-new-headings-intros/howtos/testing_addons/testing_addons.html
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+ Testing add-ons — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Testing add-ons
+
+
Note
+
You can use the Python API Examples
add-on, which you can find in the store, as an example how to include tests in your add-on.
+
+
+Why testing?
+Testing your add-on is a crucial step for maintainability, especially when dealing with multiple software versions or updates. As manually testing your add-on is often tedious and time consuming, this how-to focuses on how to include automated tests in your add-on.
+Automated tests are important when writing add-ons in Python because they help to ensure the code is running correctly and efficiently. Furthermore, they can be used to ensure that the code is compatible with different versions of the GOM Software, as well as on different machines. Finally, automated tests can be used to improve the overall performance of the add-on, as well as to ensure it meets the user’s requirements.
+
+
+File structure
+
+
Note
+
The following structure is currently recommended and should serve you as a best-practice example. In upcoming SW-Versions, this structure might become mandatory for automatic test discovery to work.
+
+The file and folder structure of add-on tests is similar to the pyTest s Conventions for Python test discovery . We recommend:
+
+You may additionally include a script at the top-level that executes all of your tests (run_tests.py
in the screenshot).
+
+
+Writing a test script
+The following steps are required to write a new test script. The example code is taken from the Python API Examples
add-on, which you can find in the store.
+
+Create a test script: Create a Python file with the convention test_*.py.
+(Example: PythonApiExamples/tests/test_data_interfaces_check_results
)
+Import the module or package to be tested: Import the module or package that you want to test.
+# Importing the example we want to test
+import PythonApiExamples.examples.data_interfaces.check_results_data_array as example
+
+
+For this to work properly, the code that you want to test needs to be structured in functions as well. In this case, there are several functions in the check_results_data_arrray
script, like get_single_result_value()
, which will be called later (see step 3).
+For more details, see also: How the examples are structured .
+
+Write test functions: Write test functions named with prefix test_
that define expected behavior.
+def test_check_results ():
+ # Setup test project
+ open_project ( 'gom_part_test_project' )
+ test_element = gom . app . project . inspection [ 'Surface comparison 1' ]
+
+ # Test definition
+ expected_single_value = 2.0495047569274902
+ actual_result_value = example . get_single_result_value ( test_element )
+
+ assert actual_result_value == expected_single_value
+
+
+
+Define which tests to run when the script itself is executed. Then run the test script.
+# Test execution
+if __name__ == '__main__' :
+ test_check_results ()
+
+
+
+Check the results: Check the results of the test execution and make sure they match the expected behavior.
+
+
+
+Running all tests
+To run all tests, it is recommended to create a wrapper script that includes the calls to the test scripts. You can invoke calls to the test scripts using the command gom.script.userscript.<script_path>
, which will execute the script as if run separately using the script editor. The <script_path>
is to be replaced with a string desribing the location of the test script, whereas double underscores (__
) indicate subdirectories.
+import gom
+#
+# Run tests
+#
+gom . script . userscript . PythonApiExamples__tests__test_data_interfaces_check_results ()
+gom . script . userscript . PythonApiExamples__tests__test_ ... #...
+gom . script . userscript . PythonApiExamples__tests__test_ ... #...
+
+# Done
+print ( "ALL TESTS PASSED!" )
+
+
+In case of (unhandled) assertion errors, this script will stop and show the error message. ALL TESTS PASSED
is printed otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/howtos/using_vscode_editor/using_vscode_editor.html b/2022-new-headings-intros/howtos/using_vscode_editor/using_vscode_editor.html
new file mode 100644
index 0000000..1d329db
--- /dev/null
+++ b/2022-new-headings-intros/howtos/using_vscode_editor/using_vscode_editor.html
@@ -0,0 +1,465 @@
+
+
+
+
+
+
+ Using Visual Studio Code as an add-on editor — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Using Visual Studio Code as an add-on editor
+
+Setup
+
+Installation
+
+Installation
+
+
+Configure connection
+
+
+
+
+
+Connecting
+
+Have a GOM software running as a host
+In the VSCode status bar, the connection status is displayed:
+
+
+Press onto the “GOM host: Disconnected” status entry to connect to the host application.
+After the connection has been established,
+
+
+
+
+
+
+Editing
+
+Creating scripts
+
+Select ‘New GOM script’ from the file explorers right mouse menu.
+Enter unique name for that script.
+
+
+
+
+Executing scripts
+
+Select script to execute in the VSCode explorer.
+
+
+Select “Run script in GOM host” from the editors toolbar
+The script outputs will be shown in the “debug console”.
+
+
+
+
+
+Recording commands
+
+Select the script to record commands into to show it in the editor.
+In that editor, select “Record commands” from the editor toolbar.
+Execute commands in the GOM application
+
+The executed commands will be recorded in the currently edited VSCode script.
+In addition, the “GOM script commands” subsection of the output tab shows a log of the executed commands.
+
+
+
+
+For recording into a different position of the script, set the cursor to that line first or while recording.
+Press “Record commands” again to stop command recording.
+
+
+
+Inserting elements
+
+Elements in the GOM applications are represented by ‘element references’ in the script. These are python expressions which, when executed, return a reference to that element.
+
+
+When connected to a GOM application host, select the ‘Elements’ in the explorer view.
+
+
+Set editor cursor to the place the element should be into inserted into.
+Select “Insert element into editor” from the top toolbar of the ‘Elements’ tab
+
+You will get an ‘element reference’, an expression which, when, executed, returns the element referenced.
+
+
+
+
+
+
+
+Inserting keywords
+
+A keyword is an attribute used to query an element property. Various element attributes are existing depending on the element type.
+
+
+Insert an element reference in the script as mentioned above.
+After the element reference, press ‘.’ to insert a point
+
+
+
+
+
+
+Debugging
+
+Start debugging
+
+Prepare debugged script as usual by setting breakpoints etc.
+
+
+Start debugger by selecting “Debug script in GOM host” from the editor toolbar
+
+
+Full VSCode debugging functionality can be used now, including
+
+
+
+
+
+
+
+User defined script dialogs
+
+
Note
+
User defined script dialogs cannot be edited graphically in VSCode at the moment. Instead, a application based script dialog can be opened. A connection to a running application must be presetn for that purpose.
+
+
+Create new user defined script dialog
+
+Select “GOM Scripting: Insert new user defined script dialog” from the command selector or from the right mouse menu while editing the script the dialog should be inserted into.
+
+
+Choose a name for the dialog file which will then be created.
+
+
+The edited script will contain the necessary dialog commands then and a separate dialog definition file (*.gdlg) has been created.
+
+
+Select the dialog definition file to open the
+
+
+When the script is executed, the user defined script dialog is displayed.
+
+
+
+
+
+Edit user defined script dialog
+
+Edit script dialog file (*.gdlg) can be edited either in JSON format directly (possible, but not recommended) or by opening the script dialog editor in the connected application:
+
+
+The application will then open the script dialog editor. After closing it again, the edited *.gdlg file will be adapted accordingly.
+
+
+
+
+
Note
+
Due to an unsolved bug, the script editor window might open below the VSCode window or on another display in some multi display settings. There is a hint box as indicator that the script editor windows has been opened at all.
+
+
+
+
+
+FAQ
+
+Configuration
+
+How do I set a shortcut to toggle the recording mode ?
+
+Select the “Keyboard Shortcuts” properties from the configurations menu:
+
+
+Assign the command “GOM Scripting: Toggle recording” to a key:
+
+
+The ‘when’ clause determines when the command is available. The correct ‘when’ clause here ist:
+resourceLangId == python && scriptingHostConnected
+
+If necessary, existing command bindings to that key can be removed here, too:
+
+
+
+
+
+How do I set shortcuts for starting the current script in the GOM host ?
+
+See above for the general process.
+The relevant commands here are:
+
+
+F9 / CTRL + F9 might be valid keys for that.
+
+
+
+
+Script editing
+
+Can I use local workspaces from disk instead of the application script database for my project ?
+
+Yes.
+You can add arbitrary folders to the workspace and edit and starts scripts from right there.
+A limitation is that environments and packages cannot yet be handled by VSCode. As a workaround, the edited external folder can be added to the internal script editor, so that it can be processed from there:
+
+
+
+
+
+
+Dialog editing
+
+I cannot edit all aspects of the user defined script dialogs in visual studio code ?
+
+
+
+
+Troubleshooting
+
+When using IntelliSense completion, the keyword list stalls
+
+When using the ‘.’ or a hotkey to access the list of possible completions, a tooltip displays ‘Loading…’ but nothing happens:
+
+
+This bug is caused by the ‘Microsoft Python’ extension in connection with the script database filesystem.
+There is currently no fix, so disabling this extension is the only way here. This does not affect most python editor features:
+
+
+
+
+
+When starting both the application and a script from within Visual Studio Code, crashes can happen
+
+This is more a GOM internal issue. When developing application code and script code at the same time from the same VSCode instance, this can happen.
+The parallel debugging session (application and scripting) seem to be the problem.
+Workaround: Do not start GOM application via the VSCode launcher, but e.g. from a command prompt.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/index.html b/2022-new-headings-intros/index.html
new file mode 100644
index 0000000..e215ded
--- /dev/null
+++ b/2022-new-headings-intros/index.html
@@ -0,0 +1,208 @@
+
+
+
+
+
+
+ GOM Inspect Add-On Development Documentation — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+GOM Inspect Add-On Development Documentation
+Welcome to the GOM Inspect Add-On development documentation. With Add-Ons, you will be able to customize and extend the functionality of your GOM Inspect software.
+You can include several template configurations from the software, as well as completely new workflows programmed in python.
+
+
Note
+
This documentation is still under development. Expect bookmarks to sub-sites to change.
+
+
+If you are new to add-ons, we recommend following our how-to guides to get you started.
+
+If you already know how to create an add-on and now you are interested in python programming in GOM Inspect, take a look at our collection of Python examples.
+
+Available API functions are documented in the Specification.
+
+
Python API Specification
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/objects.inv b/2022-new-headings-intros/objects.inv
new file mode 100644
index 0000000..7ff7ab8
Binary files /dev/null and b/2022-new-headings-intros/objects.inv differ
diff --git a/2022-new-headings-intros/python_api/python_api.html b/2022-new-headings-intros/python_api/python_api.html
new file mode 100644
index 0000000..c2bea75
--- /dev/null
+++ b/2022-new-headings-intros/python_api/python_api.html
@@ -0,0 +1,427 @@
+
+
+
+
+
+
+
+
+ GOM Inspect Python API documentation — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+GOM Inspect Python API documentation
+Welcome to the GOM Inspect Python API documentation. Here you can find a detailed documentation of a subset of the Add-on programming specification. Please bear in mind, that recording commands with the script editor can be used to add new functions to your script.
+
+
Important
+
The now preliminary API is currently under heavy development and will change massively in the near future.
+
+
+Image processing
+Image related functions can be used to query images from the measurements of a project. This is not done directly, but via an ‘image acquisition’ object which acts as a proxy between the image storing data structured and the functions which can be used to process the image data.
+Terminology:
+
+
+gom.api.project
+
+
+gom.api.project. get_image_aquisition ( measurement , camera , stages )
+Generate a list of image acquisition objects which can be used as input for image processing functions.
+
+API version:
+1
+
+Parameters:
+
+measurement (Reference ) – Measurement the image is to be queried from
+camera (str ) –
Identifier for the camera which contributed to the measurement. Valid values are:
+
+’left camera’: Left camera in a two camera system or the only existing camera in a single camera system
+’right camera’: Right camera in a two camera system
+’photogrammetry’: Photogrammery (TRITOP) camera
+
+
+stages (list [ int ] ) – (Optional ) Indices of the stages for which an image acquisition object is to be generated.
+
+
+Returns:
+List of image acquisition objects which can be used by image processing functions. The number of objects matches the number of stage indices in the stages parameter of the function call.
+
+Return type:
+List [Reference]
+
+
+
+
+Example
+measurement = gom . app . project . measurement_series [ 'Deformation series' ] . measurements [ 'D1' ]
+stage = gom . app . project . stages [ 'Stage 1' ]
+point = gom . app . project . actual_elements [ 'Point 1' ] . coordinate
+
+left = gom . api . project . get_image_acquisition ( measurement , 'left camera' , [ stage . index ])[ 0 ]
+right = gom . api . project . get_image_acquisition ( measurement , 'right camera' , [ stage . index ])[ 0 ]
+
+
+
+
+gom.api.imaging
+
+
+gom.api.imaging. compute_pixels_from_point ( point_and_image_acquisition )
+Compute pixel coordinates from point coordinates
+
+API version:
+1
+
+Parameters:
+point_and_image_acquisition (List ) – List of pairs where each entry describes a point coordinate plus the image acquisition object which should be used to compute the matching image pixel.
+
+Returns:
+List of image pixels where each entry is the result of projecting the point via the associated image acquisition structure into the image. The pixel coordinate system center is located in the upper left corner.
+
+Return type:
+List
+
+
+
+
+Example
+measurement = gom . app . project . measurement_series [ 'Deformation series' ] . measurements [ 'D1' ]
+stage = gom . app . project . stages [ 'Stage 1' ]
+point = gom . app . project . actual_elements [ 'Point 1' ] . coordinate
+
+left = gom . api . project . get_image_acquisition ( measurement , 'left camera' , [ stage . index ])[ 0 ]
+right = gom . api . project . get_image_acquisition ( measurement , 'right camera' , [ stage . index ])[ 0 ]
+
+p = gom . api . imaging . compute_pixels_from_point ([( point , left ), ( point , right )])
+
+print ( p )
+
+
+[ gom . Vec2d ( 1031.582008690226 , 1232.4155555222544 ), gom . Vec2d ( 1139.886626169376 , 1217.975608783256 )]
+
+
+
+
+gom.api.imaging. compute_point_from_pixels ( [ [ pixel_and_image acquisition , ] ] use_calibration )
+Compute point coordinate from pixel coordinates
+
+API version:
+1
+
+Parameters:
+
+pixel_and_image_acquisition (List ) – List of pairs where each entry describes a pixel image coordinate plus the image acquisition object which should be used to compute the matching point.
+use_calibration (bool ) – If set, the information from the calibration is used to compute the point. Project must provide a calibration for that case.
+
+
+Returns:
+List of lists of (pixel, residuum) where each entry is the result of projecting the point via the associated image acquisition structure into the image. The pixel coordinate system center is located in the upper left corner.
+
+Return type:
+List
+
+
+
+
+measurement = gom . app . project . measurement_series [ 'Deformation 1' ] . measurements [ 'D1' ]
+stage = gom . app . project . stages [ 0 ]
+point = gom . app . project . actual_elements [ 'Start Point 1' ] . coordinate
+
+left = gom . api . project . get_image_acquisition ( measurement , 'left camera' , [ stage . index ])[ 0 ]
+
+p = gom . api . imaging . compute_point_from_pixels ([[( gom . Vec2d ( 10 , 10 ), left )]], False )
+
+print ( p )
+
+
+[[ gom . Vec3d ( - 638.2453100625158 , 1627.6169782583584 , 0.0 ), 0.0 ]]
+
+
+
+
+gom.api.imaging. compute_epipolar_line ( image_acquisition_1, [pixel_and_image_acquisition]_2, max_distance )
+Compute epipolar line coordinates
+
+API version:
+1
+
+Parameters:
+
+image_aquisition_1 (List ) – Handle of the image acquisition the epipolar line should be found in.
+pixel_and_image_aquisition_2 (List ) – List of pairs where each entry describes a pixel image coordinate plus the image acquisition object which should be used to compute the matching point. The image acquisition object here. is the “other” acquisition providing the pixels used to find the matching epipolar lines in the image_acquisition_1 object.
+max_distance (double ) – Maximum search distance in mm.
+
+
+Returns:
+List of epipolar line coordinates, each one consisting of a list of image pixels.
+
+Return type:
+List
+
+
+
+
+stage = gom . app . project . stages [ 'Stage 1' ]
+point = gom . app . project . actual_elements [ 'Point 1' ] . coordinate
+
+left = gom . api . project . get_image_acquisition ( measurement , 'left camera' , [ stage . index ])[ 0 ]
+right = gom . api . project . get_image_acquisition ( measurement , 'right camera' , [ stage . index ])[ 0 ]
+
+l = gom . api . imaging . compute_epipolar_line ( left , [( gom . Vec2d ( 1617 , 819 ), right )], 10.0 )
+
+print ( l )
+
+
+[[ gom . Vec2d ( 4.752311764226988 , 813.7915394509045 ), gom . Vec2d ( 10.749371580282741 , 813.748887458453 ), gom . Vec2d ( 16.73347976996274 , 813.706352662515 ), ... ]]
+
+
+
+
+
+Checks
+Functions used to handle checks.
+
+gom.api.scripted_checks_util
+
+
+gom.api.scripted_checks_util. is_scalar_checkable ( element )
+Test if the referenced element is suitable for inspection with a scalar check.
+
+API version:
+1
+
+Parameters:
+element (Reference ) – Element to be checked
+
+Returns:
+True’ if the given element s suitable for inspection with a scalar check.
+
+Return type:
+bool
+
+
+
+
+element = gom . app . project . inspection [ 'Point 1' ]
+state = gom . api . scripted_checks_util . is_scalar_checkable ( element )
+print ( state )
+
+
+
+
+
+gom.api.scripted_checks_util. is_surface_checkable ( element )
+Test if the referenced element is suitable for inspection with a surface check.
+
+API version:
+1
+
+Parameters:
+element (Reference ) – Element to be checked
+
+Returns:
+True’ if the given element s suitable for inspection with a surface check.
+
+Return type:
+bool
+
+
+
+
+element = gom . app . project . inspection [ 'Point 1' ]
+state = gom . api . scripted_checks_util . is_surface_checkable ( element )
+print ( state )
+
+
+
+
+
+gom.api.scripted_checks_util. is_curve_checkable ( element )
+Test if the referenced element is suitable for inspection with a curve check.
+
+API version:
+1
+
+Parameters:
+element (Reference ) – Element to be checked
+
+Returns:
+True’ if the given element s suitable for inspection with a curve check.
+
+Return type:
+bool
+
+
+
+
+element = gom . app . project . inspection [ 'Point 1' ]
+state = gom . api . scripted_checks_util . is_curve_checkable ( element )
+print ( state )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_api/resource_api.html b/2022-new-headings-intros/python_api/resource_api.html
new file mode 100644
index 0000000..c8259c3
--- /dev/null
+++ b/2022-new-headings-intros/python_api/resource_api.html
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+ gom.Resource API — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+gom.Resource API
+
+Summmary
+The gom.Resource
API can be used to access binary data of files included in an add-on’s scripts folder.
+
+
+
+Class definition
+
+
+class gom. Resource
+This module represents the Resource class. A utility to access resource data using relative paths and shared memory.
+
+
+static Resource. list ( )
+Lists all resources
+
+Returns:
+List of resources
+
+
+
+
+
+
+static Resource. cleanup ( )
+Closing all dangling resources (API call to free memory on C++ side)
+
+
+
+
+__init__ ( path )
+Constructor
+
+Parameters:
+path – Qualified name of the resource
+
+
+
+
+
+
+isLoaded ( )
+Check if the resource is loaded
+
+Returns:
+True if the resource is loaded, False otherwise
+
+
+
+
+
+
+close ( )
+Release resource from shared memory
+
+
+
+
+open ( size = 0 )
+Open the resource in shared memory
+
+
+
+
+exists ( )
+Check if the resource exists
+
+Returns:
+True if the resource exists, False otherwise
+
+
+
+
+
+
+byteSize ( )
+Get the size of the resource in bytes
+
+Returns:
+The size of the resource in bytes
+
+
+
+
+
+
+keepInMemory ( )
+Keep the resource in memory
+
+
+
+
+save ( size = 0 )
+Save the resource
+
+Parameters:
+size – Size of the resource
+
+Returns:
+True if the save was successful, False otherwise
+
+
+
+
+
+
+saveAsUserResource ( new_path , overwrite = True )
+Save the resource to a new path
+
+Parameters:
+
+new_path – New path to save the resource
+overwrite – True to overwrite existing files, False to not overwrite
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_api/scripted_elements_api.html b/2022-new-headings-intros/python_api/scripted_elements_api.html
new file mode 100644
index 0000000..ea6f446
--- /dev/null
+++ b/2022-new-headings-intros/python_api/scripted_elements_api.html
@@ -0,0 +1,690 @@
+
+
+
+
+
+
+ Scripted elements API — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+Scripted elements API
+This reference describes functions and data structures necessary for the implementation of “scripted elements”.
+
+
+The dialog
function
+💡 Notes:
+
+
+Signature
+def dialog ( context , params ):
+
+
+
+Parameter context
+The context contains the following members:
+
+
+Name
+Role
+Remarks
+
+
+
+
.data
+UDE data storage access
+see “calculate” Function
+
+
.stages
+Current stage
+List containing stage index of current stage
+
+
.total_stages
+Number of stages
+Valid stage indices are 0 to total_stages - 1
+
+
.calc
+Function to calculate preview
+See below
+
+
.result
+Directly set preview
+see “calculate” Function
+
+
.is_new_element
+Flag if element creation
+True on (edit) creation, false on recalc
+
+
.name
+Name of created element
+Read/write attribute Ignored on recalc and script execution
+
+
.error
+Last error text from preview calculation
+Empty if no error occurred
+
+
.edit_element
+Reference to edited element
+Only available during element editing
+
+
.recalc_element
+Reference to element used in project recalculation
+
+
+
+
+
+
+Parameter params
+The params contain a map of parameter values. It is only filled on element edit and contains the current parameters of the element.
+
+
+Return value
+The function must return a map containing the new element parameters.
+If no map is returned the edit/creation is regarded as aborted by the user.
+
+
+
+Calculating a preview
+To calculate a preview, the context.calc()
function can be invoked. It takes the following parameters:
+
+
+Name
+Role
+
+
+
+
params
+A map of parameters to be used for preview calculation
+
+
stages
+Optional: A list of stage indices to calculate a preview in
+
+
dialog
+Optional: A script dialog to message when preview calculation was successful. The dialog event handler will receive the event string ‘calculated’
+
+
+
+A call to this function will return immediately. The calculation is invoked asynchronously in a separate python instance.
+
+
+
+The calculation
function
+💡 Notes:
+
+It is not possible to call script commands or read tokens from within this function. (Do not call gom.app.project....
)
+The function should loop over all stages to be calculated and set a computation result for each stage.
+
+
+Signature
+def calculation ( context , params ):
+
+
+
+Parameter context
+The context contains the following members:
+
+
+Name
+Role
+Remarks
+
+
+
+
.data[stage]
+UDE data storage access
+see below
+
+
.stages
+Current indices
+List containing stage indices to calculate
+
+
.total_stages
+Number of stages
+Valid stage indices are 0 to total_stages - 1
+
+
.result[stage]
+Directly set preview
+see below
+
+
.is_new_element
+Flag if element creation
+True on (edit) creation, false on recalc
+
+
.name
+Name of created element
+Read/write attribute Ignored on recalc and script execution
+
+
.error[stage]
+Used to assign an error text
+Will set the element to not computed in the given stage
+
+
.edit_element
+Reference to edited element
+Only available during element editing
+
+
.recalc_element
+Reference to element being computed
+Only available during non-interactive calculation
+
+
.progress_stages_computing
+Number of stages which have started to compute
+Used to display progress information
+
+
.progress_stages_total
+Number of stages which have to be computed
+Used to display progress information
+
+
+
+
+Attribute context.data[]
+The context.data is a list allowing to read or write additional data. The list is indexed with a stage index. The additional data is stored within the project, so the gom application must be able to serialize the provided data.
+context . data [ 0 ] = value
+value = context . data [ 0 ]
+
+
+
+
+Attribute context.result[]
+This is a write only list used to set computation results. The context.result[] should be set for each stage index listed in context.stages.
+The format to write must match the type of the script element. For available result types, see Scripted actuals - Return values and Scripted checks - Return values .
+
+
+
+Return value
+On success the function must return True, otherwise False.
+
+
+
+
+Scripted actuals - Return values
+
+Point
+
+Element Type:
+Plain 3D point
+
+Result:
+Point coordinate
+
+
+result = ( x , y , z )
+result = gom . Vec3D
+
+
+
+
+Distance
+
+Element Type:
+Two point distance
+
+Result:
+Start and end point of distance
+
+
+result = { 'point1' : ( x , y , z ), 'point2' : ( x , y , z ) }
+result = { 'point1' : gom . Vec3D , 'point2' : gom . Vec3D }
+
+
+
+
+Value Element
+
+Element Type:
+Plain value (only real values supported)
+
+Result:
+any double value
+
+
+
+
+
+Circle
+
+Element Type:
+2D Circle with direction
+
+Result:
+A center point, direction vector and radius (double)
+
+
+result = { 'center' : gom . Vec3D , 'direction' : gom . Vec3D , 'radius' : double }
+
+
+
+
+Curve
+
+Element Type:
+3D polyline
+
+Result:
+A curve can be made up by an array of subcurves. Each subcurve is a polyline. A closed curve will be created, if first point = last point.
+
+
+result = [ { 'points' : [ gom . Vec3D , gom . Vec3D , ... ] } ]
+
+
+
+
+Surface Curve
+
+Element Type:
+3D polyline with normals
+
+Result:
+Like a curve with additional normal data, i.e. each surface curve can be made up by an array of subcurves.
+
+
+result = {
+ 'default' : [
+ { 'points' : [ gom . Vec3d , gom . Vec3d , ... ], 'normals' : [ gom . Vec3d , gom . Vec3d , ... ]},
+ { ... },
+ ...
+ ]
+}
+
+
+
+
+Section
+
+Element Type:
+3D polyline with normals
+
+Result:
+Parameters ‘plane’, ‘cylinder’ and ‘cone’ are optional. They denote the creation geometry. You can only use one of them. Argument is a corresponding trait.
+
+
+result = {
+ 'curves' : [{ 'points' : [( x , y , z ), ... ], 'normals' : [( x , y , z ), ... ]}, ... ],
+ 'plane' : { 'normal' : ( x , y , z ), 'distance' : float },
+ 'cylinder' : ... ,
+ 'cone' : ...
+}
+
+
+
+
+Point Cloud
+
+Element Type:
+Set of 3D points
+
+Result:
+A set of points. The ‘normals ‘attribute is optional.
+
+
+result = { 'points' : [ gom . Vec3D , gom . Vec3D , ... ] , 'normals' : [ gom . Vec3D , gom . Vec3D , ... ] }
+
+
+
+
+Surface
+
+Element Type:
+Mesh
+
+Result:
+Defines a triangulation. The vertices attribute points defines all points. The triangle attribute defines triangles between these points using indices into the vertex list.
+
+
+result = { 'vertices' : [ ( x , y , z ) ], 'triangles' : [ ( v0 , v1 , v2 ) ] }
+
+
+
+
+Cone
+
+Element Type:
+Cone
+
+Result:
+Accepts any Cone Trait
+
+
+result = { 'default' : { 'point1' : gom . Vec3d , 'radius1' : float , 'point2' : gom . Vec3d , 'radius2' : float } }
+
+
+
+
Caution
+
Due to the internal represenstation of a Cone Element, the direction of the vector point1
-> point2
is always from the smaller to the larger circle (radius1
< radius2
).
+
If you specify radius1
> radius2
in the creation parameters, [point1
; radius1
] and [point2
; radius2
] are swapped automatically.
+
+
+
+Cylinder
+
+Element Type:
+Cylinder
+
+Result:
+Accepts any Cylinder Trait
+
+
+result = Reference
+
+result = { 'default' : { 'point' : gom . Vec3d , 'radius' : float , 'direction' : gom . Vec3d , 'inner' : bool } }
+
+
+
+
+Volume defects
+
+Element Type:
+Volume defects
+
+Result:
+A list of meshes defined by vertices and triangles.
The vertices attribute is a [python array] – one entry for each defect – of numpy arrays (np.array) of Vec3d.
The triangle attribute defines triangles between the points of each mesh using indices to the vertex lists.
The ‘outer_hull’ parameter can optionally be set to a reference of a mesh element of the project. This mesh will be copied and used as an outer hull for the defect element. Alternatively , ‘outer_hull_vertices’ and ‘outer_hull_triangles’ can be given as explicit outer hull mesh definition.
+
+
+result = {
+ 'vertices' : [ np . array (( x , y , z ), ( x , y , z ), ... ), np . array (( x , y , z ), ( x , y , z ), ... ), ... ],
+ 'triangles' : [ np . array (( v0 , v1 , v2 ), ( v0 , v1 , v2 ), ... ), np . array (( v0 , v1 , v2 ), ( v0 , v1 , v2 ), ... ), ... ],
+ 'outer_hull' : gom . Reference # optional OR
+ 'outer_hull_vertices' : np . array (( x , y , z ), ... ), 'outer_hull_triangles' : np . array (( v0 , v1 , v2 ), ... )
+}
+
+
+
+
+2D Volume Defects
+
+Element Type:
+2D volume defects element of curves
needed for the P201 package
+
+Result:
+Requires a list/array of lists/arrays of Vec3ds.
A list of points represents the polygon (curve) of one 2d volume defect. The list of lists of points represents all 2d volume defects that shall be included in the element.
+
+
+result = {
+ 'curves' : [ [ gom . Vec3d , gom . Vec3d , ... ],
+ [ gom . Vec3d , gom . Vec3d , ... ],
+ ... ]
+}
+
+
+
+
+Volume
+
+Element Type:
+New volume data
+
+Result:
+Accepts a numpy array with voxel data and a transformation.
The numpy array’s shape denotes the resulting volume shape. The ‘dtype’ can be one of (UINT16, BYTE, INT16, INT16, INT32, UINT32, FLOAT, DOUBLE).
The transformation can be a gom.Mat4x4 (affine transformation) or a gom.Vec3d (scaling along x/y/z axis only)
+
+
+result = { 'voxel_data' : np . array (), 'transformation' : ( gom . Mat4x4 | gom . Vec3d ) }
+
+
+
+
+Volume material map
+
+Element Type:
+Attach material labels to volume element
+
+Result:
+Creates a new volume element copy with attached material labels.
First parameter is a numpy array of type UINT8 of the size of the volume. The values are the material index per voxel. Background has Index 0.
The second parameter is a list of floating point grey values that are the representative grey values of the background and the materials.
The third parameter is a reference to the volume element, to which material labels should be attached.
+
+
+result = {
+ 'material_labels_draft' : np . array (),
+ 'material_grey_values_draft' : [ background , material 1 , ... ],
+ 'volume_reference_draft' : Reference
+}
+
+
+
+
+Volume Section
+
+Element Type:
+Volume Section
+
+Result:
+Accepts a numpy array with pixel data and a transformation.
The numpy array’s shape denotes the resulting volume section shape. The ‘dtype’ must be numpy.float32
.
The transformation is a gom.Mat4x4 (affine transformation)
+
+
+result = { 'pixel_data' : np . array (), 'transformation' : gom . Mat4x4 }
+
+
+
+
+
+Scripted checks - Return values
+Scripted Checks extend the concept of scripted actual elements to be able to calculate custom inspections based on python scripts.
+
+Supported Element Types
+The following element types are currently supported:
+
+
+Scalar
+
+Element Type:
+Scalar check: A single scalar value is assigned to an element
+
+Result:
+A nominal and actual double value are set, and a reference to element which was checked.
+
+
+result = { "nominal" : double , "actual" : double , "reference" : gom . Reference }
+
+
+
+
+Scalar Surface
+
+Element Type:
+Surface check: A scalar deviation value is assigned to each point of a mesh.
+
+Result:
+A list of deviation values for each point of a mesh. The mesh is also set as “reference” parameter.
The number of points of the mesh and the “deviation_values” array must match.
+
+
+result = { "deviation_values" : np . array ( dtype = np . float32 ), "reference" : gom . Reference }
+
+
+
+
+Scalar Curve
+
+Element Type:
+Curve check: A scalar deviation value is assigned to each point on a curve.
+
+Result:
+A list of nominal and actual values for each point of a curve. The deviation values are calculated automatically as a difference between both.
The curve is also set as “reference” parameter.
The number of points of the curve and the value arrays must match.
+
+
+result = { "actual_values" : double , 'nominal_values' : double , "reference" : gom . Reference }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/data_interfaces.html b/2022-new-headings-intros/python_examples/data_interfaces.html
new file mode 100644
index 0000000..0981cbe
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/data_interfaces.html
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+ data_interfaces — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+data_interfaces
+This is a collection of examples to access element properties and data.
+
+
Examples of this category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/data_interfaces/check_results_data_array.html b/2022-new-headings-intros/python_examples/data_interfaces/check_results_data_array.html
new file mode 100644
index 0000000..978216a
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/data_interfaces/check_results_data_array.html
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+ check_results_data_array — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+check_results_data_array
+
+
+Short description
+This example demonstrates two ways of accessing result data from checks using the element properties and data interfaces.
+
+
+Highlights
+Basically, if you have obtained an gom.Reference
element reference, e.g. by selecting an element by name (gom.app.project.inspection['Surface comparison 1']
), you can access the results of the check:
+
+By evaluating an expression
+single_scalar_value = element.get ('result_dimension[0].deviation')
+
+
+
+
+By the data interface of this element using the .data
token
+scalars = np.array (element.data.result_dimension.deviation)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/data_interfaces/volume_section_image_data.html b/2022-new-headings-intros/python_examples/data_interfaces/volume_section_image_data.html
new file mode 100644
index 0000000..ee30615
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/data_interfaces/volume_section_image_data.html
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+ volume_section_image_data — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+volume_section_image_data
+
+
+Short description
+This example demonstrates how to access the image data of a volume section.
+
+
+Highlights
+There are two output formats available.
+
+The raw image data
+This is essentially the same as getting a slice of the volume. Data type and value are the same as the volume the section belongs to.
+raw_image = np.array (element.data.raw)
+
+The rendered image
+This yields the the image as rendered for the 3D view.
+rgb_image = np.array (element.data.rgb)
+This image is in RGBA format. Therefore you’ll get the array shape of (1, 305, 295, 4). 1 project stage, 305x295 pixels, and 4 pixel values (RGBA).
+You can use this image also for processing with other libraries. The screenshot above shows the image opened with Pillow
.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/dialog_widgets.html b/2022-new-headings-intros/python_examples/dialog_widgets.html
new file mode 100644
index 0000000..2d524bb
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/dialog_widgets.html
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+ dialog_widgets — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/dialog_widgets/dropdown_widget.html b/2022-new-headings-intros/python_examples/dialog_widgets/dropdown_widget.html
new file mode 100644
index 0000000..a6817fb
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/dialog_widgets/dropdown_widget.html
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+ dropdown_widget_dynamic — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.html b/2022-new-headings-intros/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.html
new file mode 100644
index 0000000..6ca9276
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.html
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+ explorer_selected_elements_in_dialog — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+explorer_selected_elements_in_dialog
+
+
+Short description
+Sometimes you might want to get the list of elements currently selected in the element explorer. This example shows how to do so, e.g. in a script dialog.
+
+
+Highlights
+You can get all elements of a certain category by using a gom.ElementSelection
. Then you can iterate over this list to check which ones are currently selected.
+actual_elements = gom . ElementSelection ({ 'category' : [ 'key' , 'elements' , 'part' , gom . app . project . parts [ 'Part' ], 'explorer_category' , 'actual' ]})
+selected_actuals = [ element . name for element in actual_elements if element . is_selected ]
+
+
+
+
Hint
+
As the gom.ElementSelection
s get pretty lengthy, it is advised to generate these expressions using the “Script Object” explorer (F2
). Select a category of elements and directly click “OK” to insert a corresponding selection expression.
+
+
+In the example, an exemplary selection of elements is also triggered by the script:
+example_selection = [ gom . app . project . actual_elements [ 'Plane 1' ], gom . app . project . actual_elements [ 'Plane X +0.00 mm' ]]
+gom . script . explorer . apply_selection ( selection = example_selection )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/dialog_widgets/unit_dialog_event_handler.html b/2022-new-headings-intros/python_examples/dialog_widgets/unit_dialog_event_handler.html
new file mode 100644
index 0000000..bb2ae1e
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/dialog_widgets/unit_dialog_event_handler.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+ unit_dialog_event_handler — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+unit_dialog_event_handler
+
+
+Short description
+This basic example demonstrates how to use an event handler on a script dialog to set the unit to multiple widgets.
+
+
+Highlights
+After creating a dialog with gom.script.sys.create_user_defined_dialog
, you can set an event handler to this dialog. In this simple case, the unit
property of a decimal input widget and a tolerance widget are set according to what the user selected in the DIALOG.unit
widget:
+if widget == DIALOG . unit :
+ DIALOG . input . unit = DIALOG . unit . value
+ DIALOG . tolerances . unit = DIALOG . unit . value
+
+
+Another interesting part of this example is the corresponding test . In addon_tests/test_dialog_widgets_unit_dialog
is shown how a very basic testing of the event_handler can be realized:
+DIALOG = example . setup_dialog ()
+# Generating some events to test the event_handler
+unit_widget = DIALOG . unit
+unit_widget . value = "FORCE"
+
+# Test if the event_handler correctly links widget values
+DIALOG . handler ( unit_widget )
+assert ( DIALOG . input . unit == "FORCE" )
+assert ( DIALOG . tolerances . unit == "FORCE" )
+
+
+This usage of the DIALOG.handler
function mimics the user-interaction of changing the value of the unit
widget manually to "FORCE"
.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/dialog_widgets/widget_visibility.html b/2022-new-headings-intros/python_examples/dialog_widgets/widget_visibility.html
new file mode 100644
index 0000000..22398a5
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/dialog_widgets/widget_visibility.html
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+ widget_visibility — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/index.html b/2022-new-headings-intros/python_examples/index.html
new file mode 100644
index 0000000..4613907
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/index.html
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+ Added metadata: — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+
+
+Overview
+Welcome to the GOM Inspect Python API Examples. Here you can find the documentation of the examples which are provided by the
+Python API Examples
Add-On. You can reuse and adapt these code examples to your specific use case and learn the best-practices we recommend.
+
+How the examples are structured
+You will find example scripts in a corresponding category folder, e.g. data_interfaces
, dialog_widgets
, etc.
+The folders of the example scripts correspond to the chapters of this documentation.
+Many of the examples have the following structure:
+
+def function1 ():
+ < example code1 >
+
+def function2 ():
+ # -------------------------------------------------------------------------
+ < example code2 >
+ # -------------------------------------------------------------------------
+
+[ ... ]
+
+if __name__ == '__main__' :
+ [ ... ]
+ something = function1 ()
+ something2 = function2 ()
+ [ ... ]
+
+
+
+The most important spots of the example are marked with # ------
comments in the code.
+Overall, this structure seems to be a little bit too complex for simple examples.
+The same result could be achieved by directly writing the <example code>
in the script without separating it into functions.
+However, this has a reason . The functions function1
and function2
can be tested from another test script.
+You are highly encouraged to use this modular approach as well, to keep your code testable and reusable.
+If you are interested in testing add-ons (which you should be), learn more in our Testing Add-Ons How-To .
+
+
+Example projects
+Most of the example scripts rely on a certain project file to be loaded. The add-on already contains these projects, and some examples load them automatically when it is possible (E.g. in the if __name__ == '__main__'
block).
+Sometimes it is necessary to load projects manually. You can do this easily using the setup_project.py
script.
+The following project files are included:
+
+
+Project name
+Description
+
+
+
+gom_part_test_project
+Simple optically measured part with a CAD, mesh and some basic inspection
+
+volume_test_part
+A small test volume for CT related inspections
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/misc.html b/2022-new-headings-intros/python_examples/misc.html
new file mode 100644
index 0000000..76c268d
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/misc.html
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+ misc — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+misc
+This is a collection of examples that don’t fit in any other category.
+
+
Examples of this category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/misc/dialog_reopen_example.html b/2022-new-headings-intros/python_examples/misc/dialog_reopen_example.html
new file mode 100644
index 0000000..ca6cddb
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/misc/dialog_reopen_example.html
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+ dialog_reopen_example — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+dialog_reopen_example
+
+
+Short description
+This examples demonstrates, how a dialog can be closed from its own handler, just to be opened again.
+
+
Warning
+
There are very rare occasions, where you should need this. Use this approach only, if you know what you are doing.
+
+
+
+Highlights
+The approach consists of two steps. First, declare a guard variable that yields True
if the dialog should be reopened.
+[ ... ]
+reopen = True
+while reopen :
+ gom . script . sys . show_user_defined_dialog ( dialog = DIALOG )
+
+
+The example dialog contains a button to close/reopen the dialog (see top image). One of the few use cases could be, that you need to adapt the filter
property of an Selection element
widget after some dialog interaction, which can only be done when the dialog is closed.
+To achieve this, the dialog event handler is used:
+def dialog_event_handler ( widget ):
+ global reopen
+ if str ( widget ) == "initialize" :
+ reopen = False
+ if widget == DIALOG . button :
+ gom . script . sys . close_user_defined_dialog ( dialog = DIALOG )
+ gom . script . sys . delay_script ( time = 1 ) # Do stuff while dialog is closed
+ reopen = True
+
+
+
+
Warning
+
Never reopen the dialog directly from its own handler to prevent getting undefined behaviour.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/script_icons.html b/2022-new-headings-intros/python_examples/script_icons.html
new file mode 100644
index 0000000..f40378b
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/script_icons.html
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+ script_icons — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+script_icons
+This is a collection of examples regarding script icons.
+
+
Examples of this category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/script_icons/script_icon_from_file.html b/2022-new-headings-intros/python_examples/script_icons/script_icon_from_file.html
new file mode 100644
index 0000000..fc46f41
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/script_icons/script_icon_from_file.html
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+ script_icon_from_file — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+script_icon_from_file
+
+
+Short description
+This is a small example to show how an icon can be set to a script, whereas the icon itself resides in the add-on as a resource.
+
+
+
+Highlights
+Normally, the icon can be set using the “Script properties” dialog accessible by right-click in the Script Editor of the GOM Software.
+However, using VS Code or another text editor, the corresponding .metainfo
files of the scripts can be edited directly. If you have icon files within your add-on, you can directly enter the relative path to the icon in the "icon"
property.
+
+If you use this approach, and follow our icon guidelines , the icons get inverted in dark themes automatically.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/script_resources.html b/2022-new-headings-intros/python_examples/script_resources.html
new file mode 100644
index 0000000..431a289
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/script_resources.html
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+ script_resources — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+script_resources
+This is a collection of examples demonstrating how to use binary data (resources) in your scripts.
+
+
Examples of this category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/script_resources/resource_api_example.html b/2022-new-headings-intros/python_examples/script_resources/resource_api_example.html
new file mode 100644
index 0000000..5f2d5b4
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/script_resources/resource_api_example.html
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+ resource_api_example — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+resource_api_example
+
+
+Short description
+A simple example showing the usage of script resources.
+
+
+Highlights
+The example shows how to list available resources:
+
+Then, depending on whether a resource is found (by name), this resource is read or created with the content Hello World
.
+res = gom . Resource ( "test_resource.txt" )
+ if ( res . exists ()):
+ print ( "Resource found with content: " , get_resource_content ( res ))
+ else :
+ string_bytes = b "Hello World"
+ create_resource_with_content ( "test_resource.txt" , string_bytes )
+ print ( "Resource created with content:" , string_bytes )
+
+
+Output:
+> Resource found with content : b 'Hello World'
+
+
+For details on how to read and write resource data, see the related documentation below.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_actuals.html b/2022-new-headings-intros/python_examples/scripted_actuals.html
new file mode 100644
index 0000000..82a40c0
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_actuals.html
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+ scripted_actuals — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+scripted_actuals
+This is a collection of examples of scripted actual elements.
+
+
+
Examples of this category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_actuals/offset_point_simple.html b/2022-new-headings-intros/python_examples/scripted_actuals/offset_point_simple.html
new file mode 100644
index 0000000..e5ca7cf
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_actuals/offset_point_simple.html
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+ offset_point_simple — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+offset_point_simple
+
+
+Short description
+
+
Note
+
This is a basic example meant to introduce you to the concept of scripted actual elements. Therefore, head over to the How-to: Scripted actuals for the documentation of this example.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_actuals/offset_point_v2.html b/2022-new-headings-intros/python_examples/scripted_actuals/offset_point_v2.html
new file mode 100644
index 0000000..3159534
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_actuals/offset_point_v2.html
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+ offset_point_v2 — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+offset_point_v2
+
+
+Short description
+This example is an extension of the offset_point_simple
example, which has been discussed in the general How-to: Scripted actuals .
+It shows how to enhance user experience using preview calculation and error handling.
+
+
+Highlights
+
+Preview calculation
+From many of the built-in commands of the GOM Software, you know the calculation of a preview element during the creation dialog. This means, you can already see the calculation result in the 3D view, while tweaking some parameters in the dialog.
+To achieve this behaviour in a scripted element, you need to set up an event handler for the dialog (see also: How-to: Using script dialogs ).
+ 1 def dialog_event_handler ( widget ):
+ 2 # No treatment of system events
+ 3 if str ( widget ) == 'system' :
+ 4 return
+ 5 # If preview calculation returned with error
+ 6 if str ( widget ) == 'error' :
+ 7 DIALOG . control . status = context . error
+ 8 return
+ 9 # If preview calculation was successful
+10 if str ( widget ) == 'calculated' :
+11 DIALOG . control . status = ''
+12 DIALOG . control . ok . enabled = True
+13 return
+14
+15 # All other changes in the dialog --> calculate preview
+16 params [ 'x' ] = DIALOG . i_x . value ;
+17 params [ 'y' ] = DIALOG . i_y . value ;
+18 params [ 'z' ] = DIALOG . i_z . value ;
+19 params [ 'base' ] = DIALOG . point . value
+20 context . name = DIALOG . name . value
+21 DIALOG . control . ok . enabled = False
+22 context . calc ( params = params , dialog = DIALOG )
+23
+24 DIALOG . handler = dialog_event_handler
+
+
+The event handler function is to be defined taking one argument. This argument will be a handle to the cause (the event) triggering the handler. This can be a string message or a handle to a specific widget of the dialog. We’ll come back to this in a second
+The handler function shown above basically reads the current set of parameters from the DIALOG
to the params
array (lines 16-19). In this case, the offset values and base point. Then, the preview calculation is started using the special functional context.calc
, which is a function handle taking the set of params
and a reference to the dialog triggering the preview (line 22).
+
+
Attention
+
Only call context.calc(...)
from a script dialog’s event handler function, NOT from the scripted element’s dialog
function itself.
+
+The handler is applied to the dialog in the dialog
function of the scripted element, just before the dialog is shown to the user (line 23).
+
+
+Status and error handling
+Using the dialog’s event handler, we can also make the dialog responsive to successful or failed preview calculations. Therefore, the DIALOG.control.ok.enabled
can be used to control the enabledness of the dialog’s OK button.
+In line 21, the OK button is disabled before preview calculation is started.
+Furthermore, the scripted element framework provides two special event triggers: error
and calculated
, which are sent on failing/success of the calculation
function to the dialog referenced in the context.calc
call.
+In this case, we set a potential error message of a failed calcualtion to the dialogs error indicator (line 7), or enable the OK button and reset the error indicator in case of a successful calculation (lines 11-12).
+
+
+Stageful calculation
and error handling
+Above, we discussed changes applied to the scripted element’s dialog
function. Now, let’s take a look at the calculation
function.
+ 1 def calculation ( context , params ):
+ 2 valid_results = False
+ 3 # Calculating all available stages
+ 4 for stage in context . stages :
+ 5 # Access element properties with error handling
+ 6 try :
+ 7 base = params [ 'base' ] . in_stage [ stage ] . center_coordinate
+ 8 context . result [ stage ] = ( base . x + params [ 'x' ], base . y + params [ 'y' ], base . z + params [ 'z' ])
+ 9 context . data [ stage ] = { "ude_mykey" : 123456 }
+10 except Exception as error :
+11 context . error [ stage ] = str ( error )
+12 else :
+13 valid_results = True
+14 return valid_results
+
+
+The first noticeable difference to the offset_point_simple example is the calculation over all stages of the project, whose indices can be obtained using context.stages
(line 4).
+
+
See also
+
If you are not familiar with the concept of stages , get an impression in our Starter Training .
+
+Second, the access of element properties is also respecting the current stage using the .in_stage
mechanism (line 7).
+Third, you can see that the calculation is surrounded by a try/except
block that catches potential errors and sets arising error messages to context.error
. This examples catches all exceptions in a very basic way. In a real-world application, you should distinguish several types of exceptions you’d expect and set meaningful error messages. The context.error
message is then handled in the dialog as discussed above (see Status and error handling ).
+
+
+Storing generic element data
+You can observe an assignment to the context.data
member (line 9). If you assign a dictionary (map) to this data structure, you can save user-defined tokens to the scripted element. These are key/value pairs that can hold generic information you might to retrieve in consecutive scripts or checks that reference the created scripted element.
+
+After element creation of such an offset point with name “Offset point 1”, you could access this data again like:
+import gom
+
+print ( gom . app . project . actual_elements [ 'Offset point 1' ] . ude_mykey )
+
+
+Output:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_actuals/scripted_element_progress.html b/2022-new-headings-intros/python_examples/scripted_actuals/scripted_element_progress.html
new file mode 100644
index 0000000..d67398e
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_actuals/scripted_element_progress.html
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+ scripted_element_progress — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+scripted_element_progress
+
+
+
+Short description
+This examples demonstrates how to show progress information to the user while calcualting a scripted element.
+
+
+Highlights
+The scripted element itself is not of interest here, as it is rather meaningless: a point that will always be created at (1,0,0) .
+To showcase the display of calculation progress, a loop with 100 steps containing a sleep
call to simulate computation are performed in the calculation
function:
+def calculation ( context , params ):
+ context . progress_stages_total = limit
+ for i in range ( limit ):
+ context . progress_stages_computing = i
+ time . sleep ( 0.1 )
+
+ # [...]
+
+
+To indicate progress, you need to set context.progress_stages_total
to the amount of steps you expect to compute. This can but not has to be the number of stages in trend projects. You can also set any arbitrary number. As soon as you set context.progress_stages_computing
, the progress will be indicated in the bottom are of the application (see top screenshot).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_actuals/trimesh_deform_mesh.html b/2022-new-headings-intros/python_examples/scripted_actuals/trimesh_deform_mesh.html
new file mode 100644
index 0000000..2d829bb
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_actuals/trimesh_deform_mesh.html
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+ trimesh_deform_mesh — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_checks.html b/2022-new-headings-intros/python_examples/scripted_checks.html
new file mode 100644
index 0000000..8b7498a
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_checks.html
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+ scripted_checks — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+scripted_checks
+This is a collection of examples of scripted check elements.
+
+
+
Examples of this category
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_checks/scripted_curve_check.html b/2022-new-headings-intros/python_examples/scripted_checks/scripted_curve_check.html
new file mode 100644
index 0000000..b5bfdc6
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_checks/scripted_curve_check.html
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+ scripted_curve_check — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+scripted_curve_check
+
+
+Short description
+This example demonstrates how to create a scalar curve check by a script. Also, the usage of custom coordinate systems in scripted checks is shown.
+
+
+Highlights
+First of all, we need to check if the element selected by the user by the DIALOG.slct_element
widget is suitable for being checked with a curve check. You can implement your own filter for that, but you can also use the API convenience function for that purpose, which only allow “curve-like” elements:
+DIALOG . slct_element . filter = gom . api . scripted_checks_util . is_curve_checkable
+
+
+To allow calculation in a custom coordinate system (one that exists in the project), a second Selection element
widget is inserted in the dialog, here named cs
. In the dialog
function, its value is saved to the element parameters. In case of no selected coordinate system, the viewing coordinate system is used.
+def dialog ( context , params ):
+ # [...]
+ params [ 'coordinate_system' ] = DIALOG . cs . value
+ if params [ 'coordinate_system' ] is None :
+ params [ 'coordinate_system' ] = gom . app . project . view_csys
+
+
+Having this reference to a coordinate system, we can use the API function scripted_checks_util.get_cs_transformation_4x4
to get a 4x4 matrix for computation.
+During the computation for all stages, we then apply this (affine) transformation using the dot product.
+def calculation ( context , params ):
+ # [...]
+ trafo_matrices = np . array ( gom . api . scripted_checks_util . get_cs_transformation_4x4 ( params [ "coordinate_system" ]))
+ # [...]
+
+ # Apply coordinate transformation to all vertices if necessary
+ if trafo_matrices is not None :
+ stage_trafo = trafo_matrices [ s ]
+ stage_vertices = ( np . dot ( stage_trafo [ 0 : 3 , 0 : 3 ], stage_vertices . T ) + stage_trafo [: 3 , 3 :]) . T
+
+ # The result of this stage to be filled
+ actual_result = np . zeros ( stage_vertices . shape [ 0 ])
+ nominal_result = np . random . rand ( stage_vertices . shape [ 0 ])
+
+ for i in range ( stage_vertices . shape [ 0 ]):
+ point = gom . Vec3d ( stage_vertices [ i ][ 0 ], stage_vertices [ i ][ 1 ], stage_vertices [ i ][ 2 ])
+
+ # ----------------------------------------------------
+ # --- insert your calculation for each vertex here ---
+ # ----------------------------------------------------
+ actual_result [ i ] = point . y
+ # ----------------------------------------------------
+
+
+Finally, the result is to be set. For each point of the referenced curve, a nominal and actual value is needed. Therefore, the result takes the following form, where actual_result
and nominal_result
are vectors with the same length (number of curve points).
+result = { "actual_values" : actual_result , "reference" : element , 'nominal_values' : nominal_result }
+
+
+In this case, the result is just the y
coordinate of each point to easily see the correctness of the results including a given transformation.
+Using the example project gom_part_test_project
and the viewing coordinate system, you get the screenshot shown on top. However, if you select the coordinate system Cylinder 1|Plane 1|Origin
, you can see the transformation in effect:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_checks/scripted_scalar_check.html b/2022-new-headings-intros/python_examples/scripted_checks/scripted_scalar_check.html
new file mode 100644
index 0000000..a659633
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_checks/scripted_scalar_check.html
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+ scripted_scalar_check — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+scripted_scalar_check
+
+
+Short description
+This example shows how to create a scalar check by script. A scalar check is the most basic check, as it assigns a scalar value to an element. Nearly all elements you can find in the software can be checked like this.
+
+
Note
+
A scripted check has a lot in common with the scripted actual elements. Therefore, the identical mechanisms and concepts will not be explained here. See How-to: Scripted actuals if you are not already familiar with the concept of scripted elements.
+
+
+
+Highlights
+First of all, we need to check if the element selected by the user by the DIALOG.slct_element
widget is suitable for being checked with a scalar check. You can implement your own filter for that, but you can also use the API convenience function for that purpose:
+DIALOG . slct_element . filter = gom . api . scripted_checks_util . is_scalar_checkable
+
+
+As you can assign a scalar value to all common element types, this filter allows all element types available in the element explorer .
+Furthermore, as described in the How-to: Scripted checks , the special parameters for scripted checks are also assigned in the dialog
function. For ease of use, the respective dialog widgets are used, so we only need to assign the widgets’ values to the parameters array.
+def dialog ( context , params ):
+ # [...]
+ params [ 'tolerance' ] = DIALOG . tolerances . value
+ params [ 'unit' ] = DIALOG . unit . value
+ params [ 'abbreviation' ] = 'ScrSca'
+
+
+In the calculation function, there is not much calculation but just an exemplary assignment of scalar values to the result. For the scripted Scalar check
, the result dictionary needs to contain "nominal"
and "actual"
members, as well as a reference to the element which is checked.
+def calculation ( context , params ):
+ # [...]
+ for s in context . stages :
+ actual_result = 1.0
+ nominal_result = 2.0
+
+ context . result [ s ] = { "nominal" : nominal_result ,
+ "actual" : actual_result ,
+ "reference" : element }
+ return True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/python_examples/scripted_checks/scripted_surface_check.html b/2022-new-headings-intros/python_examples/scripted_checks/scripted_surface_check.html
new file mode 100644
index 0000000..e188d84
--- /dev/null
+++ b/2022-new-headings-intros/python_examples/scripted_checks/scripted_surface_check.html
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+ scripted_surface_check — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+scripted_surface_check
+
+
+Short description
+This example demonstrates how to create a scalar surface check by a script. Also, the usage of custom coordinate systems and element preview in scripted checks is shown.
+
+
+Highlights
+First of all, we need to check if the element selected by the user by the DIALOG.slct_element
widget is suitable for being checked with a surface check. You can implement your own filter for that, but you can also use the API convenience function for that purpose, which only allow “mesh-like” elements:
+DIALOG . slct_element . filter = gom . api . scripted_checks_util . is_surface_checkable
+
+
+The usage of custom coordinate systems is the same as described in the scripted_curve_check example.
+Finally, the result is to be set. For each point of the referenced mesh, a deviation value is needed. Therefore, the result takes the following form, where deviation_result
is a vector with length equal to number of mesh points.
+result = { "deviation_values" : deviation_result , "reference" : element }
+
+
+As in the scripted_curve_check example, the result for each point is just the respective y
coordinate to easily see the correctness of the results including a given transformation.
+Using the example project gom_part_test_project
and the viewing coordinate system, you get the screenshot shown on top. However, if you select the coordinate system Cylinder 1|Plane 1|Origin
, you can see the transformation in effect:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/search.html b/2022-new-headings-intros/search.html
new file mode 100644
index 0000000..d3ad962
--- /dev/null
+++ b/2022-new-headings-intros/search.html
@@ -0,0 +1,151 @@
+
+
+
+
+
+ Search — Add-On Documentation documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Add-On Documentation
+
+
+
+
+
+
+
+
+
+
+
+ Please activate JavaScript to enable the search functionality.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2022-new-headings-intros/searchindex.js b/2022-new-headings-intros/searchindex.js
new file mode 100644
index 0000000..0a4f96e
--- /dev/null
+++ b/2022-new-headings-intros/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({"docnames": ["howtos/adding_workspaces_to_packages/adding_workspaces_to_packages", "howtos/environments_for_python_scripts/environments_for_python_scripts", "howtos/localization/localization", "howtos/python_api_introduction/creating_wizard_dialogs", "howtos/python_api_introduction/python_api_introduction", "howtos/python_api_introduction/script_dialogs_introduction", "howtos/python_api_introduction/using_script_resources", "howtos/scripted_elements/scripted_actuals", "howtos/scripted_elements/scripted_checks", "howtos/scripted_elements/scripted_elements_introduction", "howtos/scripted_elements/scripted_elements_toc", "howtos/scripted_elements/tokens_on_scripted_elements", "howtos/testing_addons/testing_addons", "howtos/using_vscode_editor/using_vscode_editor", "index", "python_api/python_api", "python_api/resource_api", "python_api/scripted_elements_api", "python_examples/data_interfaces", "python_examples/data_interfaces/check_results_data_array", "python_examples/data_interfaces/volume_section_image_data", "python_examples/dialog_widgets", "python_examples/dialog_widgets/dropdown_widget", "python_examples/dialog_widgets/explorer_selected_elements_in_dialog", "python_examples/dialog_widgets/unit_dialog_event_handler", "python_examples/dialog_widgets/widget_visibility", "python_examples/index", "python_examples/misc", "python_examples/misc/dialog_reopen_example", "python_examples/script_icons", "python_examples/script_icons/script_icon_from_file", "python_examples/script_resources", "python_examples/script_resources/resource_api_example", "python_examples/scripted_actuals", "python_examples/scripted_actuals/offset_point_simple", "python_examples/scripted_actuals/offset_point_v2", "python_examples/scripted_actuals/scripted_element_progress", "python_examples/scripted_actuals/trimesh_deform_mesh", "python_examples/scripted_checks", "python_examples/scripted_checks/scripted_curve_check", "python_examples/scripted_checks/scripted_scalar_check", "python_examples/scripted_checks/scripted_surface_check"], "filenames": ["howtos/adding_workspaces_to_packages/adding_workspaces_to_packages.md", "howtos/environments_for_python_scripts/environments_for_python_scripts.md", "howtos/localization/localization.md", "howtos/python_api_introduction/creating_wizard_dialogs.md", "howtos/python_api_introduction/python_api_introduction.md", "howtos/python_api_introduction/script_dialogs_introduction.md", "howtos/python_api_introduction/using_script_resources.md", "howtos/scripted_elements/scripted_actuals.md", "howtos/scripted_elements/scripted_checks.md", "howtos/scripted_elements/scripted_elements_introduction.md", "howtos/scripted_elements/scripted_elements_toc.md", "howtos/scripted_elements/tokens_on_scripted_elements.md", "howtos/testing_addons/testing_addons.md", "howtos/using_vscode_editor/using_vscode_editor.md", "index.md", "python_api/python_api.md", "python_api/resource_api.md", "python_api/scripted_elements_api.md", "python_examples/data_interfaces.md", "python_examples/data_interfaces/check_results_data_array.md", "python_examples/data_interfaces/volume_section_image_data.md", "python_examples/dialog_widgets.md", "python_examples/dialog_widgets/dropdown_widget.md", "python_examples/dialog_widgets/explorer_selected_elements_in_dialog.md", "python_examples/dialog_widgets/unit_dialog_event_handler.md", "python_examples/dialog_widgets/widget_visibility.md", "python_examples/index.md", "python_examples/misc.md", "python_examples/misc/dialog_reopen_example.md", "python_examples/script_icons.md", "python_examples/script_icons/script_icon_from_file.md", "python_examples/script_resources.md", "python_examples/script_resources/resource_api_example.md", "python_examples/scripted_actuals.md", "python_examples/scripted_actuals/offset_point_simple.md", "python_examples/scripted_actuals/offset_point_v2.md", "python_examples/scripted_actuals/scripted_element_progress.md", "python_examples/scripted_actuals/trimesh_deform_mesh.md", "python_examples/scripted_checks.md", "python_examples/scripted_checks/scripted_curve_check.md", "python_examples/scripted_checks/scripted_scalar_check.md", "python_examples/scripted_checks/scripted_surface_check.md"], "titles": ["Adding workspaces to add-ons", "Environments for python scripts", "Localization of packages", "Creating wizard dialogs", "GOM Inspect Python API introduction", "Using script dialogs", "Using script resources", "Scripted actuals", "Scripted checks", "Introduction", "Scripted elements", "Tokens on scripted elements", "Testing add-ons", "Using Visual Studio Code as an add-on editor", "GOM Inspect Add-On Development Documentation", "GOM Inspect Python API documentation", "gom.Resource API", "Scripted elements API", "data_interfaces", "check_results_data_array", "volume_section_image_data", "dialog_widgets", "dropdown_widget_dynamic", "explorer_selected_elements_in_dialog", "unit_dialog_event_handler", "widget_visibility", "Added metadata:", "misc", "dialog_reopen_example", "script_icons", "script_icon_from_file", "script_resources", "resource_api_example", "scripted_actuals", "offset_point_simple", "offset_point_v2", "scripted_element_progress", "trimesh_deform_mesh", "scripted_checks", "scripted_curve_check", "scripted_scalar_check", "scripted_surface_check"], "terms": {"abstract": 0, "an": [0, 3, 5, 7, 8, 9, 11, 12, 14, 15, 16, 17, 19, 23, 24, 28, 30, 33, 35, 37, 38, 40], "includ": [0, 4, 6, 11, 12, 13, 14, 16, 17, 26, 39, 41], "new": [0, 1, 3, 4, 5, 11, 12, 14, 15, 16, 17], "inspect": [0, 2, 5, 7, 8, 12, 13, 17, 19], "report": [0, 5], "ar": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 20, 23, 24, 28, 35, 36, 37, 39, 40], "exampl": [0, 2, 4, 5, 6, 8, 11, 12, 15, 16, 19, 20, 22, 23, 24, 25, 28, 30, 32, 34, 35, 36, 37, 39, 40, 41], "although": [0, 5, 7], "ui": 0, "base": [0, 2, 4, 5, 7, 13, 17, 35], "editor": [0, 3, 4, 5, 6, 7, 9, 11, 12, 14, 15, 30, 37], "yet": [0, 5, 13, 17], "possibl": [0, 2, 3, 4, 5, 11, 13, 17, 26], "creat": [0, 6, 7, 8, 9, 10, 11, 12, 14, 17, 21, 22, 24, 32, 35, 36, 37, 39, 40, 41], "one": [0, 1, 3, 4, 5, 6, 9, 11, 15, 17, 35, 39], "nevertheless": [0, 11], "some": [0, 4, 5, 7, 8, 11, 13, 24, 26, 28, 35, 37], "manual": [0, 2, 5, 12, 24, 26], "work": [0, 4, 5, 9, 11, 12, 13, 19], "each": [0, 1, 2, 3, 4, 5, 8, 9, 11, 15, 17, 37, 39, 41], "gom": [0, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 17, 19, 23, 24, 28, 30, 32, 35, 37, 39, 40, 41], "applic": [0, 4, 5, 7, 9, 14, 17, 35, 36], "doe": [0, 2, 4, 13], "have": [0, 2, 3, 4, 5, 7, 9, 11, 13, 17, 19, 22, 26, 30, 39], "list": [0, 1, 2, 4, 11, 15, 16, 17, 22, 23, 32], "avail": [0, 1, 2, 5, 9, 13, 14, 17, 20, 32, 35, 40], "left": [0, 2, 3, 4, 5, 15], "side": [0, 5, 16], "which": [0, 1, 2, 3, 4, 5, 7, 9, 11, 12, 13, 15, 17, 23, 26, 28, 35, 37, 39, 40, 41], "depend": [0, 5, 7, 9, 13, 14, 32], "licens": 0, "instal": [0, 4], "A": [0, 3, 4, 5, 6, 7, 9, 13, 16, 17, 26, 32, 40], "bundl": 0, "command": [0, 4, 7, 9, 12, 15, 17, 35], "etc": [0, 6, 9, 13, 26], "themat": 0, "If": [0, 1, 2, 3, 4, 5, 8, 11, 13, 14, 15, 17, 26, 30, 35], "select": [0, 7, 8, 9, 13, 19, 22, 23, 24, 28, 37, 39, 40, 41], "view": [0, 5, 8, 13, 20, 35, 39, 41], "menu": [0, 1, 2, 4, 6, 9, 13, 22], "abov": [0, 2, 3, 4, 5, 11, 13, 20, 35], "show": [0, 3, 4, 7, 9, 12, 13, 20, 22, 23, 25, 30, 32, 35, 36, 40], "everyth": 0, "user": [0, 1, 3, 5, 7, 8, 9, 12, 17, 21, 24, 26, 35, 36, 37, 39, 40, 41], "need": [0, 4, 5, 6, 7, 8, 9, 12, 13, 17, 28, 35, 36, 39, 40, 41], "part": [0, 5, 7, 9, 23, 24, 26], "while": [0, 3, 13, 28, 35, 36], "provid": [0, 2, 5, 8, 9, 15, 17, 26, 35], "tool": [0, 1, 5], "page": [0, 4, 5, 11], "creation": [0, 4, 7, 17, 35], "its": [0, 2, 3, 4, 5, 28, 39], "own": [0, 4, 28, 39, 40, 41], "The": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 25, 26, 28, 32, 35, 36, 37, 39, 41], "blade": [0, 14], "cmm": 0, "airfoil": 0, "data": [0, 3, 5, 6, 9, 11, 15, 16, 18, 19, 20, 26, 31, 32, 37], "prepar": [0, 5, 13], "featur": [0, 13], "default": [0, 3, 4, 5, 17, 37], "becaus": [0, 5, 12], "rather": [0, 14, 36], "special": [0, 4, 5, 9, 35, 40], "There": [0, 4, 5, 9, 13, 20, 28], "just": [0, 4, 5, 7, 11, 28, 35, 39, 40, 41], "zip": 0, "differ": [0, 2, 5, 7, 9, 12, 13, 17, 35], "extens": [0, 5, 13, 35], "contain": [0, 2, 3, 4, 5, 6, 7, 9, 12, 13, 17, 22, 25, 26, 28, 36, 37, 40], "json": [0, 2, 3, 5, 7, 13], "object": [0, 3, 5, 7, 15, 23], "It": [0, 5, 7, 17, 35], "again": [0, 2, 5, 7, 13, 28, 35], "us": [0, 1, 2, 3, 4, 7, 9, 11, 12, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 27, 28, 30, 31, 32, 35, 37, 39, 40, 41], "choic": [0, 1, 7], "we": [0, 3, 5, 7, 11, 12, 14, 22, 26, 35, 37, 39, 40, 41], "recommend": [0, 4, 12, 13, 14, 26], "7": [0, 35], "task": 0, "everi": [0, 5], "other": [0, 1, 3, 5, 6, 7, 9, 11, 13, 15, 17, 20, 27, 35], "do": [0, 3, 4, 5, 17, 23, 26, 28], "job": 0, "too": [0, 1, 2, 13, 26], "you": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 19, 20, 22, 23, 24, 25, 26, 28, 30, 34, 35, 36, 39, 40, 41], "want": [0, 1, 5, 7, 8, 9, 12, 23], "perform": [0, 9, 12, 36, 37], "often": [0, 12], "regist": [0, 3], "window": [0, 5, 13], "choos": [0, 5, 7, 13, 37], "app": [0, 4, 5, 12, 15, 17, 19, 23, 35, 39], "type": [0, 4, 5, 7, 11, 13, 15, 20, 35, 37, 40], "set": [0, 3, 4, 5, 7, 8, 15, 17, 24, 26, 30, 35, 36, 37, 39, 41], "Then": [0, 7, 12, 22, 23, 32, 35, 37], "instead": [0, 1, 3, 4, 5, 7], "pack": 0, "fiddl": 0, "directli": [0, 2, 4, 13, 15, 17, 23, 26, 28, 30], "from": [0, 1, 2, 3, 4, 7, 9, 11, 12, 14, 15, 16, 17, 19, 26, 28, 35, 37], "when": [0, 1, 4, 5, 6, 7, 9, 12, 17, 26, 28], "notic": [0, 7, 35], "all": [0, 1, 2, 3, 5, 8, 9, 11, 16, 17, 19, 23, 35, 37, 39, 40, 41], "gener": [0, 7, 9, 11, 13, 15, 16, 23, 24, 37], "inform": [0, 4, 5, 7, 15, 17, 30, 35, 36, 37], "handl": [0, 4, 5, 7, 13, 15, 21, 26], "among": 0, "like": [0, 2, 3, 4, 5, 6, 7, 9, 12, 17, 35, 39, 40, 41], "descript": [0, 8, 14, 16], "associ": [0, 15], "object_xxx": 0, "tag": [0, 2], "provider_id": 0, "entri": [0, 3, 9, 13, 15, 17], "defin": [0, 1, 3, 4, 5, 9, 12, 17, 22, 35, 37], "In": [0, 2, 4, 5, 6, 7, 8, 9, 11, 12, 13, 23, 24, 35, 37, 39, 40], "exact": 0, "object_0": 0, "import_templ": 0, "script": [0, 9, 14, 15, 16, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41], "author": 0, "carl": 0, "zeiss": [0, 4, 5], "metrologi": [0, 14, 15], "gmbh": 0, "system": [0, 2, 15, 35, 39, 41], "cab03223": 0, "c3ca": 0, "4001": 0, "af23": 0, "23f6d07471cb": 0, "displaynam": 0, "resourc": [0, 2, 14, 26, 30, 31, 32], "content_id": 0, "711632f6": 0, "7444": 0, "4e66": 0, "bf21": 0, "00cdd153d535": 0, "import_cmm_xml": 0, "py": [0, 2, 3, 5, 6, 12, 26], "object_1": 0, "object_2": 0, "blade_cmm": 0, "so": [0, 4, 5, 7, 13, 14, 17, 23, 40], "complet": [0, 1, 3, 4, 5, 7, 14], "appropri": [0, 2, 3], "170": 0, "93": 0, "30": 0, "true": [0, 2, 4, 5, 7, 9, 15, 16, 17, 28, 35, 37, 40], "19": [0, 35], "cmd_mode_eval_blade_cmm": 0, "sy": [0, 2, 3, 4, 5, 7, 24, 28], "import_fil": 0, "separ": [0, 1, 2, 4, 5, 12, 13, 17, 26], "userscript": [0, 12], "blade_cmm__projectsetup__project_setup": 0, "tb_create_blade_stylus_correction_cmd_group": 0, "primit": [0, 4, 5], "create_fitting_plane_mp_none_draft": 0, "tb_create_profile_section_by_projection_cmd_group": 0, "blade_cmm__autopilot__autopilot": 0, "diagram": 0, "section_view": 0, "tabl": [0, 5, 8], "pip": 0, "displai": [0, 1, 3, 8, 13, 17, 36], "tooltip": [0, 2, 5, 13], "uniqu": [0, 1, 4, 5, 13], "id": [0, 2, 5, 11], "match": [0, 2, 12, 13, 15, 17], "field": [0, 3, 11], "pleas": [0, 1, 2, 3, 4, 5, 15], "onlin": [0, 1], "fresh": 0, "truli": 0, "rgb": [0, 4, 20], "background": [0, 9, 17], "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 20, 22, 23, 24, 25, 26, 28, 30, 32, 34, 35, 36, 37, 39, 40, 41], "mai": [0, 3, 5, 12], "overwritten": [0, 5], "theme": [0, 30], "e": [0, 1, 4, 5, 6, 7, 9, 10, 11, 13, 17, 19, 23, 26, 37], "g": [0, 4, 5, 6, 7, 9, 11, 13, 19, 23, 26], "dark": [0, 30], "51": 0, "alwai": [0, 4, 5, 9, 17, 36], "should": [0, 1, 2, 4, 7, 12, 13, 14, 15, 17, 26, 28, 35], "section": [0, 4, 5, 8, 9, 11, 20, 25], "recalcul": [0, 9, 17], "align": [0, 5], "posit": [0, 5, 7, 13], "valu": [0, 3, 4, 5, 7, 8, 9, 11, 14, 15, 19, 20, 24, 35, 39, 40, 41], "given": [0, 4, 5, 11, 15, 17, 30, 39, 41], "end": [0, 8, 9, 17, 37], "fine": [0, 7], "intern": [0, 4, 13, 17], "current": [0, 3, 4, 5, 6, 7, 8, 9, 12, 15, 17, 23, 35], "onli": [0, 3, 4, 5, 7, 13, 15, 17, 28, 35, 37, 39, 40, 41], "softwar": [0, 1, 2, 4, 5, 8, 9, 10, 12, 13, 14, 30, 35, 37, 40], "distribut": [0, 3], "anywher": 0, "outsid": 0, "world": [0, 11, 32, 35], "import": [0, 1, 3, 4, 5, 7, 9, 12, 26, 35], "limit": [0, 3, 5, 7, 13, 36], "now": [0, 1, 3, 4, 5, 7, 11, 13, 14, 15, 35], "But": [0, 2, 5], "method": 0, "custom": [0, 2, 8, 9, 14, 17, 26, 37, 39, 41], "particular": 0, "futur": [0, 15], "sw2022": 0, "0": [0, 1, 3, 4, 5, 7, 11, 15, 16, 17, 19, 23, 36, 39, 40], "later": [0, 2, 5, 12], "wide": 0, "support": [0, 2, 4, 5, 8, 37], "format": [0, 2, 4, 5, 7, 13, 17, 20, 37], "png": 0, "jpg": [0, 5], "qt": 0, "librari": [0, 19, 20, 37], "function": [0, 2, 3, 4, 7, 9, 11, 12, 13, 14, 15, 24, 26, 35, 36, 37, 39, 40, 41], "read": [0, 3, 5, 6, 9, 11, 17, 32, 35, 37], "imag": [0, 3, 4, 6, 14, 20, 28], "look": [0, 5, 7, 8, 11, 14, 17, 35], "relat": [0, 5, 15, 26], "document": [0, 2, 4, 5, 7, 8, 9, 26, 32, 34, 35], "see": [0, 2, 4, 5, 7, 8, 9, 11, 12, 13, 16, 17, 28, 32, 33, 35, 36, 38, 39, 40, 41], "base64": 0, "encod": [0, 3], "insert": [0, 4, 11, 23, 39], "result": [0, 2, 3, 7, 8, 9, 11, 12, 15, 19, 26, 35, 37, 39, 40, 41], "text": [0, 17, 25, 30], "item": [0, 5, 22], "properti": [0, 3, 7, 8, 9, 13, 18, 19, 20, 24, 28, 30, 35, 37], "string": [0, 3, 11, 12, 17, 35], "enclos": 0, "x8royf4miijq8v3ybiij6irvw1yr6dhnwuw45r0rerxcr": 0, "krealzdbzvxlgyredgzhbx1h4iiiiii": 0, "black": [0, 5], "white": [0, 5], "overal": [0, 12, 26], "style": [0, 5], "hex": 0, "333333": 0, "ffffff": 0, "255": 0, "transpar": 0, "size": [0, 5, 16, 17], "prefer": [0, 2, 5, 13], "24x24": 0, "px": 0, "minimum": [0, 5], "64x64": 0, "try": [0, 5, 35, 37], "NOT": [0, 1, 35], "ani": [0, 1, 3, 5, 6, 7, 11, 13, 17, 27, 36], "form": [0, 4, 8, 39, 41], "compress": 0, "good": 0, "bright": 0, "normal": [0, 4, 17, 30], "mean": [0, 3, 5, 35], "To": [0, 1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 17, 26, 28, 35, 36, 37, 39], "darker": 0, "two": [0, 1, 4, 5, 7, 9, 15, 17, 19, 20, 28, 35], "option": [0, 4, 5, 15, 17], "put": [0, 12], "pad": 0, "around": 0, "still": [0, 1, 4, 5, 13, 14], "visibl": [0, 4, 5, 7, 25], "let": [0, 3, 5, 7, 11, 35, 37], "automat": [0, 1, 2, 4, 5, 6, 12, 17, 26, 30], "invert": [0, 30], "get": [0, 4, 5, 6, 7, 8, 9, 11, 13, 14, 16, 19, 20, 23, 28, 30, 35, 39, 41], "autobrighten": 0, "standard": [0, 2, 5], "light": 0, "127": 0, "stai": 0, "same": [0, 2, 4, 5, 8, 9, 11, 13, 20, 26, 39, 41], "mode": [0, 5], "pure": 0, "auto": [0, 4], "brighten": 0, "These": [0, 4, 5, 11, 13, 35], "either": [0, 2, 4, 5, 13], "hardcod": 0, "start": [0, 4, 5, 6, 11, 12, 14, 15, 17, 35], "python": [0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 17, 23, 37], "here": [0, 3, 4, 5, 7, 13, 15, 26, 36, 37, 39, 40], "becom": [0, 5, 12], "right": [0, 2, 5, 9, 11, 13, 15, 30], "record": [0, 15], "skip": [0, 4], "prefix": [0, 11, 12], "execut": [0, 1, 6, 12, 17], "principl": 0, "per": [0, 4, 5, 17], "right_docking_area": 0, "toolbox": 0, "star": 0, "collaps": 0, "long": [0, 2, 3, 11], "default_view_layout_right_": 0, "isn": 0, "t": [0, 3, 17, 27, 39], "chang": [0, 2, 4, 5, 7, 9, 14, 15, 24, 25, 35], "investig": 0, "enter": [0, 3, 5, 13, 17, 30], "switch": [0, 5], "tab": [0, 5, 13], "initi": [0, 3, 5, 9, 28], "until": [0, 5], "them": [0, 2, 4, 5, 7, 11, 17, 26], "save": [0, 1, 2, 3, 5, 16, 35, 39], "svg": 0, "16x16": 0, "inkscap": 0, "templat": [0, 5, 14], "foreground": 0, "For": [0, 4, 5, 7, 8, 9, 11, 12, 13, 16, 17, 32, 33, 35, 38, 39, 40, 41], "proper": 0, "appear": [0, 5, 7, 11], "5px": 0, "bring": 0, "via": [0, 4, 5, 13, 15, 37], "mous": [0, 2, 5, 13], "i": [1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41], "sinc": [1, 2, 3], "version": [1, 2, 5, 12, 13, 15], "2022": [1, 2], "revis": 1, "147326": 1, "can": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 19, 20, 22, 23, 24, 26, 28, 30, 35, 36, 37, 39, 40, 41], "more": [1, 3, 4, 5, 7, 11, 12, 13, 25, 26, 35], "previou": [1, 3, 5, 7], "without": [1, 19, 26], "export": 1, "rmb": [1, 5], "add": [1, 3, 4, 6, 7, 8, 15, 16, 30, 37], "ctrl": [1, 13], "public": 1, "folder": [1, 2, 5, 6, 12, 13, 16, 26], "path": [1, 6, 16, 30], "\u2460the": 1, "\u2461modul": 1, "\u2462modul": 1, "local": [1, 14], "old": [1, 4], "also": [1, 3, 4, 5, 7, 11, 12, 17, 20, 23, 35, 36, 39, 40, 41], "valid": [1, 4, 13, 15, 17], "done": [1, 2, 12, 15, 28, 37], "wai": [1, 4, 5, 6, 13, 19, 35], "network": 1, "must": [1, 3, 4, 5, 9, 11, 13, 15, 17], "comma": [1, 2, 4], "specif": [1, 2, 9, 15, 26, 35], "after": [1, 3, 5, 7, 9, 11, 13, 24, 28, 35], "ex": 1, "numpi": [1, 4, 11, 17, 19, 37], "1": [1, 2, 3, 4, 5, 12, 13, 15, 17, 19, 20, 23, 28, 35, 36, 39, 40, 41], "22": [1, 35], "wheel": 1, "whl": 1, "ad": [1, 2, 5, 13, 14, 30], "remov": [1, 3, 13], "explor": [1, 5, 7, 13, 23, 40], "updat": [1, 3, 5, 12], "n": [1, 5], "wheelsfrom": 1, "requir": [1, 2, 9, 12, 17], "togeth": [1, 3, 5, 11], "being": [1, 17, 39, 40, 41], "offlin": 1, "go": [1, 3], "dialog": [1, 4, 9, 11, 14, 21, 22, 23, 24, 25, 26, 27, 28, 30, 35, 39, 40, 41], "than": [1, 4], "name": [1, 2, 3, 4, 6, 7, 8, 11, 12, 13, 16, 17, 19, 22, 23, 26, 32, 35, 37, 39], "call": [1, 4, 5, 6, 7, 9, 12, 15, 16, 17, 35, 36], "school": 1, "exist": [1, 4, 6, 8, 13, 15, 16, 32, 37, 39], "abl": [1, 5, 14, 17], "modifi": [1, 4, 5], "would": [1, 3, 4, 5, 9], "migrat": 1, "warn": [1, 5], "messag": [1, 5, 12, 17, 35], "code": [2, 3, 4, 5, 7, 12, 14, 26, 30], "compat": [2, 12], "care": 2, "thei": [2, 3, 4, 5, 7, 9, 12, 17], "kept": 2, "consist": [2, 3, 4, 5, 15, 25, 28], "lead": [2, 5], "below": [2, 3, 4, 5, 13, 17, 25, 32], "create_user_defined_dialog": [2, 3, 5, 7, 24], "content": [2, 3, 5, 13, 25, 32], "column": [2, 5], "monospac": [2, 5], "fals": [2, 4, 5, 9, 15, 16, 17, 28, 35, 37], "log": [2, 13], "row": [2, 5], "save_dialog_titl": [2, 5], "scroll_automat": [2, 5], "show_sav": [2, 5], "tr": 2, "dure": [2, 5, 7, 17, 35, 39], "process": [2, 3, 13, 14, 20], "replac": [2, 4, 5, 12], "runtim": [2, 5, 22], "print": [2, 3, 4, 5, 6, 12, 15, 32, 35], "access": [2, 3, 5, 6, 7, 11, 13, 16, 17, 18, 19, 20, 26, 30, 35, 37], "manag": [2, 3, 5], "download": [2, 5], "connect": 2, "plu": [2, 5, 15], "drag": [2, 5], "drop": [2, 5, 9], "onto": [2, 5, 13], "shall": [2, 8, 17], "identifi": [2, 4, 5, 15], "2": [2, 3, 4, 5, 12, 39, 40], "check": [2, 4, 5, 9, 10, 12, 14, 16, 19, 23, 26, 35, 38, 39, 40, 41], "number": [2, 4, 5, 15, 17, 36, 39, 41], "plausibl": 2, "3": [2, 3, 4, 5, 7, 12, 39], "press": [2, 3, 11, 13], "4": [2, 4, 5, 7, 15, 20, 35], "afterward": [2, 5, 7], "": [2, 3, 5, 7, 9, 11, 12, 15, 16, 17, 23, 25, 35, 37, 39, 40], "present": [2, 4, 7, 13], "possibli": 2, "servic": 2, "back": [2, 3, 5, 35, 37], "ns0": 2, "xmln": 2, "urn": 2, "oasi": 2, "tc": 2, "origin": [2, 4, 39, 41], "dl_analysis_01_curve_bas": 2, "datatyp": 2, "sourc": [2, 3, 5], "en": 2, "target": [2, 5, 37], "de": 2, "group": [2, 5], "restyp": 2, "x": [2, 4, 7, 9, 17, 23, 35], "gettext": 2, "domain": 2, "resnam": 2, "tran": 2, "unit": [2, 8, 24, 40], "xml": 2, "space": [2, 5], "preserv": 2, "protokolldatei": 2, "speichern": 2, "curv": [2, 8, 9, 15, 39], "kurveninspekt": 2, "bearbeitung": 2, "global": [2, 3, 5, 28], "might": [2, 5, 7, 12, 13, 14, 23, 35], "restart": 2, "due": [2, 3, 4, 13, 17], "cach": 2, "issu": [2, 5, 13], "quit": 2, "mani": [2, 7, 26, 35], "ha": [2, 3, 4, 5, 7, 11, 13, 17, 26, 35, 36, 40], "regularli": 2, "mirror": [2, 5, 13], "appdata": 2, "gom_package_script": 2, "copi": [2, 4, 5, 17], "past": 2, "remain": [2, 5], "As": [2, 3, 4, 7, 9, 12, 13, 23, 36, 40, 41], "attribut": [2, 4, 13], "alreadi": [2, 3, 4, 7, 14, 26, 35, 40], "untouch": 2, "case": [2, 4, 5, 6, 7, 8, 9, 11, 12, 15, 24, 26, 28, 35, 37, 39], "button": [2, 25, 26, 28, 35], "scheme": [2, 5], "autom": [2, 12], "build": [2, 13, 26], "queue": 2, "itself": [2, 12, 30, 35, 36], "design": [2, 25], "interact": [2, 5, 17, 21, 24, 28], "logic": [2, 3, 10, 37], "within": [2, 3, 17, 30], "implement": [2, 9, 17, 37, 39, 40, 41], "goal": 2, "shown": [2, 4, 5, 7, 13, 24, 35, 39, 41], "directori": [2, 5, 6, 12], "doubl": [2, 5, 9, 12, 15, 17], "sequenc": [3, 5], "guid": 3, "through": [3, 5], "flow": 3, "next": [3, 5, 6], "proce": 3, "close": [3, 13, 16, 17, 28], "transit": 3, "specifi": [3, 5, 17], "handler": [3, 17, 24, 25, 28, 35], "note": [3, 4, 5, 7, 11, 17], "widget": [3, 7, 22, 24, 25, 28, 35, 37, 39, 40, 41], "particularli": 3, "definit": [3, 5, 6, 12, 13, 14, 17, 32], "screenshot": [3, 5, 11, 12, 20, 36, 39, 41], "three": [3, 5, 8], "tutori": 3, "follow": [3, 4, 5, 6, 9, 10, 11, 12, 14, 17, 26, 30, 37, 39, 41], "input": [3, 5, 7, 8, 15, 24, 26], "control": [3, 35], "element": [3, 7, 8, 14, 15, 18, 19, 20, 22, 23, 26, 28, 33, 34, 36, 38, 39, 40, 41], "On": [3, 17, 26], "startup": 3, "first": [3, 4, 5, 7, 9, 13, 17, 28, 35, 37, 39, 40, 41], "instruct": 3, "correspond": [3, 5, 9, 17, 23, 24, 26, 30], "avoid": 3, "load": [3, 4, 5, 13, 16, 26], "extern": [3, 5, 13], "dummi": 3, "organ": 3, "arrai": [3, 4, 11, 17, 19, 20, 35, 37, 39, 40], "firstli": [3, 9], "hold": [3, 4, 5, 7, 9, 11, 35], "respect": [3, 4, 5, 8, 35, 40, 41], "main": [3, 7, 17, 25], "step_1": 3, "step_2": 3, "step_3": 3, "step_4": 3, "non": [3, 5, 17], "block": [3, 5, 26, 35], "ident": [3, 9, 40], "necessari": [3, 4, 7, 9, 13, 17, 26, 39], "overridden": 3, "u": 3, "count": [3, 5], "def": [3, 5, 7, 9, 12, 17, 25, 26, 28, 35, 36, 37, 39, 40], "handler_func": 3, "noteinput": 3, "been": [3, 4, 5, 13, 35], "len": [3, 4], "prev": [3, 5], "elif": [3, 5], "enabl": [3, 5, 9, 35], "state": [3, 4, 5, 7, 15], "assign": [3, 4, 5, 8, 9, 13, 17, 35, 40], "show_user_defined_dialog": [3, 5, 7, 28], "easili": [3, 4, 5, 26, 39, 41], "randombuttontext": 3, "anotherrandombuttontext": 3, "despit": 3, "mention": [3, 11, 13], "sophist": [3, 7], "anoth": [3, 5, 6, 7, 13, 24, 26, 30], "bore": [3, 5], "time": [3, 4, 5, 9, 12, 13, 28, 36], "won": 3, "inputstr": [3, 5], "current_step": 3, "new_step": 3, "current_dialog": 3, "close_user_defined_dialog": [3, 5, 28], "basic": [3, 7, 8, 11, 14, 19, 22, 24, 26, 34, 35, 40], "idea": 3, "hit": 3, "return": [3, 4, 5, 7, 8, 9, 13, 14, 15, 16, 35, 37, 40], "snippet": [3, 11], "make": [3, 5, 11, 12, 35], "clear": [3, 5], "program": [3, 14, 15], "loop": [3, 17, 36], "launch": 3, "click": [3, 4, 5, 7, 8, 9, 11, 23, 30], "leav": 3, "termin": [3, 5], "befor": [3, 4, 5, 35], "suffix": 3, "omit": 3, "combin": 3, "second": [3, 5, 7, 17, 25, 35, 39], "singlelayoutwizard": 3, "utf": [3, 5, 9], "8": [3, 4, 5, 7, 9], "multilayoutwizard": 3, "out": [3, 4, 13], "acquir": 3, "welcom": [4, 14, 15, 26], "your": [4, 6, 7, 9, 11, 12, 14, 15, 26, 30, 31, 39, 40, 41], "point": [4, 5, 8, 9, 13, 15, 35, 36, 37, 39, 41], "develop": [4, 7, 13, 15], "find": [4, 5, 11, 12, 15, 25, 26, 40], "what": [4, 7, 24, 28], "ons": [4, 6, 14], "how": [4, 5, 7, 9, 10, 12, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41], "empti": [4, 5, 7, 17], "create_project": [4, 5], "workflow": [4, 14], "refer": [4, 5, 7, 9, 11, 13, 15, 17, 19, 35, 39, 40, 41], "evalu": [4, 5, 19], "usual": [4, 5, 9, 13, 37], "place": [4, 5, 13], "under": [4, 13, 14, 15], "accordingli": [4, 13], "part_object": 4, "create_new_part": 4, "index": [4, 11, 15, 17], "categori": [4, 6, 7, 9, 16, 23, 26], "iter": [4, 23], "over": [4, 9, 13, 17, 23, 34, 35], "p": [4, 5, 15], "step": [4, 5, 12, 13, 28, 36], "import_g3d": 4, "file": [4, 6, 13, 16, 26, 30], "d": [4, 5, 35], "gom_part": 4, "g3d": [4, 5], "import_mod": 4, "move": 4, "add_elements_to_part": 4, "delete_invisible_el": 4, "actual_el": [4, 15, 23, 35], "new_el": 4, "construct": [4, 5], "belong": [4, 20], "most": [4, 5, 7, 8, 9, 13, 26, 40], "eleg": 4, "keep": [4, 5, 16, 26], "correct": [4, 13, 39, 41], "parametr": [4, 9], "formerli": 4, "mesh_proxi": 4, "actualrefer": [4, 5], "realli": 4, "repres": [4, 5, 13, 16, 17], "plan": 4, "mesh_el": 4, "address": [4, 5], "nomin": [4, 8, 17, 39, 40], "cad_proxi": 4, "nominalrefer": 4, "cad_el": 4, "retriev": [4, 11, 35, 37], "One": [4, 9, 28], "achiev": [4, 26, 28, 35], "easier": 4, "elementselect": [4, 23], "hidden": 4, "kei": [4, 5, 11, 13, 23, 35], "is_element_in_clipboard": 4, "nominal_el": 4, "mind": [4, 15], "token": [4, 10, 17, 19, 35], "establish": [4, 13], "explorer_categori": [4, 23], "multipl": [4, 5, 7, 12, 24], "distinguish": [4, 35], "unless": 4, "deal": [4, 12], "allow": [4, 5, 17, 39, 40, 41], "analyz": 4, "kind": 4, "explicit": [4, 5, 17], "2018": 4, "restrict": 4, "singl": [4, 5, 15, 17, 19], "2016": 4, "determin": [4, 13], "is_part_project": 4, "els": [4, 5, 32, 35], "former": 4, "cadgroup": 4, "about": [4, 5, 7, 17], "vmr": 4, "setup": [4, 12], "much": [4, 7, 40], "compar": [4, 5], "were": 4, "introduc": [4, 10, 34], "further": [4, 5, 11], "question": 4, "regard": [4, 9, 17, 29], "purpos": [4, 13, 17, 39, 40, 41], "contact": 4, "measurement_seri": [4, 15], "longer": 4, "scan": 4, "object_famili": 4, "did": [4, 7], "situat": 4, "slight": 4, "taken": [4, 12], "account": 4, "keyword": [4, 11, 14], "could": [4, 7, 26, 28, 35], "fact": 4, "addit": [4, 5, 13, 17, 30], "importantli": 4, "store": [4, 5, 11, 12, 15, 17, 37], "catproduct": 4, "entiti": [4, 11], "simpl": [4, 5, 8, 11, 19, 24, 25, 26, 32], "bodi": 4, "give": [4, 5, 7, 37], "delet": 4, "oper": [4, 5], "suppress": 4, "intent": 4, "usag": [4, 24, 32, 39, 41], "exchang": [4, 5], "expect": [4, 12, 14, 35, 36], "filter": [4, 5, 28, 39, 40, 41], "lambda": 4, "c": [4, 5, 16, 39], "b": [4, 6, 32], "cat_part": 4, "furthermor": [4, 8, 12, 35, 37, 40], "str": [4, 5, 15, 28, 35], "our": [4, 5, 7, 14, 26, 30, 35, 37], "detail": [4, 5, 8, 9, 12, 15, 32], "therefor": [4, 5, 7, 11, 20, 34, 35, 39, 40, 41], "anymor": 4, "tri": 4, "resolv": [4, 6], "map": [4, 5, 7, 9, 11, 35], "take": [4, 5, 7, 8, 11, 14, 17, 35, 39, 41], "actualvalu": 4, "happen": [4, 5, 37], "nominalvalu": 4, "obsolet": 4, "tesselate_geometrical_el": 4, "surfac": [4, 5, 8, 9, 12, 15, 19, 37, 41], "sever": [4, 5, 7, 12, 14, 35], "simpli": 4, "referenc": [4, 13, 15, 35, 39, 41], "gom_part_test_project": [4, 12, 26, 39, 41], "onc": 4, "context": [4, 6, 7, 9, 11, 35, 36, 37, 39, 40], "shortcut": 4, "f2": [4, 11, 23], "preview": [4, 9, 11, 41], "ok": [4, 5, 7, 11, 23, 35], "cours": [4, 11, 14], "area": 4, "output": [4, 5, 13, 20, 32, 35], "207422": 4, "1875": 4, "visual": [4, 14], "studio": [4, 14], "usabl": 4, "pop": 4, "up": [4, 11, 13, 17, 35], "multi": [4, 13], "approach": [4, 7, 9, 26, 28, 30], "describ": [4, 6, 7, 11, 15, 17, 40, 41], "in_stag": [4, 35], "indic": [4, 7, 11, 12, 13, 15, 17, 35, 36], "especi": [4, 12], "larger": [4, 17], "vertic": [4, 5, 17, 37, 39], "integ": 4, "dimens": 4, "trend": [4, 36], "238654": 4, "y": [4, 7, 9, 17, 35, 39, 41], "z": [4, 7, 9, 17, 35], "tripl": 4, "coordin": [4, 5, 15, 17, 37, 39, 41], "shape": [4, 17, 20, 39], "scalar": [4, 8, 9, 15, 19, 39, 40, 41], "my": [4, 7], "result_dimens": [4, 19], "deviat": [4, 8, 17, 19, 41], "4000x3000": 4, "pixel": [4, 15, 17, 20], "r": 4, "tupl": [4, 7], "measurement_list": 4, "m1": 4, "camera": [4, 15], "3000": 4, "4000": 4, "transfer": [4, 37], "immedi": [4, 17], "moment": [4, 13], "convert": [4, 37], "fetch": [4, 5], "45": 4, "mb": 4, "100": [4, 5, 36], "m": [4, 5], "np": [4, 11, 17, 19, 20, 37, 39], "scalar_valu": 4, "800": 4, "locat": [5, 12, 13, 15], "embed": 5, "filenam": 5, "gdlg": [5, 13], "renam": 5, "execute_user_defined_dialog": 5, "okcancel": 5, "always_toplevel": 5, "height": 5, "155": 5, "width": 5, "198": 5, "sizemod": 5, "titl": [5, 25], "translat": 5, "explain": [5, 7, 40], "gui": 5, "underli": 5, "action": 5, "merg": 5, "split": 5, "cell": 5, "horizont": 5, "mark": [5, 26], "red": 5, "overlai": 5, "direct": [5, 17], "claim": 5, "maximum": [5, 15], "share": [5, 16], "resid": [5, 13, 30], "newli": 5, "overwrit": [5, 16], "fill": [5, 7, 9, 17, 39], "rid": 5, "least": 5, "addition": [5, 12], "variou": [5, 13], "paramet": [5, 7, 9, 15, 16, 35, 37, 39, 40], "found": [5, 7, 15, 32], "scriptingeditorexampledialog": 5, "overview": [5, 14], "intuit": 5, "obtain": [5, 11, 19, 35], "doc": 5, "objnam": 5, "unclear": 5, "cancel": 5, "similar": [5, 11, 12], "cannot": 5, "fix": [5, 13], "insid": [5, 11], "lower": 5, "icon": [5, 26, 29, 30], "miss": [5, 7, 13], "semant": 5, "br": 5, "controlgroup": 5, "tip": 5, "unspecifi": 5, "programmat": 5, "bool": [5, 15, 17], "invis": 5, "small": [5, 26, 30], "regular": [5, 9], "No": [5, 35], "disabl": [5, 13, 35], "reset": [5, 35], "error": [5, 7, 12, 17], "static": [5, 16], "typic": 5, "individu": 5, "focu": 5, "word_wrap": 5, "appli": [5, 35, 37, 39], "textwidget": 5, "wordwrap": 5, "default_font_famili": 5, "arial": 5, "default_font_s": 5, "int": [5, 15], "12": [5, 7, 35], "procedur": 5, "express": [5, 13, 19, 23], "desir": [5, 7, 9], "tree": 5, "actual": [5, 8, 9, 10, 11, 14, 23, 26, 33, 34, 35, 36, 37, 39, 40], "final": [5, 7, 11, 12, 37, 39, 41], "render": [5, 20], "html": 5, "center": [5, 15, 17], "By": [5, 19], "arbitrari": [5, 13, 36], "use_system_imag": 5, "system_imag": 5, "system_message_inform": 5, "system_message_warn": 5, "system_message_crit": 5, "system_message_quest": 5, "file_nam": 5, "keep_original_s": 5, "keep_aspect": 5, "my_dialog": 5, "my_imag": 5, "image_container_dialog": 5, "image_1": 5, "beforehand": [5, 14], "shorten": 5, "aaaaaylqtkcnchokaaaadulirfiaaaqaaaacqagcaaaanpedgptzssdt": 5, "iqmprink": 5, "inspect_python": 5, "144": 5, "256": 5, "233": 5, "292": 5, "line": [5, 7, 13, 15, 35], "unformat": 5, "font": 5, "variabl": [5, 13, 28, 37], "open_user_defined_dialog": 5, "sleep": [5, 36], "33": 5, "66": 5, "corner": [5, 15], "import_project": 5, "project": [5, 9, 12, 17, 19, 20, 23, 35, 36, 37, 39, 41], "between": [5, 7, 11, 15, 17], "partial": 5, "rang": [5, 11, 36, 39], "divid": 5, "sequenti": 5, "equal": [5, 41], "interv": 5, "third": [5, 17, 35], "That": [5, 7], "finish": [5, 7], "load_project": 5, "run": [5, 9, 13], "switch_to_report_workspac": 5, "update_report_pag": 5, "switch_align": 5, "switch_stag": 5, "switch_to_inspection_workspac": 5, "recalculate_all_el": 5, "progressbar": 5, "50": 5, "20": 5, "none": [5, 39], "percentag": 5, "request": 5, "accord": [5, 24], "elementnamewidget": 5, "anyth": 5, "dialog_event_handl": [5, 25, 28, 35], "pass": [5, 12, 37], "mcad_el": 5, "create_point": 5, "vec3d": [5, 11, 15, 17, 39], "10": [5, 7, 15], "inputelenam": 5, "blob": 5, "basenam": 5, "suggest": 5, "from_element_typ": 5, "check_lik": 5, "read_onli": 5, "integerwidget": 5, "userinput": 5, "inputint": 5, "15": [5, 7], "float": [5, 17], "digit": 5, "ones": [5, 23], "decimalwidget": 5, "distanc": [5, 15], "precis": 5, "length": [5, 11, 39, 41], "textentrywidget": 5, "warsaw": 5, "password": 5, "hide": 5, "charact": 5, "dot": [5, 39], "certain": [5, 8, 9, 23, 26, 37], "sliderwidget": 5, "rotat": 5, "angl": 5, "90": 5, "orient": 5, "boolean": 5, "checkboxwidget": 5, "inputcheckbox": 5, "inputfil": 5, "protocol": 5, "multi_fil": 5, "txt": [5, 6, 32], "file_typ": 5, "filename_extens": 5, "mesh": [5, 8, 9, 11, 17, 26, 41], "stp": 5, "cad": [5, 26], "order": 5, "datewidget": 5, "dateobject": 5, "year": 5, "month": 5, "dai": 5, "inputd": 5, "fabric": 5, "use_current_d": 5, "2014": 5, "24": 5, "show_today_button": 5, "colorwidget": 5, "gomcolor": 5, "behav": 5, "ffffffff": 5, "0xffffffff": 5, "inputcolor": 5, "transparency_allow": 5, "unitwidget": 5, "inputunit": 5, "chosen": 5, "plane": [5, 17, 23, 39, 41], "elementselectionwidget": 5, "selectedel": 5, "equidist": 5, "selectel": 5, "supplier": 5, "dialog4": 5, "element_filt": [5, 37], "except": [5, 35, 37], "input_new": 5, "attach": [5, 13, 17], "predefin": 5, "selectionlistwidget": 5, "selectedvalu": 5, "entry2": 5, "selectentri": 5, "debug": 5, "select_mod": 5, "fatal": 5, "trigger": [5, 9, 13, 23, 35], "push": 5, "toggl": [5, 25], "inact": 5, "highlight": 5, "togglebuttonst": 5, "togglebuttonwidget": 5, "icon_typ": 5, "remark": [5, 17], "icon_system_typ": 5, "arrow_left": 5, "arrow_right": 5, "arrow_up": 5, "arrow_down": 5, "icon_system_s": 5, "larg": [5, 19], "extra_larg": 5, "straightforward": [5, 11], "both": [5, 17], "ONE": 5, "selectedchoic": 5, "radiobuttonswidget": 5, "radiobutton": 5, "altern": [5, 17], "value3": 5, "value1": 5, "title1": 5, "value2": 5, "title2": 5, "title3": 5, "manner": 5, "toleranceswidget": 5, "expand": 5, "widg": 5, "no_toler": 5, "via_tolerance_t": 5, "from_cad": 5, "from_el": 5, "upper": [5, 15], "use_warn_limit": 5, "level": [5, 6, 12], "upper_warn": 5, "5": [5, 7], "lower_warn": 5, "link_limit": 5, "filesystemwidget": 5, "root": 5, "show_dat": 5, "show_siz": 5, "show_typ": 5, "use_multiselect": 5, "temp": 5, "basic_training_gom_inspect_pro": 5, "train": [5, 14, 35], "raw": [5, 20], "background_styl": 5, "1000": 5, "inputdist": 5, "112": 5, "subsequ": 5, "At": [5, 9], "last": [5, 7, 17], "stufe": 5, "write": [5, 7, 9, 17, 26, 32], "whole": 5, "spinbox": 5, "dialogresult": 5, "point1": [5, 17], "point2": [5, 17], "6": 5, "create_line_by_2_point": 5, "produc": 5, "ye": [5, 13, 22], "cheater": 5, "button_y": 5, "button_no": 5, "breakerror": 5, "dialog_yes_no": 5, "receiv": [5, 17], "instanc": [5, 13, 17], "common": [5, 40], "create_dialog": 5, "signal": 5, "those": 5, "caus": [5, 13, 35], "handler_funct": 5, "argument": [5, 17, 35], "textinput": 5, "button1": 5, "execute_func_1": 5, "button2": 5, "execute_func_2": 5, "button3": 5, "execute_func_3": 5, "invalid": 5, "impli": 5, "written": [5, 10, 11], "stop": [5, 12, 13], "exit": 5, "Its": 5, "swap": [5, 17], "veri": [5, 7, 19, 24, 28, 35], "dynam": 5, "languag": 5, "queri": [5, 13, 15], "commonli": [5, 9], "consol": [5, 13], "my_button": 5, "pushbutton": 5, "tom": 5, "pars": 5, "binari": [5, 6, 16, 26, 31], "icon_file_nam": 5, "icon_s": 5, "full": [5, 13], "edg": 5, "programm": 5, "respons": [5, 9, 35], "versatil": 5, "act": [5, 15], "und": 5, "well": [5, 6, 9, 12, 14, 26, 40], "panel": 5, "func": 5, "wa": [5, 7, 11, 16, 17, 25, 35, 37], "greater": 5, "term": 6, "config": 6, "recogn": 6, "qualifi": [6, 16], "rel": [6, 16, 30], "top": [6, 12, 13, 28, 36, 39, 41], "pythonapiexampl": [6, 12], "script_resourc": [6, 14, 16, 26], "test_resourc": [6, 32], "inevit": 6, "advis": [6, 23], "suppos": [6, 22], "resource_exampl": 6, "re": [6, 32], "open": [6, 11, 13, 16, 20, 28], "api": [6, 7, 8, 9, 12, 13, 23, 32, 35, 37, 39, 40, 41], "short": [7, 8], "measur": [7, 15, 26], "geometr": [7, 9], "assum": [7, 8, 11], "whose": [7, 35], "coupl": 7, "millimet": 7, "though": 7, "clearli": 7, "serv": [7, 12], "easi": 7, "chapter": [7, 9, 26], "natur": 7, "begin": 7, "param": [7, 8, 9, 35, 36, 37, 39, 40], "i_x": [7, 35], "member": [7, 9, 17, 35, 40], "dictionari": [7, 11, 35, 40], "ask": [7, 8], "decim": [7, 24, 37], "adress": 7, "offer": 7, "edit": [7, 9, 17, 30], "henc": 7, "prefil": 7, "collect": [7, 14, 18, 21, 27, 29, 31, 33, 38], "13": 7, "framework": [7, 11, 35], "continu": [7, 13], "tricki": 7, "probabl": [7, 13], "come": [7, 35], "where": [7, 15, 28, 37, 39, 41], "solv": 7, "complex": [7, 11, 26], "mathemat": 7, "problem": [7, 13], "comput": [7, 9, 15, 17, 36, 39], "howev": [7, 8, 11, 26, 30, 39, 41], "thing": 7, "center_coordin": [7, 35], "coorin": 7, "stage": [7, 9, 11, 15, 17, 19, 20, 36, 37, 39, 40], "ignor": [7, 17], "went": 7, "along": [7, 17], "ve": 7, "grasp": 7, "concept": [7, 8, 10, 11, 14, 16, 17, 34, 35, 40], "relev": [7, 13], "topic": [7, 14], "fulli": 7, "integr": [7, 8], "experi": [7, 35], "cover": 7, "learn": [7, 26], "mechan": [7, 11, 35, 40], "familiar": [8, 11, 14, 35, 40], "realiz": [8, 24], "structur": [8, 11, 15, 17, 35], "toler": [8, 24, 40], "success": [8, 9, 16, 17, 35], "nativ": 8, "abbrevi": [8, 40], "scrsca": [8, 40], "ll": [8, 20, 35], "3d": [8, 15, 17, 20, 35], "label": [8, 17, 25], "link": [8, 24], "pair": [8, 15, 35], "scripted_scalar_check": [8, 38], "scripted_curve_check": [8, 38, 41], "scripted_surface_check": [8, 38], "intend": 9, "demonstr": [9, 19, 20, 24, 28, 31, 36, 37, 39, 41], "abil": 9, "circl": 9, "cylind": [9, 39, 41], "prodecur": 9, "v": [9, 30], "down": 9, "interfac": [9, 19, 37], "calcul": [9, 10, 11, 14, 36, 39, 40], "is_computation_valid": 9, "invok": [9, 12, 17], "who": 9, "consequ": 9, "understand": 9, "practic": [9, 12, 26], "head": [9, 34], "tos": 10, "introduct": [10, 14, 17, 23, 33, 37, 38], "ud": [11, 17], "volum": [11, 14, 20, 26], "defect": 11, "simul": [11, 36], "166": 11, "ude_defect_id": 11, "ude_test_str": 11, "hello": [11, 32], "intermedi": 11, "calc": [11, 17, 35], "reason": [11, 26], "pre": 11, "reus": [11, 26], "sw2021": 11, "interpret": 11, "With": [11, 14], "free": [11, 14, 16], "serializ": 11, "previous": 11, "exemplari": [11, 23, 40], "test": [11, 14, 15, 24, 26], "ude_": [11, 35], "successfulli": 11, "search": [11, 15], "syntax": 11, "Of": 11, "got": 11, "selector": [11, 13], "defect_id": 11, "sure": [11, 12], "165": 11, "crucial": 12, "maintain": 12, "tediou": 12, "consum": 12, "focus": 12, "help": 12, "ensur": [12, 13], "correctli": [12, 24], "effici": [12, 19], "machin": 12, "improv": 12, "meet": 12, "best": [12, 26], "upcom": 12, "sw": 12, "mandatori": 12, "discoveri": 12, "pytest": 12, "convent": 12, "test_": 12, "run_test": 12, "test_data_interfaces_check_result": 12, "modul": [12, 16], "packag": [12, 13, 14, 15, 17, 30], "data_interfac": [12, 14, 26], "check_results_data_arrai": [12, 18], "properli": [12, 13], "check_results_data_arrrai": 12, "get_single_result_valu": 12, "behavior": 12, "test_check_result": 12, "open_project": 12, "test_el": 12, "comparison": [12, 19], "expected_single_valu": 12, "0495047569274902": 12, "actual_result_valu": 12, "assert": [12, 24], "__name__": [12, 26], "__main__": [12, 26], "wrapper": 12, "script_path": 12, "desrib": 12, "wherea": [12, 30], "underscor": 12, "__": 12, "subdirectori": 12, "pythonapiexamples__tests__test_data_interfaces_check_result": 12, "pythonapiexamples__tests__test_": 12, "unhandl": 12, "otherwis": [12, 16, 17], "marketplac": 13, "vscode": 13, "64": 13, "higher": 13, "statu": 13, "bar": 13, "disconnect": 13, "reflect": 13, "toolbar": 13, "subsect": 13, "cursor": 13, "breakpoint": 13, "debugg": 13, "break": 13, "traceback": 13, "graphic": 13, "presetn": 13, "adapt": [13, 26, 28], "unsolv": 13, "bug": 13, "hint": 13, "box": 13, "keyboard": 13, "claus": 13, "ist": 13, "resourcelangid": 13, "scriptinghostconnect": 13, "bind": 13, "f9": 13, "environ": [13, 14], "workaround": 13, "hotkei": 13, "noth": 13, "microsoft": 13, "filesystem": 13, "affect": 13, "parallel": 13, "session": 13, "seem": [13, 26], "launcher": 13, "prompt": 13, "Ons": [14, 26], "extend": [14, 17], "configur": 14, "bookmark": 14, "sub": 14, "site": 14, "advanc": 14, "teach": 14, "elearn": 14, "780": 14, "starter": [14, 35], "Or": 14, "interest": [14, 24, 26, 36], "correl": 14, "wizard": 14, "workspac": [14, 30], "know": [14, 17, 28, 35], "metadata": 14, "myst": 14, "html_meta": 14, "2023": 14, "dialog_widget": [14, 26], "misc": [14, 26], "script_icon": [14, 26], "scripted_actu": [14, 26], "scripted_check": [14, 26], "summmari": 14, "class": 14, "gom inspect": 15, "python api": 15, "gom api": 15, "add-on": 15, "subset": 15, "bear": 15, "preliminari": 15, "heavi": 15, "massiv": 15, "acquisit": 15, "proxi": 15, "terminologi": 15, "2d": 15, "get_image_aquisit": 15, "contribut": 15, "photogrammetri": 15, "photogrammeri": 15, "tritop": 15, "deform": 15, "seri": 15, "d1": 15, "get_image_acquisit": 15, "compute_pixels_from_point": 15, "point_and_image_acquisit": 15, "vec2d": 15, "1031": 15, "582008690226": 15, "1232": 15, "4155555222544": 15, "1139": 15, "886626169376": 15, "1217": 15, "975608783256": 15, "compute_point_from_pixel": 15, "pixel_and_imag": 15, "use_calibr": 15, "pixel_and_image_acquisit": 15, "calibr": 15, "residuum": 15, "638": 15, "2453100625158": 15, "1627": 15, "6169782583584": 15, "compute_epipolar_lin": 15, "image_acquisition_1": 15, "_2": 15, "max_dist": 15, "epipolar": 15, "image_aquisition_1": 15, "pixel_and_image_aquisition_2": 15, "mm": [15, 23], "l": 15, "1617": 15, "819": 15, "752311764226988": 15, "813": 15, "7915394509045": 15, "749371580282741": 15, "748887458453": 15, "16": [15, 35], "73347976996274": 15, "706352662515": 15, "is_scalar_check": [15, 40], "suitabl": [15, 39, 40, 41], "is_surface_check": [15, 41], "is_curve_check": [15, 39], "util": 16, "memori": 16, "cleanup": 16, "dangl": 16, "__init__": 16, "constructor": 16, "isload": 16, "releas": 16, "bytes": 16, "byte": [16, 17], "keepinmemori": 16, "saveasuserresourc": 16, "new_path": 16, "don": [17, 27], "role": 17, "storag": 17, "total_stag": 17, "is_new_el": 17, "flag": 17, "recalc": 17, "occur": 17, "edit_el": 17, "recalc_el": 17, "abort": 17, "event": [17, 24, 25, 26, 28, 35], "asynchron": 17, "Will": 17, "progress_stages_comput": [17, 36], "progress": [17, 36], "progress_stages_tot": [17, 36], "serial": 17, "plain": 17, "real": [17, 35], "vector": [17, 39, 41], "radiu": 17, "polylin": 17, "made": 17, "subcurv": 17, "denot": 17, "geometri": 17, "trait": 17, "triangul": 17, "triangl": [17, 37], "vertex": [17, 39], "v0": 17, "v1": 17, "v2": 17, "accept": 17, "radius1": 17, "radius2": 17, "represenst": 17, "smaller": 17, "inner": 17, "outer_hul": 17, "outer": 17, "hull": 17, "outer_hull_vertic": 17, "outer_hull_triangl": 17, "OR": 17, "p201": 17, "polygon": 17, "voxel": 17, "transform": [17, 37, 39, 41], "dtype": [17, 37], "uint16": 17, "int16": 17, "int32": [17, 37], "uint32": 17, "mat4x4": 17, "affin": [17, 39], "scale": 17, "axi": 17, "voxel_data": 17, "uint8": 17, "grei": 17, "material_labels_draft": 17, "material_grey_values_draft": 17, "volume_reference_draft": 17, "float32": 17, "pixel_data": 17, "deviation_valu": [17, 41], "actual_valu": [17, 39], "nominal_valu": [17, 39], "volume_section_image_data": 18, "single_scalar_valu": 19, "dataset": 19, "essenti": 20, "slice": 20, "raw_imag": 20, "yield": [20, 28, 37], "rgb_imag": 20, "rgba": 20, "305": 20, "295": 20, "305x295": 20, "pillow": 20, "dropdown_widget_dynam": 21, "explorer_selected_elements_in_dialog": 21, "unit_dialog_event_handl": 21, "widget_vis": 21, "dropdown": 22, "sometim": [23, 26], "selected_actu": 23, "is_select": 23, "pretti": 23, "lengthi": 23, "example_select": 23, "00": 23, "apply_select": 23, "addon_test": 24, "test_dialog_widgets_unit_dialog": 24, "event_handl": 24, "setup_dialog": 24, "unit_widget": 24, "forc": 24, "mimic": 24, "turn": 25, "off": 25, "symbol": 25, "label_bottom": 25, "function1": 26, "code1": 26, "function2": 26, "code2": 26, "someth": 26, "something2": 26, "spot": 26, "comment": 26, "littl": 26, "bit": 26, "highli": 26, "encourag": 26, "modular": 26, "testabl": 26, "reusabl": 26, "reli": 26, "setup_project": 26, "optic": 26, "volume_test_part": 26, "ct": 26, "miscellan": 26, "fit": 27, "dialog_reopen_exampl": 27, "rare": 28, "occas": 28, "declar": 28, "guard": 28, "reopen": 28, "few": 28, "delay_script": 28, "stuff": 28, "never": 28, "prevent": 28, "undefin": 28, "behaviour": [28, 35], "script_icon_from_fil": 29, "meant": [30, 34], "guidelin": 30, "metainfo": 30, "resource_api_exampl": 31, "whether": 32, "get_resource_cont": 32, "string_byt": 32, "create_resource_with_cont": 32, "offset_point_simpl": [33, 35], "offset_point_v2": [33, 34], "scripted_element_progress": 33, "trimesh_deform_mesh": 33, "discuss": 35, "enhanc": 35, "built": 35, "tweak": 35, "treatment": 35, "i_i": 35, "i_z": 35, "offset": 35, "23": 35, "fail": 35, "enabled": 35, "21": 35, "sent": 35, "potenti": 35, "calcualt": [35, 36], "11": 35, "valid_result": 35, "ude_mykei": 35, "123456": 35, "impress": 35, "surround": 35, "catch": 35, "aris": 35, "meaning": 35, "observ": 35, "9": 35, "consecut": 35, "meaningless": 36, "showcas": 36, "amount": 36, "soon": 36, "bottom": 36, "random": [37, 39], "popul": 37, "cad_bodi": 37, "selected_el": 37, "magnitud": 37, "subscript": 37, "3rd": 37, "parti": 37, "algorithm": 37, "permut": 37, "nois": 37, "deformed_vertic": 37, "deformed_fac": 37, "face": 37, "slct_element": [39, 40, 41], "conveni": [39, 40, 41], "scripted_checks_util": [39, 40, 41], "coordinate_system": 39, "view_csi": 39, "get_cs_transformation_4x4": 39, "4x4": 39, "matrix": 39, "product": 39, "trafo_matric": 39, "stage_trafo": 39, "stage_vertic": 39, "actual_result": [39, 40], "zero": 39, "nominal_result": [39, 40], "rand": 39, "effect": [39, 41], "nearli": 40, "lot": 40, "eas": 40, "deviation_result": 41}, "objects": {"gom": [[16, 0, 1, "", "Resource"]], "gom.Resource.Resource": [[16, 1, 1, "", "cleanup"], [16, 1, 1, "", "list"]], "gom.Resource": [[16, 1, 1, "", "__init__"], [16, 1, 1, "", "byteSize"], [16, 1, 1, "", "close"], [16, 1, 1, "", "exists"], [16, 1, 1, "", "isLoaded"], [16, 1, 1, "", "keepInMemory"], [16, 1, 1, "", "open"], [16, 1, 1, "", "save"], [16, 1, 1, "", "saveAsUserResource"]], "gom.api.imaging": [[15, 2, 1, "", "compute_epipolar_line"], [15, 2, 1, "", "compute_pixels_from_point"], [15, 2, 1, "", "compute_point_from_pixels"]], "gom.api.project": [[15, 2, 1, "", "get_image_aquisition"]], "gom.api.scripted_checks_util": [[15, 2, 1, "", "is_curve_checkable"], [15, 2, 1, "", "is_scalar_checkable"], [15, 2, 1, "", "is_surface_checkable"]]}, "objtypes": {"0": "py:class", "1": "py:method", "2": "py:function"}, "objnames": {"0": ["py", "class", "Python class"], "1": ["py", "method", "Python method"], "2": ["py", "function", "Python function"]}, "titleterms": {"ad": [0, 4, 26], "workspac": [0, 13], "add": [0, 12, 13, 14, 26], "ons": [0, 12, 26], "step": [0, 3, 9], "1": 0, "unpack": 0, "2": 0, "edit": [0, 1, 2, 5, 13], "main": 0, "packag": [0, 1, 2, 26], "content": [0, 1, 4], "file": [0, 1, 2, 5, 12], "3": 0, "definit": [0, 16], "name": [0, 5], "uuid": 0, "color": [0, 5], "recalc_sect": 0, "alignment_sect": 0, "sort_index": 0, "icon": 0, "workflow_command": 0, "sensor_command": 0, "default_visible_view": 0, "default_visible_tab": 0, "4": 0, "test": [0, 12], "your": 0, "guidelin": 0, "faq": [0, 2, 13], "how": [0, 11, 13, 14, 26], "can": [0, 13], "i": [0, 2, 3, 13], "toolbar": 0, "environ": [1, 4], "python": [1, 4, 14, 15, 26], "script": [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 26], "creat": [1, 3, 4, 5, 13], "an": [1, 2, 4, 13], "editor": [1, 13], "instal": [1, 2, 13], "uninstal": 1, "write": [1, 2, 8, 12], "run": [1, 7, 12], "modul": 1, "json": 1, "contain": 1, "onli": 1, "manag": 1, "local": [2, 13], "translat": 2, "user": [2, 11, 13], "defin": [2, 11, 13], "dialog": [2, 3, 5, 7, 8, 13, 17, 37], "text": [2, 3, 5], "gener": [2, 35], "xliff": 2, "internation": 2, "switch": 2, "mode": [2, 13], "execut": [2, 5, 13], "updat": 2, "languag": 2, "enabl": 2, "select": [2, 5], "applic": [2, 13], "shortcut": [2, 13], "export": 2, "import": [2, 6], "ar": [2, 11, 26], "entri": [2, 5], "persist": 2, "when": [2, 13], "via": 2, "after": 2, "set": [2, 9, 11, 13], "displai": [2, 5], "wizard": [3, 5], "what": 3, "simpl": [3, 7], "chang": 3, "button": [3, 5], "differ": [3, 4], "layout": [3, 5], "per": 3, "final": 3, "singl": 3, "multi": 3, "gom": [4, 13, 14, 15, 16, 26], "inspect": [4, 14, 15, 26], "api": [4, 14, 15, 16, 17, 26], "introduct": [4, 8, 9, 11], "project": [4, 13, 15, 26], "part": 4, "element": [4, 5, 9, 10, 11, 13, 17, 35, 37], "access": 4, "cad": 4, "actual": [4, 7, 17], "mesh": [4, 37], "object": 4, "": 4, "all": [4, 12, 13], "align": 4, "clipboard": 4, "legaci": 4, "less": 4, "measur": 4, "seri": 4, "report": 4, "structur": [4, 9, 12, 26], "assembli": 4, "compat": 4, "master": 4, "group": 4, "proxi": 4, "tessel": 4, "geometr": 4, "properti": [4, 5], "explor": 4, "avail": 4, "vscode": 4, "stage": [4, 35], "data": [4, 17, 35], "interfac": 4, "concept": 4, "us": [5, 6, 8, 13, 26], "design": 5, "grid": 5, "spacer": 5, "widget": [5, 8], "insert": [5, 13], "remov": 5, "configur": [5, 13], "alreadi": 5, "__doc__": 5, "string": 5, "control": 5, "statu": [5, 35], "label": 5, "specif": [5, 14], "descript": [5, 19, 20, 22, 23, 24, 25, 26, 28, 30, 32, 34, 35, 36, 37, 39, 40, 41], "field": 5, "continu": 5, "keyword": [5, 13, 26], "intern": 5, "represent": 5, "imag": [5, 15], "log": 5, "progress": 5, "bar": 5, "integ": 5, "decim": 5, "slider": 5, "checkbox": 5, "date": 5, "unit": 5, "list": [5, 13], "radio": 5, "abort": 5, "toler": 5, "system": 5, "browser": 5, "command": [5, 13], "break": 5, "extend": 5, "show": 5, "info": 5, "open": 5, "close": 5, "result": [5, 17], "custom": 5, "event": 5, "handler": 5, "function": [5, 17], "regist": 5, "from": [5, 13], "within": [5, 13], "timer": 5, "activ": 5, "determin": 5, "exist": 5, "attribut": [5, 17], "resourc": [6, 16], "usag": [6, 9, 11], "see": 6, "also": 6, "exampl": [7, 14, 18, 21, 26, 27, 29, 31, 33, 38], "offset": 7, "point": [7, 17], "calcul": [7, 17, 35, 37], "further": 7, "read": 7, "check": [8, 11, 15, 17], "special": 8, "paramet": [8, 17], "type": [8, 9, 17], "creation": 9, "code": [9, 13], "next": 9, "token": 11, "instruct": 11, "why": 12, "visual": 13, "studio": 13, "setup": 13, "connect": 13, "record": 13, "debug": 13, "start": 13, "new": 13, "do": 13, "toggl": 13, "current": 13, "host": 13, "disk": 13, "instead": 13, "databas": 13, "my": 13, "cannot": 13, "aspect": 13, "troubleshoot": 13, "intellisens": 13, "complet": 13, "stall": 13, "both": 13, "crash": 13, "happen": 13, "On": 14, "develop": 14, "document": [14, 15], "guid": 14, "process": 15, "scripted_checks_util": 15, "summmari": 16, "class": 16, "The": 17, "signatur": 17, "context": 17, "param": 17, "return": 17, "valu": 17, "preview": [17, 35], "distanc": 17, "circl": 17, "curv": 17, "surfac": 17, "section": 17, "cloud": 17, "cone": 17, "cylind": 17, "volum": 17, "defect": 17, "2d": 17, "materi": 17, "map": 17, "support": 17, "scalar": 17, "data_interfac": 18, "thi": [18, 21, 27, 29, 31, 33, 38], "categori": [18, 21, 27, 29, 31, 33, 38], "check_results_data_arrai": 19, "short": [19, 20, 22, 23, 24, 25, 28, 30, 32, 34, 35, 36, 37, 39, 40, 41], "highlight": [19, 20, 22, 23, 24, 25, 28, 30, 32, 35, 36, 37, 39, 40, 41], "relat": [19, 20, 22, 23, 24, 25, 28, 30, 32, 34, 35, 36, 37, 39, 40, 41], "volume_section_image_data": 20, "dialog_widget": 21, "dropdown_widget_dynam": 22, "explorer_selected_elements_in_dialog": 23, "unit_dialog_event_handl": 24, "widget_vis": 25, "metadata": 26, "myst": 26, "html_meta": 26, "2023": 26, "metrologi": 26, "overview": 26, "topic": 26, "misc": 27, "dialog_reopen_exampl": 28, "script_icon": 29, "script_icon_from_fil": 30, "script_resourc": 31, "resource_api_exampl": 32, "scripted_actu": 33, "offset_point_simpl": 34, "offset_point_v2": 35, "error": 35, "handl": 35, "store": 35, "scripted_element_progress": 36, "trimesh_deform_mesh": 37, "filter": 37, "deform": 37, "trimesh": 37, "scripted_check": 38, "scripted_curve_check": 39, "scripted_scalar_check": 40, "scripted_surface_check": 41}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 57}, "alltitles": {"Adding workspaces to add-ons": [[0, "adding-workspaces-to-add-ons"], [0, "id1"]], "Workspaces": [[0, "workspaces"]], "Step 1: Unpack the add-on": [[0, "step-1-unpack-the-add-on"]], "Step 2: Edit the main package content file": [[0, "step-2-edit-the-main-package-content-file"]], "Step 3: Add a workspace definition file": [[0, "step-3-add-a-workspace-definition-file"]], "\u201cname\u201d": [[0, "name"]], "\u201cuuid\u201d": [[0, "uuid"]], "\u201ccolor\u201d": [[0, "color"]], "\u201crecalc_section\u201d": [[0, "recalc-section"]], "\u201calignment_section\u201d": [[0, "alignment-section"]], "\u201csort_index\u201d": [[0, "sort-index"]], "\u201cicon\u201d": [[0, "icon"]], "\u201cworkflow_commands\u201d": [[0, "workflow-commands"]], "\u201csensor_commands\u201d": [[0, "sensor-commands"]], "\u201cdefault_visible_views\u201d": [[0, "default-visible-views"]], "\u201cdefault_visible_tabs\u201d": [[0, "default-visible-tabs"]], "Step 4: Test your workspace": [[0, "step-4-test-your-workspace"]], "Guidelines": [[0, "guidelines"]], "Icon guidelines": [[0, "icon-guidelines"]], "FAQ": [[0, "faq"], [2, "faq"], [13, "faq"]], "How can I add icons to the workspace toolbar ?": [[0, "how-can-i-add-icons-to-the-workspace-toolbar"]], "Environments for python scripts": [[1, "environments-for-python-scripts"]], "Creating an environment in the script editor": [[1, "creating-an-environment-in-the-script-editor"]], "Install / uninstall python packages": [[1, "install-uninstall-python-packages"]], "Installation": [[1, "installation"], [13, "installation"]], "Uninstallation": [[1, "uninstallation"]], "Writing and running a script in the environment": [[1, "writing-and-running-a-script-in-the-environment"]], "Editing \u201cmodules.json\u201d file": [[1, "editing-modules-json-file"]], "Creating a package that contains environments": [[1, "creating-a-package-that-contains-environments"]], "Editing the package that contains only script environments": [[1, "editing-the-package-that-contains-only-script-environments"]], "Editing the package that contains contents not in a script environment": [[1, "editing-the-package-that-contains-contents-not-in-a-script-environment"]], "Script editor": [[1, "script-editor"]], "Package manager": [[1, "package-manager"]], "Localization of packages": [[2, "localization-of-packages"]], "Writing translatable scripts": [[2, "writing-translatable-scripts"]], "User-defined script dialogs": [[2, "user-defined-script-dialogs"]], "Text in scripts": [[2, "text-in-scripts"]], "Translating scripts": [[2, "translating-scripts"]], "Generating translatable XLIFF files": [[2, "generating-translatable-xliff-files"]], "Install package \u2018Internationalization\u2019": [[2, "install-package-internationalization"]], "Switch package into \u2018Edit\u2019 mode": [[2, "switch-package-into-edit-mode"]], "Execute script \u2018Update XLIFF files\u2019": [[2, "execute-script-update-xliff-files"]], "Translate XLIFF files": [[2, "translate-xliff-files"]], "Switching package languages": [[2, "switching-package-languages"]], "Enable language": [[2, "enable-language"]], "Selecting an package/application language": [[2, "selecting-an-package-application-language"]], "Is there a shortcut for exporting/importing the XLIFF files ?": [[2, "is-there-a-shortcut-for-exporting-importing-the-xliff-files"]], "Are the translation entries persistent when updated via the \u2018Update XLIFF files\u2019 script ?": [[2, "are-the-translation-entries-persistent-when-updated-via-the-update-xliff-files-script"]], "After the application language is set, the package is not displaying the translations for that language ?": [[2, "after-the-application-language-is-set-the-package-is-not-displaying-the-translations-for-that-language"]], "Creating wizard dialogs": [[3, "creating-wizard-dialogs"]], "What is a wizard dialog": [[3, "what-is-a-wizard-dialog"]], "Creating a simple wizard dialog": [[3, "creating-a-simple-wizard-dialog"]], "Changing the button text": [[3, "changing-the-button-text"]], "Creating wizards with different layouts per step": [[3, "creating-wizards-with-different-layouts-per-step"]], "Final scripts": [[3, "final-scripts"]], "Single Layout Wizard": [[3, "single-layout-wizard"]], "Multi Layout Wizard": [[3, "multi-layout-wizard"]], "GOM Inspect Python API introduction": [[4, "gom-inspect-python-api-introduction"]], "Creating projects": [[4, "creating-projects"]], "Creating parts": [[4, "creating-parts"]], "Adding elements to a part": [[4, "adding-elements-to-a-part"]], "Accessing CAD and actual mesh": [[4, "accessing-cad-and-actual-mesh"]], "Accessing an object\u2019s part": [[4, "accessing-an-object-s-part"]], "Accessing all elements and alignments of a part": [[4, "accessing-all-elements-and-alignments-of-a-part"]], "Accessing elements and alignments of Element in clipboard": [[4, "accessing-elements-and-alignments-of-element-in-clipboard"]], "Alignments": [[4, "alignments"]], "Legacy projects (part-less)": [[4, "legacy-projects-part-less"]], "Measurement series and Measuring environment": [[4, "measurement-series-and-measuring-environment"]], "Reports": [[4, "reports"]], "CAD structure and contents": [[4, "cad-structure-and-contents"]], "CAD assembly structure in the Elements in clipboard": [[4, "cad-assembly-structure-in-the-elements-in-clipboard"]], "Script compatibility": [[4, "script-compatibility"]], "Actual master and All CAD Group proxy": [[4, "actual-master-and-all-cad-group-proxy"]], "Measurement series": [[4, "measurement-series"]], "Tesselate Geometrical Element": [[4, "tesselate-geometrical-element"]], "Access element properties": [[4, "access-element-properties"]], "Explore available properties": [[4, "explore-available-properties"]], "Element properties in VSCode": [[4, "element-properties-in-vscode"]], "Properties of different stages": [[4, "properties-of-different-stages"]], "Element data interfaces": [[4, "element-data-interfaces"]], "Concept": [[4, "concept"]], "Using script dialogs": [[5, "using-script-dialogs"]], "Creating dialogs": [[5, "creating-dialogs"]], "Dialog designer": [[5, "dialog-designer"]], "Dialog layout": [[5, "dialog-layout"]], "Editing the grid": [[5, "editing-the-grid"]], "Spacers": [[5, "spacers"]], "Widgets": [[5, "widgets"]], "Inserting and removing widgets": [[5, "inserting-and-removing-widgets"]], "Configuring widgets": [[5, "configuring-widgets"]], "Editing already created dialogs": [[5, "editing-already-created-dialogs"]], "Dialog widgets": [[5, "dialog-widgets"]], "Use of the __doc__ string": [[5, "use-of-the-doc-string"]], "Control widget": [[5, "control-widget"]], "Control widget elements": [[5, "control-widget-elements"]], "Control button properties": [[5, "control-button-properties"]], "Status label": [[5, "status-label"]], "Specific widgets": [[5, "specific-widgets"]], "Description field (label) widget": [[5, "description-field-label-widget"]], "Continuous text widget": [[5, "continuous-text-widget"]], "Displaying keywords in a continuous text widget": [[5, "displaying-keywords-in-a-continuous-text-widget"]], "Internal representation of a dialog with text widget": [[5, "internal-representation-of-a-dialog-with-text-widget"]], "Image widget": [[5, "image-widget"]], "Internal representation of a dialog with image widget": [[5, "internal-representation-of-a-dialog-with-image-widget"]], "Log widget": [[5, "log-widget"]], "Progress bar widget": [[5, "progress-bar-widget"]], "Element name widget": [[5, "element-name-widget"]], "Integer widget": [[5, "integer-widget"]], "Decimal widget": [[5, "decimal-widget"]], "Text entry field": [[5, "text-entry-field"]], "Slider widget": [[5, "slider-widget"]], "Checkbox widget": [[5, "checkbox-widget"]], "File widget": [[5, "file-widget"]], "Date widget": [[5, "date-widget"]], "Color widget": [[5, "color-widget"]], "Unit widget": [[5, "unit-widget"]], "Selection element widget": [[5, "selection-element-widget"]], "Selection list widget": [[5, "selection-list-widget"]], "Button widget": [[5, "button-widget"]], "Radio button widget": [[5, "radio-button-widget"]], "Abort button widget": [[5, "abort-button-widget"]], "Tolerances widget": [[5, "tolerances-widget"]], "File system browser widget": [[5, "file-system-browser-widget"]], "Executing dialogs": [[5, "executing-dialogs"]], "Dialog commands": [[5, "dialog-commands"]], "Break dialog (execute)": [[5, "break-dialog-execute"]], "Extendable break dialog (create and show)": [[5, "extendable-break-dialog-create-and-show"]], "Info dialog (create, open and close)": [[5, "info-dialog-create-open-and-close"]], "Dialog results": [[5, "dialog-results"]], "Custom results": [[5, "custom-results"]], "Configuring dialog widgets": [[5, "configuring-dialog-widgets"]], "Event handler functions": [[5, "event-handler-functions"]], "Registering event handlers": [[5, "registering-event-handlers"]], "Closing dialogs from within the event handler": [[5, "closing-dialogs-from-within-the-event-handler"]], "Using a timer to activate the event handler": [[5, "using-a-timer-to-activate-the-event-handler"]], "Determining the existing widget attributes": [[5, "determining-the-existing-widget-attributes"]], "Wizards": [[5, "wizards"]], "Control widgets": [[5, "control-widgets"]], "Using script resources": [[6, "using-script-resources"]], "Importing resources": [[6, "importing-resources"]], "Usage in scripts": [[6, "usage-in-scripts"]], "See also": [[6, "see-also"]], "Scripted actuals": [[7, "scripted-actuals"]], "Example: Simple offset point": [[7, "example-simple-offset-point"]], "dialog": [[7, "dialog"]], "calculation": [[7, "calculation"]], "Running the example": [[7, "running-the-example"]], "Further reading": [[7, "further-reading"]], "Scripted checks": [[8, "scripted-checks"]], "Introduction": [[8, "introduction"], [9, "introduction"], [11, "introduction"]], "Writing a scripted check": [[8, "writing-a-scripted-check"]], "Useful dialog widgets": [[8, "useful-dialog-widgets"]], "\u201cSpecial\u201d parameters": [[8, "special-parameters"]], "Types of scripted checks": [[8, "types-of-scripted-checks"]], "Types": [[9, "types"]], "Usage": [[9, "usage"]], "Set element creation type": [[9, "set-element-creation-type"]], "Code structure": [[9, "code-structure"]], "Next steps": [[9, "next-steps"]], "Scripted elements": [[10, "scripted-elements"]], "Tokens on scripted elements": [[11, "tokens-on-scripted-elements"]], "Instructions": [[11, "instructions"]], "How user-defined tokens are set": [[11, "how-user-defined-tokens-are-set"]], "Usage of user-defined tokens in scripts": [[11, "usage-of-user-defined-tokens-in-scripts"]], "Usage in user-defined checks": [[11, "usage-in-user-defined-checks"]], "Testing add-ons": [[12, "testing-add-ons"]], "Why testing?": [[12, "why-testing"]], "File structure": [[12, "file-structure"]], "Writing a test script": [[12, "writing-a-test-script"]], "Running all tests": [[12, "running-all-tests"]], "Using Visual Studio Code as an add-on editor": [[13, "using-visual-studio-code-as-an-add-on-editor"]], "Setup": [[13, "setup"]], "Connecting": [[13, "connecting"]], "Editing": [[13, "editing"]], "Creating scripts": [[13, "creating-scripts"]], "Executing scripts": [[13, "executing-scripts"]], "Recording commands": [[13, "recording-commands"]], "Inserting elements": [[13, "inserting-elements"]], "Inserting keywords": [[13, "inserting-keywords"]], "Debugging": [[13, "debugging"]], "Start debugging": [[13, "start-debugging"]], "User defined script dialogs": [[13, "user-defined-script-dialogs"]], "Create new user defined script dialog": [[13, "create-new-user-defined-script-dialog"]], "Edit user defined script dialog": [[13, "edit-user-defined-script-dialog"]], "Configuration": [[13, "configuration"]], "How do I set a shortcut to toggle the recording mode ?": [[13, "how-do-i-set-a-shortcut-to-toggle-the-recording-mode"]], "How do I set shortcuts for starting the current script in the GOM host ?": [[13, "how-do-i-set-shortcuts-for-starting-the-current-script-in-the-gom-host"]], "Script editing": [[13, "script-editing"]], "Can I use local workspaces from disk instead of the application script database for my project ?": [[13, "can-i-use-local-workspaces-from-disk-instead-of-the-application-script-database-for-my-project"]], "Dialog editing": [[13, "dialog-editing"]], "I cannot edit all aspects of the user defined script dialogs in visual studio code ?": [[13, "i-cannot-edit-all-aspects-of-the-user-defined-script-dialogs-in-visual-studio-code"]], "Troubleshooting": [[13, "troubleshooting"]], "When using IntelliSense completion, the keyword list stalls": [[13, "when-using-intellisense-completion-the-keyword-list-stalls"]], "When starting both the application and a script from within Visual Studio Code, crashes can happen": [[13, "when-starting-both-the-application-and-a-script-from-within-visual-studio-code-crashes-can-happen"]], "GOM Inspect Add-On Development Documentation": [[14, "gom-inspect-add-on-development-documentation"]], "How-to Guides": [[14, null]], "Python API Examples": [[14, null]], "Python API Specification": [[14, null]], "GOM Inspect Python API documentation": [[15, "gom-inspect-python-api-documentation"]], "Image processing": [[15, "image-processing"]], "gom.api.project": [[15, "gom-api-project"]], "gom.api.imaging": [[15, "gom-api-imaging"]], "Checks": [[15, "checks"]], "gom.api.scripted_checks_util": [[15, "gom-api-scripted-checks-util"]], "gom.Resource API": [[16, "gom-resource-api"]], "Summmary": [[16, "summmary"]], "Class definition": [[16, "class-definition"]], "Scripted elements API": [[17, "scripted-elements-api"]], "The dialog function": [[17, "the-dialog-function"]], "Signature": [[17, "signature"], [17, "id1"]], "Parameter context": [[17, "parameter-context"], [17, "id2"]], "Parameter params": [[17, "parameter-params"]], "Return value": [[17, "return-value"], [17, "id3"]], "Calculating a preview": [[17, "calculating-a-preview"]], "The calculation function": [[17, "the-calculation-function"]], "Attribute context.data[]": [[17, "attribute-context-data"]], "Attribute context.result[]": [[17, "attribute-context-result"]], "Scripted actuals - Return values": [[17, "scripted-actuals-return-values"]], "Point": [[17, "point"]], "Distance": [[17, "distance"]], "Value Element": [[17, "value-element"]], "Circle": [[17, "circle"]], "Curve": [[17, "curve"]], "Surface Curve": [[17, "surface-curve"]], "Section": [[17, "section"]], "Point Cloud": [[17, "point-cloud"]], "Surface": [[17, "surface"]], "Cone": [[17, "cone"]], "Cylinder": [[17, "cylinder"]], "Volume defects": [[17, "volume-defects"]], "2D Volume Defects": [[17, "d-volume-defects"]], "Volume": [[17, "volume"]], "Volume material map": [[17, "volume-material-map"]], "Volume Section": [[17, "volume-section"]], "Scripted checks - Return values": [[17, "scripted-checks-return-values"]], "Supported Element Types": [[17, "supported-element-types"]], "Scalar": [[17, "scalar"]], "Scalar Surface": [[17, "scalar-surface"]], "Scalar Curve": [[17, "scalar-curve"]], "data_interfaces": [[18, "data-interfaces"]], "Examples of this category": [[18, null], [21, null], [27, null], [29, null], [31, null], [33, null], [38, null]], "check_results_data_array": [[19, "check-results-data-array"]], "Short description": [[19, "short-description"], [20, "short-description"], [22, "short-description"], [23, "short-description"], [24, "short-description"], [25, "short-description"], [28, "short-description"], [30, "short-description"], [32, "short-description"], [34, "short-description"], [35, "short-description"], [36, "short-description"], [37, "short-description"], [39, "short-description"], [40, "short-description"], [41, "short-description"]], "Highlights": [[19, "highlights"], [20, "highlights"], [22, "highlights"], [23, "highlights"], [24, "highlights"], [25, "highlights"], [28, "highlights"], [30, "highlights"], [32, "highlights"], [35, "highlights"], [36, "highlights"], [37, "highlights"], [39, "highlights"], [40, "highlights"], [41, "highlights"]], "Related": [[19, "related"], [20, "related"], [22, "related"], [23, "related"], [24, "related"], [25, "related"], [28, "related"], [30, "related"], [32, "related"], [34, "related"], [35, "related"], [36, "related"], [37, "related"], [39, "related"], [40, "related"], [41, "related"]], "volume_section_image_data": [[20, "volume-section-image-data"]], "dialog_widgets": [[21, "dialog-widgets"]], "dropdown_widget_dynamic": [[22, "dropdown-widget-dynamic"]], "explorer_selected_elements_in_dialog": [[23, "explorer-selected-elements-in-dialog"]], "unit_dialog_event_handler": [[24, "unit-dialog-event-handler"]], "widget_visibility": [[25, "widget-visibility"]], "Added metadata:": [[26, "added-metadata"]], "myst:\nhtml_meta:\n\u201cdescription\u201d: \u201cExamples for using the GOM Inspect 2023 Add-on Python API\u201d\n\u201ckeywords\u201d: \u201cMetrology, GOM Inspect, Python API, GOM API, Scripting, Packages, Add-ons, Examples\u201d": [[26, "myst-html-meta-description-examples-for-using-the-gom-inspect-2023-add-on-python-api-keywords-metrology-gom-inspect-python-api-gom-api-scripting-packages-add-ons-examples"]], "Overview": [[26, "overview"]], "How the examples are structured": [[26, "how-the-examples-are-structured"]], "Example projects": [[26, "example-projects"]], "Examples by topic": [[26, "examples-by-topic"]], "misc": [[27, "misc"]], "dialog_reopen_example": [[28, "dialog-reopen-example"]], "script_icons": [[29, "script-icons"]], "script_icon_from_file": [[30, "script-icon-from-file"]], "script_resources": [[31, "script-resources"]], "resource_api_example": [[32, "resource-api-example"]], "scripted_actuals": [[33, "scripted-actuals"]], "offset_point_simple": [[34, "offset-point-simple"]], "offset_point_v2": [[35, "offset-point-v2"]], "Preview calculation": [[35, "preview-calculation"]], "Status and error handling": [[35, "status-and-error-handling"]], "Stageful calculation and error handling": [[35, "stageful-calculation-and-error-handling"]], "Storing generic element data": [[35, "storing-generic-element-data"]], "scripted_element_progress": [[36, "scripted-element-progress"]], "trimesh_deform_mesh": [[37, "trimesh-deform-mesh"]], "Dialog: Element filter": [[37, "dialog-element-filter"]], "Calculation: Mesh deformation with trimesh": [[37, "calculation-mesh-deformation-with-trimesh"]], "scripted_checks": [[38, "scripted-checks"]], "scripted_curve_check": [[39, "scripted-curve-check"]], "scripted_scalar_check": [[40, "scripted-scalar-check"]], "scripted_surface_check": [[41, "scripted-surface-check"]]}, "indexentries": {"built-in function": [[15, "gom.api.imaging.compute_epipolar_line"], [15, "gom.api.imaging.compute_pixels_from_point"], [15, "gom.api.imaging.compute_point_from_pixels"], [15, "gom.api.project.get_image_aquisition"], [15, "gom.api.scripted_checks_util.is_curve_checkable"], [15, "gom.api.scripted_checks_util.is_scalar_checkable"], [15, "gom.api.scripted_checks_util.is_surface_checkable"]], "gom.api.imaging.compute_epipolar_line()": [[15, "gom.api.imaging.compute_epipolar_line"]], "gom.api.imaging.compute_pixels_from_point()": [[15, "gom.api.imaging.compute_pixels_from_point"]], "gom.api.imaging.compute_point_from_pixels()": [[15, "gom.api.imaging.compute_point_from_pixels"]], "gom.api.project.get_image_aquisition()": [[15, "gom.api.project.get_image_aquisition"]], "gom.api.scripted_checks_util.is_curve_checkable()": [[15, "gom.api.scripted_checks_util.is_curve_checkable"]], "gom.api.scripted_checks_util.is_scalar_checkable()": [[15, "gom.api.scripted_checks_util.is_scalar_checkable"]], "gom.api.scripted_checks_util.is_surface_checkable()": [[15, "gom.api.scripted_checks_util.is_surface_checkable"]], "__init__() (gom.resource method)": [[16, "gom.Resource.__init__"]], "bytesize() (gom.resource method)": [[16, "gom.Resource.byteSize"]], "cleanup() (gom.resource.resource static method)": [[16, "gom.Resource.Resource.cleanup"]], "close() (gom.resource method)": [[16, "gom.Resource.close"]], "exists() (gom.resource method)": [[16, "gom.Resource.exists"]], "gom.resource (built-in class)": [[16, "gom.Resource"]], "isloaded() (gom.resource method)": [[16, "gom.Resource.isLoaded"]], "keepinmemory() (gom.resource method)": [[16, "gom.Resource.keepInMemory"]], "list() (gom.resource.resource static method)": [[16, "gom.Resource.Resource.list"]], "open() (gom.resource method)": [[16, "gom.Resource.open"]], "save() (gom.resource method)": [[16, "gom.Resource.save"]], "saveasuserresource() (gom.resource method)": [[16, "gom.Resource.saveAsUserResource"]]}})
\ No newline at end of file