{"id":21731059,"url":"https://github.com/rxnt/react-jsonschema-form-conditionals","last_synced_at":"2025-04-06T06:09:15.749Z","repository":{"id":45956308,"uuid":"95245542","full_name":"RXNT/react-jsonschema-form-conditionals","owner":"RXNT","description":"react-jsonschema-form-conditionals","archived":false,"fork":false,"pushed_at":"2023-06-28T05:03:37.000Z","size":1108,"stargazers_count":100,"open_issues_count":44,"forks_count":46,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-04-26T21:22:43.619Z","etag":null,"topics":["form","react","react-jsonschema-form","rule-engine","schema"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RXNT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-23T18:21:54.000Z","updated_at":"2024-06-18T16:40:20.674Z","dependencies_parsed_at":"2024-06-18T16:39:54.252Z","dependency_job_id":"19d34427-a801-4b53-a779-351a7a8a9a52","html_url":"https://github.com/RXNT/react-jsonschema-form-conditionals","commit_stats":{"total_commits":165,"total_committers":7,"mean_commits":"23.571428571428573","dds":"0.048484848484848464","last_synced_commit":"432adb6bea87203a864fef31d1064e27ef32d57c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-conditionals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-conditionals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-conditionals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RXNT%2Freact-jsonschema-form-conditionals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RXNT","download_url":"https://codeload.github.com/RXNT/react-jsonschema-form-conditionals/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247441052,"owners_count":20939239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","react","react-jsonschema-form","rule-engine","schema"],"created_at":"2024-11-26T04:19:35.435Z","updated_at":"2025-04-06T06:09:15.721Z","avatar_url":"https://github.com/RXNT.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/RxNT/react-jsonschema-form-conditionals.svg?branch=master)](https://travis-ci.org/RxNT/react-jsonschema-form-conditionals)\n[![Coverage Status](https://coveralls.io/repos/github/RxNT/react-jsonschema-form-conditionals/badge.svg?branch=master)](https://coveralls.io/github/RxNT/react-jsonschema-form-conditionals?branch=master)\n[![npm version](https://badge.fury.io/js/react-jsonschema-form-conditionals.svg)](https://badge.fury.io/js/react-jsonschema-form-conditionals)\n# Form with conditionals\n\nThis project extends [react-jsonschema-form](https://github.com/mozilla-services/react-jsonschema-form) with\nconditional logic, which allow to have more complicated logic expressed and controlled with JSON schema.\nThis is primarily useful for complicated schemas with extended business logic,\nwhich are suspect to changes and need to be manageable and changeable without modifying running application.\n\nIf you need simple rule logic, that does not change a lot, you can use original [mozilla project](https://github.com/mozilla-services/react-jsonschema-form),\nby following examples like https://jsfiddle.net/69z2wepo/68259/\n\nThe project is done to be fully compatible with mozilla,\nwithout imposing additional limitations.\n\n## Features\n\n- Support for [Json Rules Engine](https://github.com/CacheControl/json-rules-engine) and [json-rules-engine-simplified](https://github.com/RxNT/json-rules-engine-simplified)\n- Extensible action mechanism\n- Configuration over coding\n- Lightweight and extensible\n\n## Installation\n\nInstall `react-jsonschema-form-conditionals` by running:\n\n```bash\nnpm install --s react-jsonschema-form-conditionals\n```\n\n## Usage\n\nThe simplest example of using `react-jsonschema-form-conditionals`\n\n```jsx\nimport applyRules from 'react-jsonschema-form-conditionals';\nimport Engine from 'json-rules-engine-simplified';\nimport Form from \"react-jsonschema-form\";\n\n...\n\nconst rules = [{\n    ...\n}];\n\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine)(Form);\n\nReactDOM.render(\n  \u003cFormWithConditionals .../\u003e,\n  document.querySelector('#app')\n);\n```\n\nTo show case uses for this library we'll be using simple registration schema example\n\n```jsx\n\nimport applyRules from 'react-jsonschema-form-conditionals';\nimport Form from \"react-jsonschema-form\";\n\nlet schema = {\n  definitions: {\n    hobby: {\n      type: \"object\",\n      properties: {\n        name: { type: \"string\" },\n        durationInMonth: { \"type\": \"integer\" },\n      }\n    }\n  },\n  title: \"A registration form\",\n  description: \"A simple form example.\",\n  type: \"object\",\n  required: [\n    \"firstName\",\n    \"lastName\"\n  ],\n  properties: {\n    firstName: {\n      type: \"string\",\n      title: \"First name\"\n    },\n    lastName: {\n      type: \"string\",\n      title: \"Last name\"\n    },\n    age: {\n      type: \"integer\",\n      title: \"Age\",\n    },\n    bio: {\n      type: \"string\",\n      title: \"Bio\",\n    },\n    country: {\n      type: \"string\",\n      title: \"Country\"\n    },\n    state: {\n      type: \"string\",\n      title: \"State\"\n    },\n    zip: {\n      type: \"string\",\n      title: \"ZIP\"\n    },\n    password: {\n      type: \"string\",\n      title: \"Password\",\n      minLength: 3\n    },\n    telephone: {\n      type: \"string\",\n      title: \"Telephone\",\n      minLength: 10\n    },\n    hobbies: {\n        type: \"array\",\n        items: { \"$ref\": \"#/definitions/hobby\" }\n    }\n  }\n}\n\nlet rules = [{\n    ...\n}]\n\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine)(Form);\n\nrender((\n  \u003cFormWithConditionals /\u003e\n), document.getElementById(\"app\"));\n```\n\nConditionals functionality is build using 2 things\n- Rules engine ([Json Rules Engine](https://github.com/CacheControl/json-rules-engine) or [Simplified Json Rules Engine](https://github.com/RxNT/json-rules-engine-simplified))\n- Schema action mechanism\n\nRules engine responsibility is to trigger events, action mechanism\nperforms needed actions on the requests.\n\n## Rules engine\n\nProject supports 2 rules engines out of the box:\n- [Json Rules Engine](https://github.com/CacheControl/json-rules-engine)\n- [Simplified Json Rules Engine](https://github.com/RxNT/json-rules-engine-simplified)\n\nIn order to use either of those, you need to specify `Engine` in `applyRules` configuration.\n\nFor example:\n\nTo use [Simplified Json Rules Engine](https://github.com/RxNT/json-rules-engine-simplified), you can do following:\n```js\n\nimport applyRules from 'react-jsonschema-form-conditionals';\nimport Form from \"react-jsonschema-form\";\n\nimport Engine from 'json-rules-engine-simplified';\n\n...\n\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine)(Form);\n\nReactDOM.render(\n  \u003cFormWithConditionals /\u003e,\n  document.querySelector('#app')\n);\n```\n\nTo use [Json Rules Engine](https://github.com/RxNT/json-rules-engine-simplified), is almost the same:\n\n```js\n\nimport applyRules from 'react-jsonschema-form-conditionals';\nimport Engine from 'json-rules-engine';\nimport Form from \"react-jsonschema-form\";\n\n// ...\n\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine)(Form);\n\nReactDOM.render(\n  \u003cFormWithConditionals /\u003e,\n  document.querySelector('#app')\n);\n```\n\n### Extending rules engine\n\nIf non of the provided engines satisfies, your needs, you can\nimplement your own `Engine` which should\ncomply to following:\n\n```js\nclass Engine {\n  constructor(rules, schema) {\n  }\n  addRule = (rule) =\u003e {\n  }\n  run = (formData) =\u003e {\n    return Promise[Event]\n  }\n}\n```\n\nOriginal `rules` and `schema` is used as a parameter for a factory call,\nin order to be able to have additional functionality, such as rules to schema compliance validation,\nlike it's done in Simplified Json Rules Engine](https://github.com/RxNT/json-rules-engine-simplified)\n\n## Schema action mechanism\n\nRules engine emits events, which are expected to have a `type` and `params` field,\n`type` is used to distinguish action that is needed, `params` are used as input for that action:\n\n```json\n{\n  \"type\": \"remove\",\n  \"params\": {\n    \"field\": \"name\"\n  }\n}\n```\n\nBy default action mechanism defines a supported set of rules, which you can extend as needed:\n\n- `remove` removes a field or set of fields from `schema` and `uiSchema`\n- `require` makes a field or set of fields required\n\n### Remove action\n\nIf you want to remove a field, your configuration should look like this:\n\n```json\n    {\n      \"conditions\": { },\n      \"event\": {\n        \"type\": \"remove\",\n        \"params\": {\n          \"field\": \"password\"\n        }\n      }\n    }\n```\nWhen `condition` is met, `password` will be removed from both `schema` and `uiSchema`.\n\nIn case you want to remove multiple fields `name`, `password`, rule should look like this:\n\n```json\n    {\n      \"conditions\": { },\n      \"event\": {\n        \"type\": \"remove\",\n        \"params\": {\n          \"field\": [ \"name\", \"password\" ]\n        }\n      }\n    }\n```\n\nTo remove nested schema properties, use json dot notation. e.g. For schema object:\n\n```json\n  {\n    \"type\": \"object\",\n    \"properties\": {\n      \"someParentWrapper\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"booleanValA\": {\n            \"type\": \"boolean\",\n            \"title\": \"Some boolean input\"\n          },\n          \"booleanValB\": {\n            \"type\": \"boolean\",\n            \"title\": \"Another boolean input\"\n          }\n        }\n      }\n    }\n  }\n\n```\n\nYou can remove the nested booleanValA or booleanValB like so:\n\n```json\n  {\n    \"conditions\": { },\n    \"event\": {\n      \"type\": \"remove\",\n      \"params\": {\n        \"field\": \"someParentWrapper.booleanValA\"\n      }\n    }\n  }\n```\n\n### Require action\n\nThe same convention goes for `require` action\n\nFor a single field:\n\n```json\n    {\n      \"conditions\": { },\n      \"event\": {\n        \"type\": \"require\",\n        \"params\": {\n          \"field\": \"password\"\n        }\n      }\n    }\n```\n\nFor multiple fields:\n\n```json\n    {\n      \"conditions\": { },\n      \"event\": {\n        \"type\": \"require\",\n        \"params\": {\n          \"field\": [ \"name\", \"password\"]\n        }\n      }\n    }\n```\n\n## UiSchema actions\n\nAPI defines a set of actions, that you can take on `uiSchema`, they cover most of the\n\n- `uiAppend` appends `uiSchema` specified in params with an original `uiSchema`\n- `uiOverride` replaces field in original `uiSchema` with fields in `params`, keeping unrelated entries\n- `uiRepalce` replaces whole `uiSchema` with a conf schema\n\nTo show case, let's take a simple `schema`\n\n```json\n{\n  \"properties\": {\n    \"lastName\": { \"type\": \"string\" },\n    \"firstName\": { \"type\": \"string\" },\n    \"nickName\": { \"type\": \"string\"}\n  }\n}\n```\n\nand `uiSchema`\n\n```json\n{\n  \"ui:order\": [\"firstName\"],\n  \"lastName\": {\n    \"classNames\": \"col-md-1\",\n  },\n  \"firstName\": {\n    \"ui:disabled\": false,\n    \"num\": 23\n  },\n  \"nickName\": {\n    \"classNames\": \"col-md-12\"\n  }\n}\n```\nwith event `params` something like this\n```json\n{\n  \"ui:order\": [ \"lastName\" ],\n  \"lastName\": {\n    \"classNames\": \"has-error\"\n  },\n  \"firstName\" : {\n    \"classNames\": \"col-md-6\",\n    \"ui:disabled\": true,\n    \"num\": 22\n  }\n}\n```\n\nAnd look at different results depend on the choosen action.\n\n### uiAppend\n\nUiAppend can handle `arrays` and `string`, with fallback to `uiOverride` behavior for all other fields.\n\nSo the expected result `uiSchema` will be:\n```json\n{\n  \"ui:order\": [\"firstName\", \"lastName\"],\n  \"lastName\": {\n    \"classNames\": \"col-md-1 has-error\"\n  },\n  \"firstName\": {\n    \"classNames\": \"col-md-6\",\n    \"ui:disabled\": true,\n    \"num\": 22\n  },\n  \"nickName\": {\n    \"classNames\": \"col-md-12\"\n  }\n}\n```\n\nIn this case it\n - added `lastName` to `ui:order` array,\n - appended `has-error` to `classNames` in `lastName` field\n - added `classNames` and enabled `firstName`\n - as for the `num` in `firstName` it just overrode it\n\nThis is useful for example if you want to add some additional markup in your code, without touching layout that you've defined.\n\n### uiOverride\n\n`uiOverride` behaves similar to append, but instead of appending it completely replaces overlapping values  \n\nSo the expected result `uiSchema` will be:\n```json\n{\n  \"ui:order\": [ \"lastName\" ],\n  \"lastName\": {\n    \"classNames\": \"has-error\"\n  },\n  \"firstName\": {\n    \"classNames\": \"col-md-6\",\n    \"ui:disabled\": true,\n    \"num\": 22\n  },\n  \"nickName\": {\n    \"classNames\": \"col-md-12\"\n  }\n}\n```\n\nIn this case it\n - `ui:order` was replaced with configured value\n - `className` for the `lastName` was replaced with `has-error`\n - added `classNames` and enabled `firstName`\n - as for the `num` in `firstName` it just overrode it\n\n### uiReplace\n\n`uiReplace` just replaces all fields in `uiSchema` with `params` fields, leaving unrelated fields untouched.\n\nSo the result `uiSchema` will be\n```json\n{\n  \"ui:order\": [ \"lastName\" ],\n  \"lastName\": {\n    \"classNames\": \"has-error\"\n  },\n  \"firstName\" : {\n    \"classNames\": \"col-md-6\",\n    \"ui:disabled\": true,\n    \"num\": 22\n  },\n  \"nickName\": {\n     \"classNames\": \"col-md-12\"\n   }\n}\n```\n\n## Extension mechanism\n\nYou can extend existing actions list, by specifying `extraActions` on the form.\n\nLet's say we need to introduce `replaceClassNames` action, that\nwould just specify `classNames` `col-md-4` for all fields except for `ignore`d one.\nWe also want to trigger it only when `password` is `empty`.\n\nThis is how we can do this:\n\n```js\nimport applyRules from 'react-jsonschema-form-conditionals';\nimport Engine from 'json-rules-engine-simplified';\nimport Form from \"react-jsonschema-form\";\n\n...\n\nconst rules = [\n    {\n        conditons: {\n            password: \"empty\"\n        },\n        event: {\n            type: \"replaceClassNames\",\n            params: {\n                classNames: \"col-md-4\",\n                ignore: [ \"password\" ]\n            }\n        }\n    }\n];\n\n\nlet extraActions = {\n    replaceClassNames: function(params, schema, uiSchema, formData) {\n        Object.keys(schema.properties).forEach((field) =\u003e {\n            if (uiSchema[field] === undefined) {\n                uiSchema[field] = {}\n            }\n            uiSchema[field].classNames = params.classNames;\n        }\n    }\n};\n\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine, extraActions)(Form);\n\nReactDOM.render(\n  \u003cFormWithConditionals/\u003e,\n  document.querySelector('#app')\n);\n```\n\nProvided snippet does just that.\n\n### Extension with calculated values\n\nIn case you need to calculate value, based on other field values, you can also do that.\n\nLet's say we want to have schema with `a`, `b` and `sum` fields\n\n```js\nimport applyRules from 'react-jsonschema-form-conditionals';\nimport Engine from 'json-rules-engine-simplified';\nimport Form from \"react-jsonschema-form\";\n\n...\n\nconst rules = [\n    {\n        conditons: {\n            a: { not: \"empty\" },\n            b: { not: \"empty\" }\n        },\n        event: {\n            type: \"updateSum\"\n        }\n    }\n];\n\n\nlet extraActions = {\n    updateSum: function(params, schema, uiSchema, formData) {\n        formData.sum = formData.a + formData.b;\n    }\n};\n\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine, extraActions)(Form);\n\nReactDOM.render(\n  \u003cFormWithConditionals/\u003e,\n  document.querySelector('#app')\n);\n```\n\nThis is how you can do that.\n\n\u003e WARNING!!! You need to be careful with a rules order, when using calculated values.\n\u003e Put calculation rules at the top of your rules specification.\n\nFor example, let's say you want to mark `sum` field, if you have sum `greater` than `10`. The rule would look something like this:\n\n```json\n{\n  \"conditions\": {\n    \"sum\": { \"greater\" : 10 }\n  },\n  \"event\": {\n    \"type\": \"appendClass\",\n    \"classNames\": \"has-success\"\n  }\n}\n```\n\nBut it will work only if you put it after `updateSum` rule, like this\n```json\n[\n    {\n        \"conditons\": {\n            \"a\": { \"not\": \"empty\" },\n            \"b\": { \"not\": \"empty\" }\n        },\n        \"event\": {\n            \"type\": \"updateSum\"\n        }\n    },\n    {\n      \"conditions\": {\n        \"sum\": { \"greater\" : 10 }\n      },\n      \"event\": {\n        \"type\": \"appendClass\",\n        \"classNames\": \"has-success\"\n      }\n    }\n];\n```\n\nOtherwise it will work with **old `sum` values** and therefor show incorrect value.\n\n### Rules order\n\nOriginally actions performed in sequence defined in the array. If you have interdependent rules, that you need to run in order\nyou can specify `order` on a rule, so that it would be executed first. Rules are executed based on order from lowest to highest with\nrules without order executed last.\n\nFor example to make updateSum work regardless the order rules were added, you can do following:\n```json\n[\n    {\n      \"conditions\": {\n        \"sum\": { \"greater\" : 10 }\n      },\n      \"order\": 1,\n      \"event\": {\n        \"type\": \"appendClass\",\n        \"classNames\": \"has-success\"\n      }\n    },\n    {\n        \"conditons\": {\n            \"a\": { \"not\": \"empty\" },\n            \"b\": { \"not\": \"empty\" }\n        },\n        \"order\": 0,\n        \"event\": {\n            \"type\": \"updateSum\"\n        }\n    }\n]\n```\nHere although `updateSum` comes after `appendClass`, it will be executed first, since it has a lower order.\n\n## Action validation mechanism\n\nAll default actions are validated by default, checking that field exists in the schema, to save you some headaches.\nThere are 2 levels of validation\n\n- `propTypes` validation, using FB `prop-types` package\n- explicit validation\n\nYou can define those validations in your actions as well, to improve actions usability.\n\nAll validation is disabled in production.\n\n### Prop types action validation\n\nThis is reuse of familiar `prop-types` validation used with React components, and it's used in the same way:\n\nIn case of `require` it can look like this:\n```js\nrequire.propTypes = {\n  field: PropTypes.oneOfType([\n    PropTypes.string,\n    PropTypes.arrayOf(PropTypes.string),\n  ]).isRequired,\n};\n```\n\nThe rest is magic.\n\nWARNING, the default behavior of `prop-types` is to send errors to console,\nwhich you need to have running in order to see them.\n\nFor our `replaceClassNames` action, it can look like this:\n\n```js\nreplaceClassNames.propTypes = {\n  classNames: PropTypes.string.isRequired,\n  ignore: PropTypes.arrayOf(PropTypes.string)\n};\n```\n\n## Explicit validation\n\nIn order to provide more granular validation, you can specify validate function on\nyour action, that will receive `params`, `schema` and `uiSchema` so you could provide appropriate validation.\n\nFor example, validation for `require` can be done like this:\n\n```js\n  require.validate = function({ field }, schema, uiSchema) {\n    if (Array.isArray(field)) {\n      field\n        .filter(f =\u003e schema \u0026\u0026 schema.properties \u0026\u0026 schema.properties[f] === undefined)\n        .forEach(f =\u003e console.error(`Field  \"${f}\" is missing from schema on \"require\"`));\n    } else if (\n      schema \u0026\u0026\n      schema.properties \u0026\u0026\n      schema.properties[field] === undefined\n    ) {\n      console.error(`Field  \"${field}\" is missing from schema on \"require\"`);\n    }\n  };\n```\n\nValidation is not mandatory, and will be done only if field is provided.\n\nFor our `replaceClassNames` action, it would look similar:\n```js\n  replaceClassNames.validate = function({ ignore }, schema, uiSchema) {\n    if (Array.isArray(field)) {\n      ignore\n        .filter(f =\u003e schema \u0026\u0026 schema.properties \u0026\u0026 schema.properties[f] === undefined)\n        .forEach(f =\u003e console.error(`Field  \"${f}\" is missing from schema on \"replaceClassNames\"`));\n    } else if (\n      schema \u0026\u0026\n      schema.properties \u0026\u0026\n      schema.properties[ignore] === undefined\n    ) {\n      console.error(`Field  \"${ignore}\" is missing from schema on \"replaceClassNames\"`);\n    }\n  };\n```\n\n# Listening to configuration changes\n\nIn order to listen for configuration changes you can specify `onSchemaConfChange`, which will be notified every time `schema` or `uiSchema` changes it's value.\n\n```js\nlet FormWithConditionals = applyRules(schema, uiSchema, rules, Engine, extraActions)(Form);\n\nReactDOM.render(\n  \u003cFormWithConditionals onSchemaConfChange = {({ schema, uiSchema }) =\u003e { console.log(\"configuration changed\") }}/\u003e,\n  document.querySelector('#app')\n);\n\n```\n\n## Contribute\n\n- Issue Tracker: github.com/RxNT/react-jsonschema-form-conditionals/issues\n- Source Code: github.com/RxNT/react-jsonschema-form-conditionals\n\n## Support\n\nIf you are having issues, please let us know.\n\n## License\n\nThe project is licensed under the Apache-2.0 license.\n\n\n## Migration\n\n### Migration to 0.4.x\n\nThe only significant change is signature of `applyRules` call. In 0.4.0 `schema`, `uiSchema`, `rules`, `Engine` and `extraActions` all consider to be constant that is why, they moved to `applyRules` call.\nThis helps improve performance on large schemas.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frxnt%2Freact-jsonschema-form-conditionals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frxnt%2Freact-jsonschema-form-conditionals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frxnt%2Freact-jsonschema-form-conditionals/lists"}