We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
vds: cannot export sheets containing a date column
**Small description**

It's not possible to save a sheet to a .vds file if said sheet contains a date column.
This results in the error below.

**Expected result**

It should just work(tm).

**Actual result with screenshot**

```stacktrace
Traceback (most recent call last):
  File "/nix/store/srkr2wnwq95ylmgiadh28p3jiaadl5yw-visidata-2.4/lib/python3.8/site-packages/visidata/threads.py", line 215, in _toplevelTryFunc
    t.status = func(*args, **kwargs)
  File "/nix/store/srkr2wnwq95ylmgiadh28p3jiaadl5yw-visidata-2.4/lib/python3.8/site-packages/visidata/loaders/vds.py", line 32, in save_vds
    fp.write(json.dumps(d)+NL)
  File "/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type date is not JSON serializable
```

**Steps to reproduce with sample data and a .vd**

❯ cat testsheet.vd
```log
sheet	col	row	longname	input	keystrokes	comment
visidata_menu			sheets-stack		S	open Sheets Stack: join or jump between the active sheets on the current stack
sheets		キsheets	add-row		a	append a blank row
sheets	name	キ	edit-cell	testsheet	e	edit contents of current cell
sheets		キtestsheet	open-row		^J	open sheet referenced in current row
testsheet	0		rename-col	testcol	^	edit name of current column
testsheet	testcol		type-date		@	set type of current column to date
testsheet			add-row		a	append a blank row
testsheet	testcol	0	edit-cell	2021-06-14	e	edit contents of current cell
testsheet			save-all	test.vds	g^S	save all sheets to given file or directory)
```


**Additional context**

Problem is present on v2.4 and on the develop branch (commit 3350d9fd8c9e64ebf409deae4b31085d12efeb7f)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `visidata/loaders/vds.py`
Content:
```
1 'Custom VisiData save format'
2 
3 import json
4 from visidata import *
5 
6 NL='\n'
7 
8 @VisiData.api
9 def open_vds(vd, p):
10     return VdsIndexSheet(p.name, source=p)
11 
12 
13 @VisiData.api
14 def save_vds(vd, p, *sheets):
15     'Save in custom VisiData format, preserving columns and their attributes.'
16 
17     with p.open_text(mode='w') as fp:
18         for vs in sheets:
19             # class and attrs for vs
20             d = { 'name': vs.name, }
21             fp.write('#'+json.dumps(d)+NL)
22 
23             # class and attrs for each column in vs
24             for col in vs.visibleCols:
25                 d = col.__getstate__()
26                 d['col'] = type(col).__name__
27                 fp.write('#'+json.dumps(d)+NL)
28 
29             with Progress(gerund='saving'):
30                 for row in vs.iterdispvals(*vs.visibleCols, format=False):
31                     d = {col.name:val for col, val in row.items()}
32                     fp.write(json.dumps(d)+NL)
33 
34 
35 class VdsIndexSheet(IndexSheet):
36     def iterload(self):
37         vs = None
38         with self.source.open_text() as fp:
39             line = fp.readline()
40             while line:
41                 if line.startswith('#{'):
42                     d = json.loads(line[1:])
43                     if 'col' not in d:
44                         vs = VdsSheet(d.pop('name'), columns=[], source=self.source, source_fpos=fp.tell())
45                         yield vs
46                 line = fp.readline()
47 
48 
49 class VdsSheet(Sheet):
50     def newRow(self):
51         return {}   # rowdef: dict
52 
53     def iterload(self):
54         self.colnames = {}
55         self.columns = []
56 
57         with self.source.open_text() as fp:
58             fp.seek(self.source_fpos)
59 
60             # consume all metadata, create columns
61             line = fp.readline()
62             while line and line.startswith('#{'):
63                 d = json.loads(line[1:])
64                 if 'col' not in d:
65                     raise Exception(d)
66                 classname = d.pop('col')
67                 if classname == 'Column':
68                     classname = 'ItemColumn'
69                     d['expr'] = d['name']
70 
71                 c = globals()[classname](d.pop('name'))
72                 self.colnames[c.name] = c
73                 self.addColumn(c)
74                 for k, v in d.items():
75                     setattr(c, k, v)
76 
77                 line = fp.readline()
78 
79             while line and not line.startswith('#{'):
80                 d = json.loads(line)
81                 yield d
82                 line = fp.readline()
83
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/visidata/loaders/vds.py b/visidata/loaders/vds.py
--- a/visidata/loaders/vds.py
+++ b/visidata/loaders/vds.py
@@ -29,7 +29,7 @@
             with Progress(gerund='saving'):
                 for row in vs.iterdispvals(*vs.visibleCols, format=False):
                     d = {col.name:val for col, val in row.items()}
-                    fp.write(json.dumps(d)+NL)
+                    fp.write(json.dumps(d, default=str)+NL)
 
 
 class VdsIndexSheet(IndexSheet):

{"golden_diff": "diff --git a/visidata/loaders/vds.py b/visidata/loaders/vds.py\n--- a/visidata/loaders/vds.py\n+++ b/visidata/loaders/vds.py\n@@ -29,7 +29,7 @@\n             with Progress(gerund='saving'):\n                 for row in vs.iterdispvals(*vs.visibleCols, format=False):\n                     d = {col.name:val for col, val in row.items()}\n-                    fp.write(json.dumps(d)+NL)\n+                    fp.write(json.dumps(d, default=str)+NL)\n \n \n class VdsIndexSheet(IndexSheet):\n", "issue": "vds: cannot export sheets containing a date column\n**Small description**\r\n\r\nIt's not possible to save a sheet to a .vds file if said sheet contains a date column.\r\nThis results in the error below.\r\n\r\n**Expected result**\r\n\r\nIt should just work(tm).\r\n\r\n**Actual result with screenshot**\r\n\r\n```stacktrace\r\nTraceback (most recent call last):\r\n  File \"/nix/store/srkr2wnwq95ylmgiadh28p3jiaadl5yw-visidata-2.4/lib/python3.8/site-packages/visidata/threads.py\", line 215, in _toplevelTryFunc\r\n    t.status = func(*args, **kwargs)\r\n  File \"/nix/store/srkr2wnwq95ylmgiadh28p3jiaadl5yw-visidata-2.4/lib/python3.8/site-packages/visidata/loaders/vds.py\", line 32, in save_vds\r\n    fp.write(json.dumps(d)+NL)\r\n  File \"/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/__init__.py\", line 231, in dumps\r\n    return _default_encoder.encode(obj)\r\n  File \"/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/encoder.py\", line 199, in encode\r\n    chunks = self.iterencode(o, _one_shot=True)\r\n  File \"/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/encoder.py\", line 257, in iterencode\r\n    return _iterencode(o, 0)\r\n  File \"/nix/store/4s0h5aawbap3xhldxhcijvl26751qrjr-python3-3.8.9/lib/python3.8/json/encoder.py\", line 179, in default\r\n    raise TypeError(f'Object of type {o.__class__.__name__} '\r\nTypeError: Object of type date is not JSON serializable\r\n```\r\n\r\n**Steps to reproduce with sample data and a .vd**\r\n\r\n\u276f cat testsheet.vd\r\n```log\r\nsheet\tcol\trow\tlongname\tinput\tkeystrokes\tcomment\r\nvisidata_menu\t\t\tsheets-stack\t\tS\topen Sheets Stack: join or jump between the active sheets on the current stack\r\nsheets\t\t\u30adsheets\tadd-row\t\ta\tappend a blank row\r\nsheets\tname\t\u30ad\tedit-cell\ttestsheet\te\tedit contents of current cell\r\nsheets\t\t\u30adtestsheet\topen-row\t\t^J\topen sheet referenced in current row\r\ntestsheet\t0\t\trename-col\ttestcol\t^\tedit name of current column\r\ntestsheet\ttestcol\t\ttype-date\t\t@\tset type of current column to date\r\ntestsheet\t\t\tadd-row\t\ta\tappend a blank row\r\ntestsheet\ttestcol\t0\tedit-cell\t2021-06-14\te\tedit contents of current cell\r\ntestsheet\t\t\tsave-all\ttest.vds\tg^S\tsave all sheets to given file or directory)\r\n```\r\n\r\n\r\n**Additional context**\r\n\r\nProblem is present on v2.4 and on the develop branch (commit 3350d9fd8c9e64ebf409deae4b31085d12efeb7f)\n", "before_files": [{"content": "'Custom VisiData save format'\n\nimport json\nfrom visidata import *\n\nNL='\\n'\n\n@VisiData.api\ndef open_vds(vd, p):\n    return VdsIndexSheet(p.name, source=p)\n\n\n@VisiData.api\ndef save_vds(vd, p, *sheets):\n    'Save in custom VisiData format, preserving columns and their attributes.'\n\n    with p.open_text(mode='w') as fp:\n        for vs in sheets:\n            # class and attrs for vs\n            d = { 'name': vs.name, }\n            fp.write('#'+json.dumps(d)+NL)\n\n            # class and attrs for each column in vs\n            for col in vs.visibleCols:\n                d = col.__getstate__()\n                d['col'] = type(col).__name__\n                fp.write('#'+json.dumps(d)+NL)\n\n            with Progress(gerund='saving'):\n                for row in vs.iterdispvals(*vs.visibleCols, format=False):\n                    d = {col.name:val for col, val in row.items()}\n                    fp.write(json.dumps(d)+NL)\n\n\nclass VdsIndexSheet(IndexSheet):\n    def iterload(self):\n        vs = None\n        with self.source.open_text() as fp:\n            line = fp.readline()\n            while line:\n                if line.startswith('#{'):\n                    d = json.loads(line[1:])\n                    if 'col' not in d:\n                        vs = VdsSheet(d.pop('name'), columns=[], source=self.source, source_fpos=fp.tell())\n                        yield vs\n                line = fp.readline()\n\n\nclass VdsSheet(Sheet):\n    def newRow(self):\n        return {}   # rowdef: dict\n\n    def iterload(self):\n        self.colnames = {}\n        self.columns = []\n\n        with self.source.open_text() as fp:\n            fp.seek(self.source_fpos)\n\n            # consume all metadata, create columns\n            line = fp.readline()\n            while line and line.startswith('#{'):\n                d = json.loads(line[1:])\n                if 'col' not in d:\n                    raise Exception(d)\n                classname = d.pop('col')\n                if classname == 'Column':\n                    classname = 'ItemColumn'\n                    d['expr'] = d['name']\n\n                c = globals()[classname](d.pop('name'))\n                self.colnames[c.name] = c\n                self.addColumn(c)\n                for k, v in d.items():\n                    setattr(c, k, v)\n\n                line = fp.readline()\n\n            while line and not line.startswith('#{'):\n                d = json.loads(line)\n                yield d\n                line = fp.readline()\n", "path": "visidata/loaders/vds.py"}], "after_files": [{"content": "'Custom VisiData save format'\n\nimport json\nfrom visidata import *\n\nNL='\\n'\n\n@VisiData.api\ndef open_vds(vd, p):\n    return VdsIndexSheet(p.name, source=p)\n\n\n@VisiData.api\ndef save_vds(vd, p, *sheets):\n    'Save in custom VisiData format, preserving columns and their attributes.'\n\n    with p.open_text(mode='w') as fp:\n        for vs in sheets:\n            # class and attrs for vs\n            d = { 'name': vs.name, }\n            fp.write('#'+json.dumps(d)+NL)\n\n            # class and attrs for each column in vs\n            for col in vs.visibleCols:\n                d = col.__getstate__()\n                d['col'] = type(col).__name__\n                fp.write('#'+json.dumps(d)+NL)\n\n            with Progress(gerund='saving'):\n                for row in vs.iterdispvals(*vs.visibleCols, format=False):\n                    d = {col.name:val for col, val in row.items()}\n                    fp.write(json.dumps(d, default=str)+NL)\n\n\nclass VdsIndexSheet(IndexSheet):\n    def iterload(self):\n        vs = None\n        with self.source.open_text() as fp:\n            line = fp.readline()\n            while line:\n                if line.startswith('#{'):\n                    d = json.loads(line[1:])\n                    if 'col' not in d:\n                        vs = VdsSheet(d.pop('name'), columns=[], source=self.source, source_fpos=fp.tell())\n                        yield vs\n                line = fp.readline()\n\n\nclass VdsSheet(Sheet):\n    def newRow(self):\n        return {}   # rowdef: dict\n\n    def iterload(self):\n        self.colnames = {}\n        self.columns = []\n\n        with self.source.open_text() as fp:\n            fp.seek(self.source_fpos)\n\n            # consume all metadata, create columns\n            line = fp.readline()\n            while line and line.startswith('#{'):\n                d = json.loads(line[1:])\n                if 'col' not in d:\n                    raise Exception(d)\n                classname = d.pop('col')\n                if classname == 'Column':\n                    classname = 'ItemColumn'\n                    d['expr'] = d['name']\n\n                c = globals()[classname](d.pop('name'))\n                self.colnames[c.name] = c\n                self.addColumn(c)\n                for k, v in d.items():\n                    setattr(c, k, v)\n\n                line = fp.readline()\n\n            while line and not line.startswith('#{'):\n                d = json.loads(line)\n                yield d\n                line = fp.readline()\n", "path": "visidata/loaders/vds.py"}]}