Tetra IDBS E-Workbook Connector
The Tetra IDBS E-Workbook Connector provides bi-directional communication between IDBS’s E-Workbook electronic lab notebook (ELN) and the Tetra Data Platform (TDP). The integration is driven by a user external action from within the E-Workbook’s spreadsheets, and can facilitate data transfer between IDBS E-Workbook and the TDP.
Architecture
The following diagram shows an example workflow for the Tetra IDBS E-Workbook Connector.
The diagram shows the following process:
- A scientist begins an experiment preparation in their IDBS E-Workbook spreadsheet and initiates an action to send the spreadsheet data to the TDP through the Teta IDBS E-Workbook Connector.
- Tetra Data Pipelines transform this data into an experimental method to be sent to other Tetra Integrations to be transferred to a compatible instrument control system.
- The scientist starts the experiment with method information pre-populated and initiates data generation from the instruments that are integrated with the TDP.
- Tetra Integrations upload the data to the TDP.
- After the data is ingested by the TDP and transformed into a harmonized Intermediate Data Schema (IDS), IDBS E-Workbook users can press a custom action button in the IDBS E-Workbook spreadsheet to populate it with data pulled from the TDP through the Tetra IDBS E-Workbook Connector.
NOTE
The Tetra IDBS E-Workbook Connector is responsible for running steps 1 and 5 and can be added as External Actions to a spreadsheet by using the IDBS Spreadsheet Designer. These actions are customizable in the Connector configuration by using DataWeave scripts. Connector users with suitable privileges (administrator or DataWeave administrator) can modify the DataWeave scripts themselves. The Connector provides a user interface for editing and viewing existing DataWeave scripts.
Prerequisites
To install the Tetra IDBS E-Workbook Connector, the following is required:
- IDBS E-Workbook version 10.5.x or higher (on-premises or cloud based)
- Administrator permissions in both your IDBS E-Workbook and TDP environments
Installation and Upgrades
To install a new Tetra IDBS E-Workbook Connector, or to upgrade to the latest Connector version, see IDBS Connector - Installation and IDBS Connector - Admin Configuration.
Connector Concepts
DataWeave
The DataWeave language is a functional language for performing transformations between different representations of data. It can take XML, CSV or JSON data and convert it to a supported DataWeave format. This functionality provides a powerful tool to programmatically tailor exactly how your data in the TDP should be mapped to specific IDBS spreadsheets while minimizing the security risks that a language like Python might have.
Actions, Scripts, and Templates
- Action: An action is what is to be performed by the trigger of the IDBS E-Workbook Custom Action. An action will execute one or more scripts.
- Script: A script holds the code logic (DataWeave or Query DSL query) that is to be executed as part of an action call. A script must be part of a template.
- Template: An organizational construct that holds the logical scripts for that specific template type.
A user starts by first selecting from a predefined list of template types, then saves their desired business logic encoded into each script, and finally sets up the IDBS E-Workbook Custom Action to call a specific template uuid
and the associated action desired.
Action Dataflow
When the user performs an action from IDBS, the Connector will open a new tab to display executed activities.
The Connector performs the following activities for a Retrieve action:
- Login: Authenticates with IDBS
- Download: Retrieves spreadsheet data from IDBS
- Query: Uses data from IDBS and dynamically generates an OpenSearch Query DSL query to then send to the TDP
- Transform hits: Transforms the results/hits from OpenSearch to IDBS format
- Resolve: This step allows the user to resolve conflict(s) and errors encountered by the transformation step
- Save: Saves the results in IDBS
Resolve
When conflict(s) and/or errors are encountered during transformation, the Resolve tab will display the information and allow the user to review and confirm selections. The following is an example of a transform that has conflicts, errors, and warnings:
- A conflict occurs when multiple files in the TDP would write conflicting information in one or more cells in the spreadsheet.
- An error occurs when a result can't be transformed, such as problems with downloading files or missing data. Errors are displayed against a red background.
- (For Tetra IDBS E-Workbook Connector v1.3.0 and higher only) A warning occurs when the
results
script of a retrieve action returns warnings, or when updates fail the connector's internal validation check. Warnings are displayed against a yellow background. The distinction between errors and warnings is that errors correspond to a fatal DataWeave crash.
The user can then review each issue and confirm the resolution.
Connector Action Configuration
Multi-Dimensional IDBS Spreadsheet Support
Tables in an IDBS spreadsheet can be more than two-dimensional. Some of the connector features (particularly adding rows to a spreadsheet table) have only been fully tested for 2D tables. In IDBS, this corresponds to them having a single, non-data dimension.
The IDBS Connector supports two actions that use customer-provided DataWeave scripts to provide the business logic:
upload
: Uploads the contents of the IDBS Spreadsheet to the TDP with a custom file path and attributes.retrieve
: Searches the TDP with custom Query DSL queries constructed from the IDBS Spreadsheet contents and allows for custom transform of the retrieved file content into a IDBS spreadsheet.
Actions
Table 1: Requirements for what scripts are needed per action.
Actions | Script: Transform ELN Data for TDP Upload | Script: Create ElasticSearch Query | Script: Transform Results |
---|---|---|---|
upload | ✅ | ||
retrieve | ✅ | ✅ |
upload
upload
Syntax
upload <template-uuid> toDatalake
NOTE
For
<template-uuid>
, enter the key associated with the desired DataWeave template in the connector.
Supported templates
- Round-trip
Description
This action sends a JSON representation of an IDBS spreadsheet to the TDP. The file in TDP can have a custom path (or custom attributes) set using one DataWeave script upload.
Maximum File Size Limitation
upload
supports a maximum file size of 500 MB.
Configuration in IDBS
- Open a spreadsheet in the IDBS Spreadsheet Designer application.
- Go to Tools > Instruction Set Designer.
- Create a “Connect to TDP” action.
- In the Data to pass to Action section of the Instruction Set designer, enter
upload <template-uuid> toDatalake
, where<template-uuid>
is the key associated with the desired DataWeave template in the connector.
retrieve
retrieve
Syntax
retrieve <template-uuid>
NOTE
For
<template-uuid>
, enter the key associated with the desired DataWeave template in the Connector.
Supported templates
- Round-trip
- Pull from TDP
Description
This action uses data from an IDBS spreadsheet to form a set of Query DSL queries to find data in the TDP. After finding the data, the action then transforms the hits into an appropriate payload to send to IDBS. This action uses two scripts retrieve and query, described below
Configuration in IDBS
- Open a spreadsheet in the IDBS Spreadsheet Designer application.
- Go to Tools > Instruction Set Designer.
- Create a “Connect to TDP” action.
- In the Data to pass to Action section of the Instruction Set designer, enter
retrieve <template-uuid>
, where<template-uuid>
is the key associated with the desired DataWeave template in the Connector.
Scripts
Transform ELN Data for TDP Upload (upload
)
upload
)The upload
DataWeave script can be used to generate file paths and custom metadata for uploaded files based on information from the IDBS spreadsheet.
Inputs
payload
: information about the IDBS spreadsheet that initiated the action, and the experiment that it lives in. The payload will have the following structure:
type UploadPayloadData = {
spreadsheet: {
name: string,
id: string,
modelId: string,
tables: string[],
structure: SpreadsheetStructure
},
experiment: {
name: string, // name of spreadsheet in IDBS
id: string, // ID of spreadsheet in IDBS
path: string[], // path of folders to experiment in IDBS
}
}
type SpreadsheetStructure = {
[tableName: string]: {
dataDimensionName: string,
dimensions: {
name: string,
itemNames: string[]
}[]
}
}
{
"spreadsheet": {
"id": "63da1040857411eea5bd00000a000079",
"modelId": "6614f03085e411eea5bd00000a000079",
"name": "Template.ewbss",
"tables": [
"Cell Counter"
],
"structure": {
"Cell Counter": {
"dataDimensionName": "Data",
"dimensions": [
{
"name": "Data",
"itemNames": [
"Raw Data Lake Link",
"Sample ID",
"Total Cell Conc, 10^5 cells/mL",
"Viable Cell Conc, 10^5 cells/mL"
]
},
{
"name": "S",
"itemNames": [
"1",
"2",
"3"
]
}
]
}
},
"content": {
"tables": [
{
"name": "Cell Counter",
"ranges": [
{
"range": "",
"data": [
{
"S": {
"string": "1"
},
"Sample ID": {
"string": "sample-2023-01"
},
"Total Cell Conc, 10^5 cells/mL": {
"number": 258612
},
"Viable Cell Conc, 10^5 cells/mL": {
"number": 268066
},
"Raw Data Lake Link": {
"string": "https://tetrascience-uat.com/file-details/767948f4-46ae-4697-9b77-61d9fdb9fe84"
}
},
{
"S": {
"string": "2"
},
"Sample ID": {
"string": "sample-2023-02"
},
"Total Cell Conc, 10^5 cells/mL": {
"number": 262140
},
"Viable Cell Conc, 10^5 cells/mL": {
"number": 224281
},
"Raw Data Lake Link": {
"string": "https://tetrascience-uat.com/file-details/aa9ae909-33ca-481d-adc0-2a18a42255e8"
}
},
{
"S": {
"string": "3"
},
"Sample ID": {
"string": "sample-2023-03"
},
"Total Cell Conc, 10^5 cells/mL": {
"number": 249244
},
"Viable Cell Conc, 10^5 cells/mL": {
"number": 263782
},
"Raw Data Lake Link": {
"string": "https://tetrascience-uat.com/file-details/1bdc16db-b41a-4582-acc1-e41f098328ce"
}
}
]
}
]
}
]
}
},
"experiment": {
"id": "dc57d39084e311eea5bd00000a000079",
"name": "IDBS Workshop",
"path": [
"Root",
"Partners",
"Tetrascience",
"Jeremy",
"IDBS Workshop"
]
}
}
Outputs
The expected output from the DataWeave is expected to have the following form:
{
filePath?: string, // TDP file path; defaults to '/idbs/uploads/upload-<random-uuid>' if missing
sourceType?: string, // TDP source type, must be lowercase letters and hyphens; defaults to `idbs-eworkbook` if missing
metadata?: Record<str, str>, // custom metadata, ASCII characters only for key and val
tags?: string[], // custom tags, must be unique, ASCII characters (and no commas)
labels?: { name: string, value: string }[]
}
%dw 2.0
output application/json
---
{
"filePath": "idbs/upload-test/experiment/" ++ payload.experiment.name ++ "/spreadsheet-" ++ payload.spreadsheet.name ++ ".json",
"sourceType": "idbs-eworkbook-test",
"metadata": {"developer": "john-doe"}
}
Note that all fields are optional. If you don’t need any customization, the upload
script can return an empty object and use the default values indicated above for filePath
and sourceType
. For Tetra IDBS E-Workbook Connector v1.3.0 and higher, the connector will validate these optional fields and raise a warning in the UI indicating differences from the expected form. Even if these fields fail validation, the connector will still attempt to upload the file.
The actual contents of the uploaded file are in JSON format, and they are the same as the spreadsheet piece of the payload but with the contents restored:
{
name: string,
id: string,
modelId: string,
tables: string[],
structure: SpreadsheetStructure,
content: SpreadsheetContent
}
type SpreadsheetContent = {
tables: {
name: string,
ranges: {
range: string,
data: SpreadsheetTableContent[]
}[]
}[]
}
type SpreadsheetTableContent = {
[dimensionName: string]: {string: string} | {number: number}
}
If you specify a file path that ends with a .json
extension, you will be able to use file preview within TDP to inspect this JSON document in the platform.
Create Query DSL Query (query
)
query
)The query DataWeave script is used to dynamically generate one or more Query DSL queries to send to Amazon OpenSearch Service. All unique hits from these queries will form the results to be transformed by the next step.
Note that for certain IDS types, the full OpenSearch document returned can be quite large. To improve performance in the connector, consider optimizing your queries to only return the necessary fields for transformation. For documentation, see Query DSL in the OpenSearch documentation.
Inputs
payload
: information about the IDBS spreadsheet that initiated the action, and the experiment that it lives in. The payload will have the following structure:
type QueryPayloadData = {
spreadsheet: {
name: string,
id: string,
modelId: string,
tables: string[],
structure: SpreadsheetStructure,
content: SpreadsheetContent
},
experiment: {
name: string, // name of spreadsheet in IDBS
id: string, // ID of spreadsheet in IDBS
path: string[], // path of folders to experiment in IDBS
}
}
type SpreadsheetStructure = {
[tableName: string]: {
dataDimensionName: string,
dimensions: {
name: string,
itemNames: string[]
}[]
}
}
type SpreadsheetContent = {
tables: {
name: string,
ranges: {
range: string,
data: SpreadsheetTableContent[]
}[]
}[]
}
type SpreadsheetTableContent = {
[dimensionName: string]: {string: string} | {number: number}
}
config
: holds information about the TDP and IDBS instances being used. The structure is:
type QueryConfigData = {
tdp: {
baseUrl: string,
orgSlug: string
},
idbs: {
baseUrl: string,
username: string // IDBS user who initiated the current external action
}
}
Outputs
The script should output a list of one or more valid queries. All queries in the list will be performed through TDP, and all hits corresponding to unique TDP fileId
will be passed on to a later step.
An error will be thrown if either of the following occurs:
- Any single query in the list fails. For example, a single malformed query will prevent you from proceeding.
- All queries combined produce
0
total hits. An individual query may yield0
hits with no error.
Transform Results (results
)
results
)The results
DataWeave script is used to transform the OpenSearch hits into the correct form to send to IDBS to update a spreadsheet. By default, all files are downloaded, and each hit is transformed individually, resulting in latency proportional to the number of hits returned by the query. However, there is an option available to improve performance:
- Skip Retrieve: If the information in the indexed OpenSearch document is sufficient, and you don't need to download files from the TDP or access data stored in datacubes, you can skip downloading files from the TDP. In addition, the connector will attempt to do all updates with a single DataWeave transform, which saves considerable time if you have many hits.
The skip retrieve option can be enabled by using a special comment in the DataWeave script. This comment can be placed anywhere that a comment is syntactically valid in DataWeave, but it's recommended to place it in the header section, just beneath the %dw 2.0
line.
The comments must have the following form:
- To enable skip retrieve, use
//@ts-skip-retrieve
NOTE
For backwards compatibility reasons, you can also enable skip-retrieve mode by running the following command:
//@ts-single-transform
For Tetra IDBS E-Workbook Connector v1.3.0 and higher, the connector can be set to automatically rerun an action in skip retrieve mode as multiple transforms in the event that the single transform fails. In the Settings > Connector tab of the Connector UI, a connector administrator can set a global default for whether retrieve actions will attempt this automatic rerun. If the global default is not set, the global default will be no reruns. Auto rerun behavior can also be set by using a dropdown in any template that supports retrieve
actions.
When a retrieve action runs using multiple transforms, Tetra IDBS E-Workbook Connector v1.3.0 and later supports a configurable batch size for the action. This corresponds to the maximum number of concurrent transforms (and file downloads, if needed) the connector will perform. Increasing this number will result in faster execution of the action, at the expense of using more connector resources. For use cases with many files, or with large files, this may result in increased connector instability, particularly if you have many concurrent users. It's recommended that you use a batch size greater than 1
only in instances where you expect few, relatively small files.
Inputs
Default (download all files, multi-transforms):
payload_1
: A single hit from OpenSearchpayload_2
: The full file corresponding to the hit given inpayload_1
payload_3
: The contents of the IDBS spreadsheet that initiated the action
If using Skip Retrieve:
payload_1
: The list of hits from OpenSearch. For Skip Retrieve, this will be a list containing a single hit. Looking at the body of the OpenSearch response, this corresponds tohits.hits
.payload_2
: The contents of the IDBS spreadsheet that initiated the action. This will have the typeGetADTResponseBody
.
Output
This script should put out a collection of spreadsheets and optionally (in connector v1.3.0 or later) warning messages. The following is the expected format of these outputs:
type ResultsScriptOutput = SpreadsheetUpdate[] | {
updates: SpreadsheetUpdate[],
warnings?: WarningFromDataWeave[]
}
type SpreadsheetUpdate = {
id: string, // see below for significance of this field
fileId: string, // TDP fileId related to this spreadsheet update
filePath: string, // TDP file path related to this spreadsheet update
tables: SpreadsheetUpdateContent[], // Spreadsheet update table content
summary?: any // see below for significance of this field
};
type WarningFromDataWeave = {
message: string, // will be shown in `Issues during transformation` screen
fileId?: string,
filePath?: string
}
// Note that the actual format of `tables` is more restrictive than this.
// Entries of tables should alternate between names and content
type SpreadsheetUpdateContent = SpreadsheetUpdateTableName | SpreadsheetTableContent[];
type SpreadsheetUpdateTableName = {
name: string,
range?: string
};
// `dimension` in IDBS means an index for a cell. Right now, if you want to
// add rows to a table, you do so by referencing the row's index and setting
// it to null. The connector interprets this as needing to add a row along
// that non-data dimension.
type SpreadsheetTableContent = {
[dimensionName: string]: {string: string} | {number: number} | {index: number | null}
};
After the updates are created, the connector runs them through a validator to make sure that they have the correct format. The updates are also checked for conflicts. A conflict is defined to be a place where the connector is attempting to write two or more inconsistent values to a given table cell. The connector provides a conflict resolution interface to allow the user to choose which value should apply.
- The
id
field above is used by the connector to group updates that might possibly conflict. Put differently, if two updates in the list have a differentid
, the conflict checker will not examine them for possible conflicts. DataWeave writers should adopt a convention where, for example, writes to the same table use a consistentid
. - The
summary
field controls what is shown in the connector’s Progress tab. For each result, the keys ofsummary
set the columns of the table displayed when you click on the result in the Progress tab; the values are what are displayed in that result’s cells. It is useful to provide values here that you can quickly inspect to handle any conflict resolution that is needed.
Templates
The actions supported by the Tetra IDBS E-Workbook Connector each use separate DataWeave scripts at different steps of the process. Templates help organize DataWeave scripts into logical groupings as guided by business or scientific workflows. Three distinct types of templates are available:
- Pull from TDP: Supports the retrieve external action from IDBS, and, as the name suggests, it is used to pull data from TDP into IDBS.
- Round-trip: Supports both the upload and retrieve external actions from IDBS. The upload action gathers data from an IDBS spreadsheet and allows the user to upload the spreadsheet contents as a JSON file to the TDP.
- Library: Unlike the other templates, this type does not correspond to an action the connector performs. Instead, DataWeave code in a library template can be imported into scripts used in other templates. This allows you to define common utility functions in one place instead of copying them to all relevant templates.
The expected DataWeave interface for the scripts contained in these templates is described above.
To use a library template, you may define DataWeave functions or variables in the script contained in the template. This script functions like a custom module in DataWeave. The name of the library template is the name that should be used when importing from the module elsewhere. As an example, if you define myTestFn
in the library sample_connector_library
, you can access this function in other connector DataWeave by including the line import myTestFn from sample_connector_library
in other scripts.
IDBS Spreadsheet Table Allowlisting
IDBS spreadsheets may have a very large number of tables, many of which are not relevant to the operation of the connector in a particular scenario. For each template, the Table Whitelist allows for specification of a list of tables that are necessary for the actions of interest to be used, improving the performance of the connector.
- If populated, only the tables listed in the Table Whitelist field will be downloaded into the connector and made available to the DataWeave scripts.
- Any tables listed in the allowlist that do not exist in the spreadsheet will be ignored silently, and no error will be raised.
- If the Table Whitelist field is left blank, all tables will be downloaded. This is the same behavior as earlier versions of the connector.
Unsupported Table Names for Allowlisting
Allowlisting does not support table names that contain commas.
DataWeave Explorer
From the Connector Homepage, click on the DataWeave tab next to Settings on the menu to go to the DataWeave Explorer.
Each row represents an individual template. On the left is a descriptive name for the template; this is a link that will take you to an editor where you can change the contents of the template. The pencil icon next to each name allows you to rename templates. Template names have two different naming conventions, depending on whether the template is a library or not:
- For non-library templates, the name may only contain letters, numbers, underscores, and hyphens. All letters are converted to lowercase.
- For library templates, the name may only contain letters, numbers, and underscores. The name must begin with a letter. All letters are converted to lowercase.
If you attempt to reuse an existing name, a small integer will be appended to the end of the name (similar to what a web browser does when saving downloads).
Other notable features:
- Each row contains the template key (a system-generated UUID) used internally to refer to the template. This is the value that must be inserted when configuring the instruction set in the IDBS Spreadsheet Designer. Unlike the name, this value cannot be changed.
Filter by name or key
allows the user to type characters, and will show all rows where either the name or key match those characters.Show deactivated templates
, if active, will allow templates that have been deactivated to appear in the file explorer. A deactivated template is read-only and will result in an error if a spreadsheet attempts to use it for actual work. Templates can be deactivated (or reactivated) from the editor screen.
If you have no scripts, you can either create a new one or use the button to import an existing one (typically this will come from the connector export function from a different environment).
Selecting the New
button will prompt you to first select a template type:
Selecting the Import DataWeave
button produces the following modal with text area for pasting in the exported JSON:
DataWeave Editor
The DataWeave Editor allows users with appropriate permissions to modify and save the DataWeave scripts used by the connector. The editor has two panes: Create Elasticsearch Query, which extracts data from the IDBS spreadsheet and forms a query string to send to the TDP; and Transform Results, which converts the results of this search back into IDBS spreadsheet updates.
Other notable features:
- The name, template key, and last modified information of the current template are displayed in the upper left corner. In the upper right is a link to return to the DataWeave Explorer.
- You may enter a description of the template in the Description text area. This description is visible in the explorer when an individual row is selected.
- Above the description is a toggle that allows the user to deactivate (or reactivate) the template.
- In Tetra IDBS E-Workbook Connector v1.3.0 and higher, non-library templates have a dropdown labeled
Auto Rerun
. This controls whether or not retrieve actions that fail when tried as a single transform (those using skip retrieve mode) are rerun using one DataWeave transform per Elasticsearch hit. - In version 1.3.0 and later, templates have a field for setting batch size. This controls how many transforms happen concurrently when a retrieve action runs using multiple transforms
- Whenever any field in the template is changed, the user must click Save in the bottom left to keep the changes. If there are unsaved changes and the user attempts to navigate away, the connector will prompt the user to ask if they wish to leave despite having unsaved data.
Save As..
allows the user to save a copy of the template under a different name. This will also generate a new template key for the copy.Export
will download the current template information to a filedataweave-export-<template-name>.json
. The text from this can be copied and pasted into the text area in the import modal to move DataWeave templates between environments.
Connector Logs
The connector comes with two logs: an Audit Log and a System Log. The Audit Log is not intended for troubleshooting, but rather exists for GxP compliance reasons.
Audit Log
Audit Log Future Location Move
In a future major version release of the IDBS Connector, the Audit Log will be transferred to TDP automatically and viewable there along with all of the other agent and connector Audit Logs.
The Audit Log is intended to capture all changes to the connector that might affect how data is moved, including the following:
- Connector version changes
- Configuration changes
- Log-in and log-out information
- Changes to DataWeave templates
The Audit Log is never truncated, however, only the most recent 1000 entries will be shown in the browser. The link at the top of the Audit Log provides access to the full log. Currently, this lives in audit.db
in the configuration volume of the connector.
The Audit Log records the following:
- A UTC timestamp of when changes occurred
- What user made the change
- What item changed (typically this corresponds to a key in the configuration database)
- A verbal description of what kind of change occurred
- The before and after status of the change (the JSON data associated with before and after versions can be inspected within the table)
Sensitive Information Stripping
Certain types of sensitive data (for example, application secrets) are masked when writing to the Audit Log.
System Log
The System Log serves as a diagnostic tool for users to look for more information when they encounter a problem. Within the System Log screen, the Details tab is available when the connector session has data from a recent request from IDBS. The System Log looks very similar to the Audit Log.
The System Log captures a large amount of internal data during the data retrieval process.
Other notable features:
- Unlike the Audit Log, the System Log is regularly truncated to maintain a manageable size.
- Whenever the log exceeds 512 MB, the oldest entries are trimmed until the size is valid again.
- The Details tab contains information about the current data retrieval job.
- It includes a variety of expandable sections which show things such as which DataWeave scripts are being used, the Query DSL query sent to TDP, the results of the DataWeave transforms, and other technical details about the transaction.
- It is very useful for developing new DataWeave scripts.
Template Tracker
The Template Tracker page shows the utilization of the various DataWeave templates defined in the Connector. Much less information is recorded here than in the System Log; however, like the Audit Log, the Template Tracker is never truncated.
The Template Tracker is visible to users with Admin privileges in the Connector.
The Template Tracker records the following information:
- A timestamp in UTC indicating when the Connector action ran
- The template key that identifies the action that ran
- The name of the template at the time the action ran (Note: It's possible to rename Connector actions, and the data is not retroactively changed in this table. The template key is a more reliable measure.)
- The IDBS username of the user who initiated the action
Like the Audit Log, only the most recent 1,000 entries are shown. The full table can be downloaded as a JSON file by selecting the link above the Template Tracker table.
Updated 22 days ago