Metadata and Schemas

A schema specifies what metadata should be recorded when performing an action. The metadata should contain all the information required to reproduce what a user did.

Simple schemas can be created and edited using the graphical schema editor:

Editing an action using the schema editor

Editing an action using the schema editor

To access more advanced features like arrays and conditions, users can instead edit the schema directly in a text-based editor by setting the Use Schema Editor setting to No in their preferences.

Disabling the graphical schema editor

Disabling the graphical schema editor

Schemas are defined using JSON. They consist of nested JSON objects, with each object having a title and a type attribute, and more attributes depending on the type (note: when discussing JSON, what is called an “attribute” here is usually called a “property”, this would be ambiguous however, as the metadata fields of an object are also called properties in SampleDB). The root object of each schema must have the object type and contain at least a text attribute called name, as shown here:

A minimal schema containing only the object name
{
  "type": "object",
  "title": "Object Information",
  "properties": {
    "name": {
      "title": "Name",
      "type": "text"
    }
  },
  "propertyOrder": ["name"],
  "required": ["name"]
}

Data types

Currently, the following basic data types are supported for metadata:

  • Texts

  • Booleans

  • Quantities

  • Datetimes

These can be used to form the following composite data types:

  • Arrays

  • Objects

Additionally, there are special data types:

  • Tags

  • Hazards

  • plotly Charts

  • User References

  • Object References
    • Sample References

    • Measurement References

    • Generic Object References

In the following, each data type and the attributes in a schema of each type are listed.

Objects

Objects represent complex composite data types containing named properties. All SampleDB schemas start with an object (the root object), which consists of various other properties, mapping the name of each property to its subschema. In the minimal example above, the root object contains only a name, but you can add many more properties, as long as they all have a unique name.

A minimal schema containing only the object name
{
  "type": "object",
  "title": "Example Object Information",
  "properties": {
    "name": {
      "title": "Name",
      "type": "text"
    }
    "created": {
      "title": "Creation Datetime",
      "type": "datetime"
    }
  },
  "propertyOrder": ["name", "created"],
  "required": ["name"]
}

Object instances are JSON objects mapping the property names to the property data.

An object instance for the schema above.
{
  "name": {
    "_type": "text",
    "text": "Demo Object"
  }
  "created": {
    "_type": "datetime",
    "utc_datetime": "2021-07-22 01:23:45"
  }
}

type

This sets the type for this subschema as a JSON string and must be set to object.

title

The title for the object as a JSON string or object, e.g. "Sample Information" or {"en": "Simulation Parameters"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given object property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

properties

This JSON object maps names to the subschemas for other properties. The names may consist of lowercase characters, digits and underscores, but must not begin or end with an underscore. These names are, for example, used for the advanced search.

The properties attribute from the example above.
"properties": {
  "name": {
    "title": "Name",
    "type": "text"
  }
  "created": {
    "title": "Creation Datetime",
    "type": "datetime"
  }
}

Note

As mentioned above, the root object must have a required property called name with the type "text". This is the object name used on SampleDB to represent the object. Even though it is not process-specific, it might have process-specific restrictions, which is why it needs to be included in the schema.

Note

Try to use consistent property names between schemas, as this can greatly simplify searches, automated data entry or data analysis.

propertyOrder

As the properties JSON objects does not necessarily preserve the order of properties when processed by SampleDB, this attribute can set the desired order of properties when creating or displaying objects created with this schema. It is optional, though recommended to ensure consistent behavior. The property names are given as JSON strings in a JSON array, e.g. ["name", "created"].

required

This JSON array lists the names of all properties which must be set for an object to be valid, e.g. ["name"] if only the name property must be set.

Note

For the root object, the name property must be required. If a hazards property exists in the root object, it must also be required.

Note

Sometimes, the behavior of required properties of type text may appear confusing, as even an empty text ("") is technically a text. If you want a text property to be non-empty, you can set a minLength for it in addition to setting it as required. See the text data type below for more information.

default

An object instance may be provided as the default attribute, e.g. for creating a new object. This should be a JSON object mapping each property name to its default data. The default must be a valid instance of the object schema, so the properties in it must fulfill all restrictions from their individual subschemas.

A default attribute for the example above.
"default": {
  "name": {
    "_type": "text",
    "text": "Demo Object"
  }
  "created": {
    "_type": "datetime",
    "utc_datetime": "2021-07-22 01:23:45"
  }
}

displayProperties

This attribute can be set to a JSON array containing the names of properties that should be displayed in a list of objects for the action this schema belongs to.

Note

This attribute may only be set for the root object.

Note

For some data types, it may be impossible to display them in the table, e.g. due to size restrictions. If you encounter issues with a property that should be possible to display but isn’t shown correctly, you can report it on GitHub.

batch

This attribute is a boolean that sets whether or not the action for this root object should create a batch of objects. If set to true, the user will be able to enter how many objects should be created during object creation, and that number of objects will be created with identical data except for the name. By default, it is set to false.

Note

This attribute may only be set for the root object.

batch_name_format

If the batch attribute is set to true, this string attribute sets the format for the suffix that will be attached to the name of the objects created as a batch. It must follow the Python string format syntax and will be provided with the index of the individual object in that batch (starting with 1). If no batch_name_format is provided, the index will be used by itself. If the user set the name as Demo and were to create three items in a batch, then the default would result in the names Demo1, Demo2 and Demo3, while a batch_name_format set to "-{:03d}" would result in the names Demo-001, Demo-002 and Demo-003.

Note

This attribute may only be set for the root object.

notebookTemplates

A JSON array containing information about Jupyter notebook templates. For more information, see JupyterHub Support.

Note

This attribute may only be set for the root object.

Arrays

Array properties represent a list of properties of the same type called items. While each property in an object must have an individual subschema, all items in an array share their subschema.

An array property containing texts, with a default and length restrictions
{
  "title": "Notes",
  "type": "array",
  "items": {
    "title": "Note",
    "type": "text"
  },
  "minItems": 1,
  "maxItems": 10,
  "default": [
    {
      "_type": "text",
      "text": "First default note"
    },
    {
      "_type": "text",
      "text": "Second default note"
    }
  ]
}

type

This sets the type for this subschema as a JSON string and must be set to array.

title

The title for the array as a JSON string or object, e.g. "Preparation Steps" or {"en": "Notes"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given array property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

items

This JSON object contains the subschema for the items in this array. Arrays may contain all other data types (aside from the special types tags and hazards, which may only occur in the root object).

The items attribute from the example above.
"items": {
  "title": "Note",
  "type": "text"
}

minItems

A number that sets how many items must at least be present in the array for it to be valid, e.g. 1. By default, there is no minimum number of items.

maxItems

A number that sets how many items must at most be present in the array for it to be valid, e.g. 10. By default, there is no limit to the number of items.

default

A JSON array containing the default data for the individual items. See also the defaultItems attribute below.

The default attribute from the example above.
"default": [
  {
    "_type": "text",
    "text": "First default note"
  },
  {
    "_type": "text",
    "text": "Second default note"
  }
]

defaultItems

If the default attribute is not set, this number can be used to set how many items should be present by default, e.g. if it is common to have at least one item, but this is not a strict requirement, defaultItems could be set to 1.

style

This attribute is a string indicating how the array should be displayed. By default, the items will be shown one after another, but sometimes a different behavior may be desired. If the items are objects, using the table style may be useful to create a table with the items as rows and their properties in the columns. Alternatively, if the items should be in the columns and their properties should be in the rows, the horizontal_table style can be used. If the items are neither objects nor arrays, the list style may be useful to create a simple list.

Note

Using a style other than the default may lead to issues when entering or viewing object data. Please test the action and how its objects are displayed. If you encounter issues with a style, you can report it on GitHub.

Texts

Text properties represent various types of textual data:

  • Single line texts

  • Multi line texts

  • Rich text using Markdown

  • A selection from a list of predefined texts (displayed as a dropdown field)

A sample name as a text property with a default, a pattern and length restrictions
{
  "title": "Sample Name",
  "type": "text",
  "minLength": 1,
  "maxLength": 100,
  "default": "Sample-",
  "pattern": "^.+$"
}
A sample description allowing multiple lines of text
{
  "title": "Description",
  "type": "text",
  "multiline": true
}
A sample description allowing Markdown content
{
  "title": "Description",
  "type": "text",
  "markdown": true
}
A measurement option using predefined choices
{
  "title": "Measurement Option",
  "type": "text",
  "choices": [
    "Option A",
    "Option B"
  ]
}

type

This sets the type for this subschema as a JSON string and must be set to text.

title

The title for the text as a JSON string or object, e.g. "Description" or {"en": "Substrate"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the field when creating or editing an object using this schema, as a JSON string or object, e.g. "Please describe the process in detail." or {"en": "Can be filled in later."}.

placeholder

The placeholder for the text when creating or editing an object using this schema, as a JSON string or object, e.g. "Description" or {"en": "Substrate"}.

default

The default value for this property, as a JSON string or object, e.g. "Example" or {"en": "Example"}. If there are choices defined for this property, then the default must be one of the choices.

The default attribute from one of the examples above
"default": "Sample-"

minLength

This attribute sets the minimum number of characters for the value of this property, e.g. 1. By default, there is no minimum length.

maxLength

This attribute sets the maximum number of characters for the value of this property, e.g. 1. By default, there is no maximum length.

pattern

A JSON string containing a regular expression limiting what values are valid for this property, e.g. ^Sample-[0-9]{4}$ to ensure only values starting with Sample- followed by a four digit number will be valid.

languages

Either a JSON array containing the allowed language codes for this property, e.g. ["en", "de"] or the JSON string "all" to allow all languages enabled for user input. By default, this attribute is set to ["en"] only allowing english language input.

choices

A JSON array of acceptable values, either as JSON objects or JSON strings. If choices are provided, the value for this property must be one of the choices and a dropdown menu will be used to let the user select the choice. If this property is not required, not selecting a choice at all and therefore not providing a value for this property will also be valid.

The choices attribute from one of the examples above
"choices": [
  "Option A",
  "Option B"
]

Note

For properties with choices set, you cannot provide a placeholder value and should not set a minLength, maxLength or pattern. Setting choices, multiline and markdown are all mutually exclusive.

multiline

This attribute is a boolean that sets whether or not the value of this property may contain multiple lines. By default, this is false and the field when creating or editing an object using this schema will be for a single line only.

Note

Setting choices, multiline and markdown are all mutually exclusive.

markdown

This attribute is a boolean that sets whether or not the value of this property should be rich text based on the Markdown syntax. If this attribute is true, users will be able to input multiple lines and use a Markdown editor to include formatting, images and other rich text elements in the value of this property. By default, this is false.

Note

Setting choices, multiline and markdown are all mutually exclusive.

Booleans

Booleans represent a value that is either true or false.

A boolean property with a default
{
  "title": "Lid Open?",
  "type": "bool",
  "default": true
}

type

This sets the type for this subschema as a JSON string and must be set to bool.

title

The title for the boolean as a JSON string or object, e.g. "Pressurization" or {"en": "Target Set"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the field when creating or editing an object using this schema, as a JSON string or object, e.g. "Set if chamber was pressurized." or {"en": "Check box if a target was set"}.

default

The default value for this property as a boolean, so true or false.

Quantities

Properties of the quantity type represent physical quantities and unitless numbers. The units attribute is mandatory, so for unitless numbers it must be set to 1.

A temperature property with a default of 25°C (298.15K)
{
  "title": "Temperature",
  "type": "quantity",
  "units": "degC",
  "default": 298.15
}

type

This sets the type for this subschema as a JSON string and must be set to quantity.

title

The title for the quantity as a JSON string or object, e.g. "Temperature" or {"en": "Detector Distance"}.

placeholder

The placeholder for the text when creating or editing an object using this schema, as a JSON string or object, e.g. "Temperature in K" or {"en": "Detector Distance (horizontal)"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the field when creating or editing an object using this schema, as a JSON string or object, e.g. "Temperature in measurement chamber." or {"en": "Horizontal distance between sample and detector"}.

default

The default value for this property as a number. This should be the value in base units, so if units is set to nm and you want to set a default of 10nm, you need to set default to 0.00000001 as it will be interpreted in meters.

units

A JSON string containing the units for this property, e.g. nm or degC.

Note

These units will be parsed using the pint Python Package with additional units defined by SampleDB.

Datetimes

Datetime properties represent points in time. They are stored using YYYY-MM-DD hh:mm:ss notation and UTC, though users may enter and display them in differing timezones.

A datetime property with a default value
{
  "title": "Creation Datetime",
  "type": "datetime",
  "default": "2018-12-05 15:38:12"
}

type

This sets the type for this subschema as a JSON string and must be set to datetime.

title

The title for the datetime as a JSON string or object, e.g. "Creation Date" or {"en": "Use Before"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the field when creating or editing an object using this schema, as a JSON string or object, e.g. "Use experiment starting time" or {"en": "Include cool down time in estimate"}.

default

A default value for the property, as a JSON string using YYYY-MM-DD hh:mm:ss notation and UTC, e.g. "2021-07-23 08:00:00". If no default is given, the current date and time when creating or editing an object using this schema will be used as the default.

Tags

Tags are keywords that can be used to categorize and quickly find objects relating to a specific topic. They may only be used as a property of the root object with the name tags. The tag values themselves may only consist of lowercase characters, digits and underscores.

A tags property with default tags
{
  "title": "Tags",
  "type": "tags",
  "default": ["tag1", "tag2"]
}

type

This sets the type for this subschema as a JSON string and must be set to tags.

title

The title for the tags as a JSON string or object, e.g. "Tags" or {"en": "Keywords"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

default

A JSON array containing default tags as strings, e.g. [] or ["demo", "documentation"]. There must be no duplicates in the array and as noted above, tags are limited to lowercase characters, digits and underscores.

Hazards

Hazards allow users to declare whether or not the substance represented by the object poses any hazards by selecting the relevant GHS pictograms. Hazards may only be used as a property of the root object with the name hazards. If such a property exists, it must be required to avoid any ambiguity, so that users have to explicitly declare that a substance poses no hazards instead of just not entering any.

A hazards property
{
  "title": "GHS hazards",
  "type": "hazards"
}

type

This sets the type for this subschema as a JSON string and must be set to hazards.

title

The title for the hazards as a JSON string or object, e.g. "GHS hazards" or {"en": "Hazards (GHS)"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

note

A note to display below the hazards selection when creating or editing an object using this schema, as a JSON string or object, e.g. "See lab guidelines" or {"en": "Please provide additional information in the description."}.

plotly Charts

Properties of this type allow users to store JSON data that can be rendered by plotly. This is most useful in combination with automated data entry as opposed to manually creating and entering the JSON data.

A plotly chart from the plotly documentation
{
  "data": [
    {
      "x": [
        "giraffes",
        "orangutans",
        "monkeys"
      ],
      "y": [
        20,
        14,
        23
      ],
      "type": "bar"
    }
  ]
}

For more information on the plotly JSON format, see the JSON chart schema.

A plotly chart property
{
  "title": "Temperature",
  "type": "plotly_chart"
}

type

This sets the type for this subschema as a JSON string and must be set to plotly_chart.

title

The title for the plotly chart as a JSON string or object, e.g. "Temperature" or {"en": "Z Distance Movement"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the JSON field when creating or editing an object using this schema, as a JSON string or object, e.g. "Will be filled by bot" or {"en": "Upload raw log file as well"}.

User References

Properties of this type allow you to reference SampleDB users.

A user reference property
{
  "title": "Client",
  "type": "user"
}

type

This sets the type for this subschema as a JSON string and must be set to user.

title

The title for the property as a JSON string or object, e.g. "Client" or {"en": "Principal Investigator"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the field when creating or editing an object using this schema, as a JSON string or object, e.g. "For external users, leave blank and fill in information below" or {"en": "Remember to set as responsible user as well"}.

default

A JSON number containing the user ID to be used as default selection, or a JSON string "self" to denote that the user who is currently creating or editing the object should be the default.

Object References

Properties of this type allow you to reference other objects, e.g. to denote a precursor material or a dataset used for a simulation. Using action_type_id or action_id you can limit which objects may be referenced using this property.

An object reference property
{
  "title": "Measured Object",
  "type": "object_reference"
}

type

This sets the type for this subschema as a JSON string and must be set to object_reference.

title

The title for the property as a JSON string or object, e.g. "Precursor" or {"en": "Calibration Measurement"}.

may_copy

This attribute is a boolean that sets whether or not the data for the given property may be copied when using the Use as template functionality in SampleDB. By default, it is set to true.

dataverse_export

This attribute is a boolean that controls whether this property should be exported as part of a :ref`dataverse_export` or not, although the exporting user will still have the choice to enable or disable this property during the export. By default, it is set to false.

conditions

This attribute is a JSON array containing a list of conditions which need to be fulfilled for this property to be available to the user. By default, no conditions need to be met. For examples and more information, see Conditional Properties.

note

A note to display below the field when creating or editing an object using this schema, as a JSON string or object, e.g. "Leave blank if no precursor was used." or {"en": "Select the associated calibration measurement"}.

action_type_id

This attribute is a number that sets the ID of an action type to limit which actions an object referenced by this property may have been created with, e.g. -99 to limit the property to samples.

action_id

This attribute is a number that sets the ID of an action to limit that only objects created with that action may be referenced by this property, e.g. 1.

Sample References

Properties of this type are a special case of object reference, limited to referencing samples. The same can be achieved using an object reference with action_type_id set to -99. These properties support the same attributes as those of type object_reference, aside from action_id and action_type_id. Their type must be sample.

A sample reference property
{
  "title": "Previous Sample",
  "type": "sample"
}

Measurement References

Properties of this type are a special case of object reference, limited to referencing measurements. The same can be achieved using an object reference with action_type_id set to -98. These properties support the same attributes as those of type object_reference, aside from action_id and action_type_id. Their type must be measurement.

A measurement reference property
{
  "title": "Preparatory Measurement",
  "type": "measurement"
}

Conditional Properties

Some properties might only sometimes be needed, based on some conditions, such as a particular setting of an instrument. Properties can contain conditions like this, consisting of a JSON object with a type and additional information depending on the type of condition.

A schema with a conditional property
{
  'title': 'Example Object',
  'type': 'object',
  'properties': {
    'name': {
      'title': 'Object Name',
      'type': 'text',
      'languages': ['en', 'de']
    },
    'dropdown': {
      'title': 'Dropdown',
      'type': 'text',
      'choices': [
        {'en': 'A'},
        {'en': 'B'},
      ],
      'default': {'en': 'A'}
    },
    'conditional_text': {
      'title': 'Conditional Text',
      'type': 'text',
      'markdown': true,
      'conditions': [
        {
          'type': 'choice_equals',
          'property_name': 'dropdown',
          'choice': {'en': 'B'}
        }
      ]
    }
  },
  'required': ['name']
}

In the example schema above the property conditional_text will only be enabled if its choice_equals condition is fulfilled, that is if the dropdown property has the value {'en': 'B'} selected.

The following types of conditions are supported by SampleDB:

choice_equals

For this type of condition, the property_name attribute must be the name of another property, in the same object as the property the condition is for. The property of that name must be a property of type text with the choices attribute set. The condition must have a choice attribute that must be one of those choices, and for the condition to be fulfilled that choice must be selected.

A choice_equals condition
{
  'type': 'choice_equals',
  'property_name': 'dropdown',
  'choice': {'en': 'B'}
}

user_equals

For this type of condition, the property_name attribute must be the name of another property, in the same object as the property the condition is for. The property of that name must be a property of type user. The condition must have a user_id attribute that must be the ID of a user, and for the condition to be fulfilled that user must be selected.

A user_equals condition
{
  'type': 'user_equals',
  'property_name': 'client',
  'user_id': 1
}

If the user_id is set to null instead, the condition will be fulfilled if no user has been selected.

A user_equals condition for not having selected a user
{
  'type': 'user_equals',
  'property_name': 'client',
  'user_id': null
}

bool_equals

For this type of condition, the property_name attribute must be the name of another property, in the same object as the property the condition is for. The property of that name must be a property of type bool. The condition must have a value attribute that must be either true or false, and for the condition to be fulfilled the property must also be true or false, correspondingly.

A bool_equals condition
{
  'type': 'bool_equals',
  'property_name': 'heating_on',
  'value': true
}

object_equals

For this type of condition, the property_name attribute must be the name of another property, in the same object as the property the condition is for. The property of that name must be a property of type object_reference, sample or measurement. The condition must have a object_id attribute that must be the ID of an object, and for the condition to be fulfilled that object must be selected.

An object_equals condition
{
  'type': 'object_equals',
  'property_name': 'precursor',
  'object_id': 1
}

If the object_id is set to null instead, the condition will be fulfilled if no user has been selected.

An object_equals condition for not having selected an object
{
  'type': 'object_equals',
  'property_name': 'precursor',
  'object_id': null
}

Note

If you need a new type of conditions, please open an issue on GitHub to let us know.