We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Location sync broken for dates, ints
#### ALL software version info

```
Python 3.9.0

bokeh==2.2.3
notebook==5.7.9
panel==0.10.1

macOS Catalina 10.15.7

Chrome 85.0.4183.121
```

#### Description of expected behavior and the observed behavior

##### Expected

When syncing params with the browser location, refreshing the page or sharing the URL should restore those param values.

##### Observed

Refreshing the page or sharing the URL does not restore param values for dates and ints. It does seem to work for strings and floats.

Editing the URL by changing `?bday="2000-01-01"` to `?bday=2000-01-01` lets you share the URL (though the sync on page load immediately changes the URL back).

#### Complete, minimal, self-contained example code that reproduces the issue

```python
import panel as pn
import panel.widgets as pnw

bday = pnw.DatePicker()
pn.state.location.sync(bday, {"value": "bday"})

@pn.depends(bday)
def summary(bday):
    return f"My birthday is {bday}"

app = pn.Column(bday, summary)
app.servable()
```

#### Stack traceback and/or browser JavaScript console output

```
2020-11-13 16:12:06,453 Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x142be9c10>>, <Task finished name='Task-369' coro=<_needs_document_lock.<locals>._needs_document_lock_wrapper() done, defined at /Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/bokeh/server/session.py:51> exception=ValueError("CalendarDate 'value' only takes datetime types.")>)
Traceback (most recent call last):
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/tornado/ioloop.py", line 741, in _run_callback
    ret = callback()
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/tornado/ioloop.py", line 765, in _discard_future_result
    future.result()
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/bokeh/server/session.py", line 71, in _needs_document_lock_wrapper
    result = await result
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/tornado/gen.py", line 216, in wrapper
    result = ctx_run(func, *args, **kwargs)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/reactive.py", line 194, in _change_coroutine
    self._change_event(doc)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/reactive.py", line 204, in _change_event
    self._process_events(events)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/reactive.py", line 187, in _process_events
    self.param.set_param(**self._process_property_change(events))
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 1451, in set_param
    self_._batch_call_watchers()
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 1578, in _batch_call_watchers
    watcher.fn(*events)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/io/location.py", line 108, in _update_synced
    p.param.set_param(**mapped)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 1444, in set_param
    setattr(self_or_cls, k, v)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 302, in _f
    instance_param.__set__(obj, val)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 304, in _f
    return f(self, obj, val)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/__init__.py", line 623, in __set__
    super(Dynamic,self).__set__(obj,val)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 304, in _f
    return f(self, obj, val)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py", line 871, in __set__
    self._validate(val)
  File "/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/__init__.py", line 1891, in _validate
    raise ValueError("CalendarDate '%s' only takes datetime types."%self.name)
ValueError: CalendarDate 'value' only takes datetime types.
```

#### Screenshots or screencasts of the bug in action

<img width="478" alt="Screen Shot 2020-11-13 at 4 24 00 PM" src="https://user-images.githubusercontent.com/3858785/99122635-b844ba00-25cc-11eb-83c4-57760c138586.png">


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `panel/io/location.py`
Content:
```
1 """
2 Defines the Location  widget which allows changing the href of the window.
3 """
4 
5 import urllib.parse as urlparse
6 
7 import param
8 
9 from ..models.location import Location as _BkLocation
10 from ..reactive import Syncable
11 from ..util import parse_query
12 from .state import state
13 
14 
15 class Location(Syncable):
16     """
17     The Location component can be made available in a server context
18     to provide read and write access to the URL components in the
19     browser.
20     """
21 
22     href = param.String(readonly=True, doc="""
23         The full url, e.g. 'https://localhost:80?color=blue#interact'""")
24 
25     hostname = param.String(readonly=True, doc="""
26         hostname in window.location e.g. 'panel.holoviz.org'""")
27 
28     pathname = param.String(regex=r"^$|[\/].*$", doc="""
29         pathname in window.location e.g. '/user_guide/Interact.html'""")
30 
31     protocol = param.String(readonly=True, doc="""
32         protocol in window.location e.g. 'http:' or 'https:'""")
33 
34     port = param.String(readonly=True, doc="""
35         port in window.location e.g. '80'""")
36 
37     search = param.String(regex=r"^$|\?", doc="""
38         search in window.location e.g. '?color=blue'""")
39 
40     hash = param.String(regex=r"^$|#", doc="""
41         hash in window.location e.g. '#interact'""")
42 
43     reload = param.Boolean(default=False, doc="""
44         Reload the page when the location is updated. For multipage
45         apps this should be set to True, For single page apps this
46         should be set to False""")
47 
48     # Mapping from parameter name to bokeh model property name
49     _rename = {"name": None}
50 
51     def __init__(self, **params):
52         super(Location, self).__init__(**params)
53         self._synced = []
54         self._syncing = False
55         self.param.watch(self._update_synced, ['search'])
56 
57     def _get_model(self, doc, root=None, parent=None, comm=None):
58         model = _BkLocation(**self._process_param_change(self._init_properties()))
59         root = root or model
60         values = dict(self.param.get_param_values())
61         properties = list(self._process_param_change(values))
62         self._models[root.ref['id']] = (model, parent)
63         self._link_props(model, properties, doc, root, comm)
64         return model
65 
66     def _get_root(self, doc=None, comm=None):
67         root = self._get_model(doc, comm=comm)
68         ref = root.ref['id']
69         state._views[ref] = (self, root, doc, comm)
70         self._documents[doc] = root
71         return root
72 
73     def _cleanup(self, root):
74         if root.document in self._documents:
75             del self._documents[root.document]
76         ref = root.ref['id']
77         super()._cleanup(root)
78         if ref in state._views:
79             del state._views[ref]
80 
81     def _update_synced(self, event=None):
82         if self._syncing:
83             return
84         query_params = self.query_params
85         for p, parameters, _ in self._synced:
86             mapping = {v: k for k, v in parameters.items()}
87             mapped = {}
88             for k, v in query_params.items():
89                 if k not in mapping:
90                     continue
91                 pname = mapping[k]
92                 if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
93                     v = v[1:-1]
94                 else:
95                     try:
96                         v = p.param[pname].deserialize(v)
97                     except Exception:
98                         pass
99                 mapped[pname] = v
100             p.param.set_param(**mapped)
101 
102     def _update_query(self, *events, query=None):
103         if self._syncing:
104             return
105         query = query or {}
106         for e in events:
107             matches = [ps for o, ps, _ in self._synced if o in (e.cls, e.obj)]
108             if not matches:
109                 continue
110             owner = e.cls if e.obj is None else e.obj
111             try:
112                 val = owner.param.serialize_value(e.name)
113             except Exception:
114                 val = e.new
115             query[matches[0][e.name]] = val
116         self._syncing = True
117         try:
118             self.update_query(**{k: v for k, v in query.items() if v is not None})
119         finally:
120             self._syncing = False
121 
122     @property
123     def query_params(self):
124         return parse_query(self.search)
125 
126     def update_query(self, **kwargs):
127         query = self.query_params
128         query.update(kwargs)
129         self.search = '?' + urlparse.urlencode(query)
130 
131     def sync(self, parameterized, parameters=None):
132         """
133         Syncs the parameters of a Parameterized object with the query
134         parameters in the URL. If no parameters are supplied all
135         parameters except the name are synced.
136 
137         Arguments
138         ---------
139         parameterized (param.Parameterized):
140           The Parameterized object to sync query parameters with
141         parameters (list or dict):
142           A list or dictionary specifying parameters to sync.
143           If a dictionary is supplied it should define a mapping from
144           the Parameterized's parameteres to the names of the query
145           parameters.
146         """
147         parameters = parameters or [p for p in parameterized.param if p != 'name']
148         if not isinstance(parameters, dict):
149             parameters = dict(zip(parameters, parameters))
150         watcher = parameterized.param.watch(self._update_query, list(parameters))
151         self._synced.append((parameterized, parameters, watcher))
152         self._update_synced()
153         self._update_query(query={v: getattr(parameterized, k)
154                                   for k, v in parameters.items()})
155 
156     def unsync(self, parameterized, parameters=None):
157         """
158         Unsyncs the parameters of the Parameterized with the query
159         params in the URL. If no parameters are supplied all
160         parameters except the name are unsynced.
161 
162         Arguments
163         ---------
164         parameterized (param.Parameterized):
165           The Parameterized object to unsync query parameters with
166         parameters (list or dict):
167           A list of parameters to unsync.
168         """
169         matches = [s for s in self._synced if s[0] is parameterized]
170         if not matches:
171             ptype = type(parameterized)
172             raise ValueError(f"Cannot unsync {ptype} object since it "
173                              "was never synced in the first place.")
174         synced = []
175         for p, params, watcher in self._synced:
176             if parameterized is p:
177                 parameterized.param.unwatch(watcher)
178                 if parameters is not None:
179                     new_params = {p: q for p, q in params.items()
180                                   if p not in parameters}
181                     new_watcher = parameterized.param.watch(watcher.fn, list(new_params))
182                     synced.append((p, new_params, new_watcher))
183             else:
184                 synced.append((p, params, watcher))
185         self._synced = synced
186
```
--- 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/panel/io/location.py b/panel/io/location.py
--- a/panel/io/location.py
+++ b/panel/io/location.py
@@ -2,6 +2,7 @@
 Defines the Location  widget which allows changing the href of the window.
 """
 
+import json
 import urllib.parse as urlparse
 
 import param
@@ -89,33 +90,32 @@
                 if k not in mapping:
                     continue
                 pname = mapping[k]
-                if isinstance(v, str) and v.startswith('"') and v.endswith('"'):
-                    v = v[1:-1]
-                else:
-                    try:
-                        v = p.param[pname].deserialize(v)
-                    except Exception:
-                        pass
+                try:
+                    v = p.param[pname].deserialize(v)
+                except Exception:
+                    pass
                 mapped[pname] = v
             p.param.set_param(**mapped)
 
     def _update_query(self, *events, query=None):
         if self._syncing:
             return
-        query = query or {}
+        serialized = query or {}
         for e in events:
             matches = [ps for o, ps, _ in self._synced if o in (e.cls, e.obj)]
             if not matches:
                 continue
             owner = e.cls if e.obj is None else e.obj
             try:
-                val = owner.param.serialize_value(e.name)
+                val = owner.param[e.name].serialize(e.new)
             except Exception:
                 val = e.new
-            query[matches[0][e.name]] = val
+            if not isinstance(val, str):
+                val = json.dumps(val)
+            serialized[matches[0][e.name]] = val
         self._syncing = True
         try:
-            self.update_query(**{k: v for k, v in query.items() if v is not None})
+            self.update_query(**{k: v for k, v in serialized.items() if v is not None})
         finally:
             self._syncing = False
 
@@ -150,8 +150,19 @@
         watcher = parameterized.param.watch(self._update_query, list(parameters))
         self._synced.append((parameterized, parameters, watcher))
         self._update_synced()
-        self._update_query(query={v: getattr(parameterized, k)
-                                  for k, v in parameters.items()})
+        query = {}
+        for p, name in parameters.items():
+            v = getattr(parameterized, p)
+            if v is None:
+                continue
+            try:
+                parameterized.param[p].serialize(v)
+            except Exception:
+                pass
+            if not isinstance(v, str):
+                v = json.dumps(v)
+            query[name] = v
+        self._update_query(query=query)
 
     def unsync(self, parameterized, parameters=None):
         """

{"golden_diff": "diff --git a/panel/io/location.py b/panel/io/location.py\n--- a/panel/io/location.py\n+++ b/panel/io/location.py\n@@ -2,6 +2,7 @@\n Defines the Location  widget which allows changing the href of the window.\n \"\"\"\n \n+import json\n import urllib.parse as urlparse\n \n import param\n@@ -89,33 +90,32 @@\n                 if k not in mapping:\n                     continue\n                 pname = mapping[k]\n-                if isinstance(v, str) and v.startswith('\"') and v.endswith('\"'):\n-                    v = v[1:-1]\n-                else:\n-                    try:\n-                        v = p.param[pname].deserialize(v)\n-                    except Exception:\n-                        pass\n+                try:\n+                    v = p.param[pname].deserialize(v)\n+                except Exception:\n+                    pass\n                 mapped[pname] = v\n             p.param.set_param(**mapped)\n \n     def _update_query(self, *events, query=None):\n         if self._syncing:\n             return\n-        query = query or {}\n+        serialized = query or {}\n         for e in events:\n             matches = [ps for o, ps, _ in self._synced if o in (e.cls, e.obj)]\n             if not matches:\n                 continue\n             owner = e.cls if e.obj is None else e.obj\n             try:\n-                val = owner.param.serialize_value(e.name)\n+                val = owner.param[e.name].serialize(e.new)\n             except Exception:\n                 val = e.new\n-            query[matches[0][e.name]] = val\n+            if not isinstance(val, str):\n+                val = json.dumps(val)\n+            serialized[matches[0][e.name]] = val\n         self._syncing = True\n         try:\n-            self.update_query(**{k: v for k, v in query.items() if v is not None})\n+            self.update_query(**{k: v for k, v in serialized.items() if v is not None})\n         finally:\n             self._syncing = False\n \n@@ -150,8 +150,19 @@\n         watcher = parameterized.param.watch(self._update_query, list(parameters))\n         self._synced.append((parameterized, parameters, watcher))\n         self._update_synced()\n-        self._update_query(query={v: getattr(parameterized, k)\n-                                  for k, v in parameters.items()})\n+        query = {}\n+        for p, name in parameters.items():\n+            v = getattr(parameterized, p)\n+            if v is None:\n+                continue\n+            try:\n+                parameterized.param[p].serialize(v)\n+            except Exception:\n+                pass\n+            if not isinstance(v, str):\n+                v = json.dumps(v)\n+            query[name] = v\n+        self._update_query(query=query)\n \n     def unsync(self, parameterized, parameters=None):\n         \"\"\"\n", "issue": "Location sync broken for dates, ints\n#### ALL software version info\r\n\r\n```\r\nPython 3.9.0\r\n\r\nbokeh==2.2.3\r\nnotebook==5.7.9\r\npanel==0.10.1\r\n\r\nmacOS Catalina 10.15.7\r\n\r\nChrome 85.0.4183.121\r\n```\r\n\r\n#### Description of expected behavior and the observed behavior\r\n\r\n##### Expected\r\n\r\nWhen syncing params with the browser location, refreshing the page or sharing the URL should restore those param values.\r\n\r\n##### Observed\r\n\r\nRefreshing the page or sharing the URL does not restore param values for dates and ints. It does seem to work for strings and floats.\r\n\r\nEditing the URL by changing `?bday=\"2000-01-01\"` to `?bday=2000-01-01` lets you share the URL (though the sync on page load immediately changes the URL back).\r\n\r\n#### Complete, minimal, self-contained example code that reproduces the issue\r\n\r\n```python\r\nimport panel as pn\r\nimport panel.widgets as pnw\r\n\r\nbday = pnw.DatePicker()\r\npn.state.location.sync(bday, {\"value\": \"bday\"})\r\n\r\n@pn.depends(bday)\r\ndef summary(bday):\r\n    return f\"My birthday is {bday}\"\r\n\r\napp = pn.Column(bday, summary)\r\napp.servable()\r\n```\r\n\r\n#### Stack traceback and/or browser JavaScript console output\r\n\r\n```\r\n2020-11-13 16:12:06,453 Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x142be9c10>>, <Task finished name='Task-369' coro=<_needs_document_lock.<locals>._needs_document_lock_wrapper() done, defined at /Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/bokeh/server/session.py:51> exception=ValueError(\"CalendarDate 'value' only takes datetime types.\")>)\r\nTraceback (most recent call last):\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/tornado/ioloop.py\", line 741, in _run_callback\r\n    ret = callback()\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/tornado/ioloop.py\", line 765, in _discard_future_result\r\n    future.result()\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/bokeh/server/session.py\", line 71, in _needs_document_lock_wrapper\r\n    result = await result\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/tornado/gen.py\", line 216, in wrapper\r\n    result = ctx_run(func, *args, **kwargs)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/reactive.py\", line 194, in _change_coroutine\r\n    self._change_event(doc)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/reactive.py\", line 204, in _change_event\r\n    self._process_events(events)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/reactive.py\", line 187, in _process_events\r\n    self.param.set_param(**self._process_property_change(events))\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 1451, in set_param\r\n    self_._batch_call_watchers()\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 1578, in _batch_call_watchers\r\n    watcher.fn(*events)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/panel/io/location.py\", line 108, in _update_synced\r\n    p.param.set_param(**mapped)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 1444, in set_param\r\n    setattr(self_or_cls, k, v)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 302, in _f\r\n    instance_param.__set__(obj, val)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 304, in _f\r\n    return f(self, obj, val)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/__init__.py\", line 623, in __set__\r\n    super(Dynamic,self).__set__(obj,val)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 304, in _f\r\n    return f(self, obj, val)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/parameterized.py\", line 871, in __set__\r\n    self._validate(val)\r\n  File \"/Users/johnzeringue/.pyenv/versions/3.9.0/envs/pydata-panel/lib/python3.9/site-packages/param/__init__.py\", line 1891, in _validate\r\n    raise ValueError(\"CalendarDate '%s' only takes datetime types.\"%self.name)\r\nValueError: CalendarDate 'value' only takes datetime types.\r\n```\r\n\r\n#### Screenshots or screencasts of the bug in action\r\n\r\n<img width=\"478\" alt=\"Screen Shot 2020-11-13 at 4 24 00 PM\" src=\"https://user-images.githubusercontent.com/3858785/99122635-b844ba00-25cc-11eb-83c4-57760c138586.png\">\r\n\n", "before_files": [{"content": "\"\"\"\nDefines the Location  widget which allows changing the href of the window.\n\"\"\"\n\nimport urllib.parse as urlparse\n\nimport param\n\nfrom ..models.location import Location as _BkLocation\nfrom ..reactive import Syncable\nfrom ..util import parse_query\nfrom .state import state\n\n\nclass Location(Syncable):\n    \"\"\"\n    The Location component can be made available in a server context\n    to provide read and write access to the URL components in the\n    browser.\n    \"\"\"\n\n    href = param.String(readonly=True, doc=\"\"\"\n        The full url, e.g. 'https://localhost:80?color=blue#interact'\"\"\")\n\n    hostname = param.String(readonly=True, doc=\"\"\"\n        hostname in window.location e.g. 'panel.holoviz.org'\"\"\")\n\n    pathname = param.String(regex=r\"^$|[\\/].*$\", doc=\"\"\"\n        pathname in window.location e.g. '/user_guide/Interact.html'\"\"\")\n\n    protocol = param.String(readonly=True, doc=\"\"\"\n        protocol in window.location e.g. 'http:' or 'https:'\"\"\")\n\n    port = param.String(readonly=True, doc=\"\"\"\n        port in window.location e.g. '80'\"\"\")\n\n    search = param.String(regex=r\"^$|\\?\", doc=\"\"\"\n        search in window.location e.g. '?color=blue'\"\"\")\n\n    hash = param.String(regex=r\"^$|#\", doc=\"\"\"\n        hash in window.location e.g. '#interact'\"\"\")\n\n    reload = param.Boolean(default=False, doc=\"\"\"\n        Reload the page when the location is updated. For multipage\n        apps this should be set to True, For single page apps this\n        should be set to False\"\"\")\n\n    # Mapping from parameter name to bokeh model property name\n    _rename = {\"name\": None}\n\n    def __init__(self, **params):\n        super(Location, self).__init__(**params)\n        self._synced = []\n        self._syncing = False\n        self.param.watch(self._update_synced, ['search'])\n\n    def _get_model(self, doc, root=None, parent=None, comm=None):\n        model = _BkLocation(**self._process_param_change(self._init_properties()))\n        root = root or model\n        values = dict(self.param.get_param_values())\n        properties = list(self._process_param_change(values))\n        self._models[root.ref['id']] = (model, parent)\n        self._link_props(model, properties, doc, root, comm)\n        return model\n\n    def _get_root(self, doc=None, comm=None):\n        root = self._get_model(doc, comm=comm)\n        ref = root.ref['id']\n        state._views[ref] = (self, root, doc, comm)\n        self._documents[doc] = root\n        return root\n\n    def _cleanup(self, root):\n        if root.document in self._documents:\n            del self._documents[root.document]\n        ref = root.ref['id']\n        super()._cleanup(root)\n        if ref in state._views:\n            del state._views[ref]\n\n    def _update_synced(self, event=None):\n        if self._syncing:\n            return\n        query_params = self.query_params\n        for p, parameters, _ in self._synced:\n            mapping = {v: k for k, v in parameters.items()}\n            mapped = {}\n            for k, v in query_params.items():\n                if k not in mapping:\n                    continue\n                pname = mapping[k]\n                if isinstance(v, str) and v.startswith('\"') and v.endswith('\"'):\n                    v = v[1:-1]\n                else:\n                    try:\n                        v = p.param[pname].deserialize(v)\n                    except Exception:\n                        pass\n                mapped[pname] = v\n            p.param.set_param(**mapped)\n\n    def _update_query(self, *events, query=None):\n        if self._syncing:\n            return\n        query = query or {}\n        for e in events:\n            matches = [ps for o, ps, _ in self._synced if o in (e.cls, e.obj)]\n            if not matches:\n                continue\n            owner = e.cls if e.obj is None else e.obj\n            try:\n                val = owner.param.serialize_value(e.name)\n            except Exception:\n                val = e.new\n            query[matches[0][e.name]] = val\n        self._syncing = True\n        try:\n            self.update_query(**{k: v for k, v in query.items() if v is not None})\n        finally:\n            self._syncing = False\n\n    @property\n    def query_params(self):\n        return parse_query(self.search)\n\n    def update_query(self, **kwargs):\n        query = self.query_params\n        query.update(kwargs)\n        self.search = '?' + urlparse.urlencode(query)\n\n    def sync(self, parameterized, parameters=None):\n        \"\"\"\n        Syncs the parameters of a Parameterized object with the query\n        parameters in the URL. If no parameters are supplied all\n        parameters except the name are synced.\n\n        Arguments\n        ---------\n        parameterized (param.Parameterized):\n          The Parameterized object to sync query parameters with\n        parameters (list or dict):\n          A list or dictionary specifying parameters to sync.\n          If a dictionary is supplied it should define a mapping from\n          the Parameterized's parameteres to the names of the query\n          parameters.\n        \"\"\"\n        parameters = parameters or [p for p in parameterized.param if p != 'name']\n        if not isinstance(parameters, dict):\n            parameters = dict(zip(parameters, parameters))\n        watcher = parameterized.param.watch(self._update_query, list(parameters))\n        self._synced.append((parameterized, parameters, watcher))\n        self._update_synced()\n        self._update_query(query={v: getattr(parameterized, k)\n                                  for k, v in parameters.items()})\n\n    def unsync(self, parameterized, parameters=None):\n        \"\"\"\n        Unsyncs the parameters of the Parameterized with the query\n        params in the URL. If no parameters are supplied all\n        parameters except the name are unsynced.\n\n        Arguments\n        ---------\n        parameterized (param.Parameterized):\n          The Parameterized object to unsync query parameters with\n        parameters (list or dict):\n          A list of parameters to unsync.\n        \"\"\"\n        matches = [s for s in self._synced if s[0] is parameterized]\n        if not matches:\n            ptype = type(parameterized)\n            raise ValueError(f\"Cannot unsync {ptype} object since it \"\n                             \"was never synced in the first place.\")\n        synced = []\n        for p, params, watcher in self._synced:\n            if parameterized is p:\n                parameterized.param.unwatch(watcher)\n                if parameters is not None:\n                    new_params = {p: q for p, q in params.items()\n                                  if p not in parameters}\n                    new_watcher = parameterized.param.watch(watcher.fn, list(new_params))\n                    synced.append((p, new_params, new_watcher))\n            else:\n                synced.append((p, params, watcher))\n        self._synced = synced\n", "path": "panel/io/location.py"}], "after_files": [{"content": "\"\"\"\nDefines the Location  widget which allows changing the href of the window.\n\"\"\"\n\nimport json\nimport urllib.parse as urlparse\n\nimport param\n\nfrom ..models.location import Location as _BkLocation\nfrom ..reactive import Syncable\nfrom ..util import parse_query\nfrom .state import state\n\n\nclass Location(Syncable):\n    \"\"\"\n    The Location component can be made available in a server context\n    to provide read and write access to the URL components in the\n    browser.\n    \"\"\"\n\n    href = param.String(readonly=True, doc=\"\"\"\n        The full url, e.g. 'https://localhost:80?color=blue#interact'\"\"\")\n\n    hostname = param.String(readonly=True, doc=\"\"\"\n        hostname in window.location e.g. 'panel.holoviz.org'\"\"\")\n\n    pathname = param.String(regex=r\"^$|[\\/].*$\", doc=\"\"\"\n        pathname in window.location e.g. '/user_guide/Interact.html'\"\"\")\n\n    protocol = param.String(readonly=True, doc=\"\"\"\n        protocol in window.location e.g. 'http:' or 'https:'\"\"\")\n\n    port = param.String(readonly=True, doc=\"\"\"\n        port in window.location e.g. '80'\"\"\")\n\n    search = param.String(regex=r\"^$|\\?\", doc=\"\"\"\n        search in window.location e.g. '?color=blue'\"\"\")\n\n    hash = param.String(regex=r\"^$|#\", doc=\"\"\"\n        hash in window.location e.g. '#interact'\"\"\")\n\n    reload = param.Boolean(default=False, doc=\"\"\"\n        Reload the page when the location is updated. For multipage\n        apps this should be set to True, For single page apps this\n        should be set to False\"\"\")\n\n    # Mapping from parameter name to bokeh model property name\n    _rename = {\"name\": None}\n\n    def __init__(self, **params):\n        super(Location, self).__init__(**params)\n        self._synced = []\n        self._syncing = False\n        self.param.watch(self._update_synced, ['search'])\n\n    def _get_model(self, doc, root=None, parent=None, comm=None):\n        model = _BkLocation(**self._process_param_change(self._init_properties()))\n        root = root or model\n        values = dict(self.param.get_param_values())\n        properties = list(self._process_param_change(values))\n        self._models[root.ref['id']] = (model, parent)\n        self._link_props(model, properties, doc, root, comm)\n        return model\n\n    def _get_root(self, doc=None, comm=None):\n        root = self._get_model(doc, comm=comm)\n        ref = root.ref['id']\n        state._views[ref] = (self, root, doc, comm)\n        self._documents[doc] = root\n        return root\n\n    def _cleanup(self, root):\n        if root.document in self._documents:\n            del self._documents[root.document]\n        ref = root.ref['id']\n        super()._cleanup(root)\n        if ref in state._views:\n            del state._views[ref]\n\n    def _update_synced(self, event=None):\n        if self._syncing:\n            return\n        query_params = self.query_params\n        for p, parameters, _ in self._synced:\n            mapping = {v: k for k, v in parameters.items()}\n            mapped = {}\n            for k, v in query_params.items():\n                if k not in mapping:\n                    continue\n                pname = mapping[k]\n                try:\n                    v = p.param[pname].deserialize(v)\n                except Exception:\n                    pass\n                mapped[pname] = v\n            p.param.set_param(**mapped)\n\n    def _update_query(self, *events, query=None):\n        if self._syncing:\n            return\n        serialized = query or {}\n        for e in events:\n            matches = [ps for o, ps, _ in self._synced if o in (e.cls, e.obj)]\n            if not matches:\n                continue\n            owner = e.cls if e.obj is None else e.obj\n            try:\n                val = owner.param[e.name].serialize(e.new)\n            except Exception:\n                val = e.new\n            if not isinstance(val, str):\n                val = json.dumps(val)\n            serialized[matches[0][e.name]] = val\n        self._syncing = True\n        try:\n            self.update_query(**{k: v for k, v in serialized.items() if v is not None})\n        finally:\n            self._syncing = False\n\n    @property\n    def query_params(self):\n        return parse_query(self.search)\n\n    def update_query(self, **kwargs):\n        query = self.query_params\n        query.update(kwargs)\n        self.search = '?' + urlparse.urlencode(query)\n\n    def sync(self, parameterized, parameters=None):\n        \"\"\"\n        Syncs the parameters of a Parameterized object with the query\n        parameters in the URL. If no parameters are supplied all\n        parameters except the name are synced.\n\n        Arguments\n        ---------\n        parameterized (param.Parameterized):\n          The Parameterized object to sync query parameters with\n        parameters (list or dict):\n          A list or dictionary specifying parameters to sync.\n          If a dictionary is supplied it should define a mapping from\n          the Parameterized's parameteres to the names of the query\n          parameters.\n        \"\"\"\n        parameters = parameters or [p for p in parameterized.param if p != 'name']\n        if not isinstance(parameters, dict):\n            parameters = dict(zip(parameters, parameters))\n        watcher = parameterized.param.watch(self._update_query, list(parameters))\n        self._synced.append((parameterized, parameters, watcher))\n        self._update_synced()\n        query = {}\n        for p, name in parameters.items():\n            v = getattr(parameterized, p)\n            if v is None:\n                continue\n            try:\n                parameterized.param[p].serialize(v)\n            except Exception:\n                pass\n            if not isinstance(v, str):\n                v = json.dumps(v)\n            query[name] = v\n        self._update_query(query=query)\n\n    def unsync(self, parameterized, parameters=None):\n        \"\"\"\n        Unsyncs the parameters of the Parameterized with the query\n        params in the URL. If no parameters are supplied all\n        parameters except the name are unsynced.\n\n        Arguments\n        ---------\n        parameterized (param.Parameterized):\n          The Parameterized object to unsync query parameters with\n        parameters (list or dict):\n          A list of parameters to unsync.\n        \"\"\"\n        matches = [s for s in self._synced if s[0] is parameterized]\n        if not matches:\n            ptype = type(parameterized)\n            raise ValueError(f\"Cannot unsync {ptype} object since it \"\n                             \"was never synced in the first place.\")\n        synced = []\n        for p, params, watcher in self._synced:\n            if parameterized is p:\n                parameterized.param.unwatch(watcher)\n                if parameters is not None:\n                    new_params = {p: q for p, q in params.items()\n                                  if p not in parameters}\n                    new_watcher = parameterized.param.watch(watcher.fn, list(new_params))\n                    synced.append((p, new_params, new_watcher))\n            else:\n                synced.append((p, params, watcher))\n        self._synced = synced\n", "path": "panel/io/location.py"}]}