prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Viewer configuration does not show linking options
  **Describe the bug**
  The view and edit pages for viewer configurations no longer show options to set the linking configuration.
  
  **To Reproduce**
  Steps to reproduce the behavior:
  1. Go to https://grand-challenge.org/viewer-configurations/demo-rse/
  2. Scroll down to 'Linking Configuration'
  The options displayed are duplicates of the 'Plugin and Tools' section.
  
  **Expected behavior**
  A clear and concise description of what you expected to happen.
  
  **Screenshots**
  If applicable, add screenshots to help explain your problem.
  
  **Desktop (please complete the following information):**
   - OS: [e.g. iOS]
   - Browser [e.g. chrome, safari]
   - Version [e.g. 22]
  
  **Smartphone (please complete the following information):**
   - Device: [e.g. iPhone6]
   - OS: [e.g. iOS8.1]
   - Browser [e.g. stock browser, safari]
   - Version [e.g. 22]
  
  **Additional context**
  Add any other context about the problem here.
  
  
  </issue>
  <code>
  [start of app/grandchallenge/workstation_configs/forms.py]
  1 from crispy_forms.helper import FormHelper
  2 from crispy_forms.layout import Fieldset, Layout, Submit
  3 from django.forms import ModelForm
  4 from django_select2.forms import Select2MultipleWidget
  5 
  6 from grandchallenge.core.forms import SaveFormInitMixin
  7 from grandchallenge.core.widgets import ColorEditorWidget, JSONEditorWidget
  8 from grandchallenge.workstation_configs.models import (
  9     KEY_BINDINGS_SCHEMA,
  10     OVERLAY_SEGMENTS_SCHEMA,
  11     WorkstationConfig,
  12 )
  13 
  14 GENERAL_FIELDS = (
  15     "title",
  16     "description",
  17     "image_context",
  18     "window_presets",
  19     "default_window_preset",
  20     "default_slab_thickness_mm",
  21     "default_slab_render_method",
  22     "default_orientation",
  23     "default_image_interpolation",
  24     "default_limit_view_area_to_image_volume",
  25     "default_overlay_alpha",
  26     "ghosting_slice_depth",
  27     "overlay_luts",
  28     "default_overlay_lut",
  29     "default_overlay_interpolation",
  30     "overlay_segments",
  31     "key_bindings",
  32     "default_zoom_scale",
  33     "default_brush_size",
  34     "default_annotation_color",
  35     "default_annotation_line_width",
  36     "auto_jump_center_of_gravity",
  37     "point_bounding_box_size_mm",
  38 )
  39 PLUGIN_FIELDS = (
  40     "show_image_info_plugin",
  41     "show_display_plugin",
  42     "show_image_switcher_plugin",
  43     "show_algorithm_output_plugin",
  44     "show_overlay_plugin",
  45     "show_annotation_statistics_plugin",
  46     "show_swivel_tool",
  47     "show_invert_tool",
  48     "show_flip_tool",
  49     "show_window_level_tool",
  50     "show_reset_tool",
  51     "show_overlay_selection_tool",
  52     "show_lut_selection_tool",
  53     "show_annotation_counter_tool",
  54     "enable_contrast_enhancement",
  55 )
  56 LINKED_FIELDS = (
  57     "link_images",
  58     "link_panning",
  59     "link_zooming",
  60     "link_slicing",
  61     "link_orienting",
  62     "link_windowing",
  63     "link_inverting",
  64     "link_flipping",
  65 )
  66 
  67 
  68 class WorkstationConfigForm(SaveFormInitMixin, ModelForm):
  69     def __init__(self, *args, read_only=False, **kwargs):
  70         super().__init__(*args, **kwargs)
  71 
  72         self.helper = FormHelper(self)
  73         self.helper.layout = Layout(
  74             Fieldset("", *GENERAL_FIELDS),
  75             Fieldset(
  76                 "Plugins and Tools",
  77                 *PLUGIN_FIELDS,
  78                 css_class="border rounded px-2 my-4",
  79             ),
  80             Fieldset(
  81                 "Linking Configuration",
  82                 *PLUGIN_FIELDS,
  83                 css_class="border rounded px-2 my-4",
  84             ),
  85         )
  86 
  87         if read_only:
  88             for field in self.fields:
  89                 self.fields[field].disabled = True
  90         else:
  91             self.helper.layout.append(Submit("save", "Save"))
  92 
  93     class Meta:
  94         model = WorkstationConfig
  95         fields = (
  96             *GENERAL_FIELDS,
  97             *PLUGIN_FIELDS,
  98             *LINKED_FIELDS,
  99         )
  100 
  101         widgets = {
  102             "overlay_segments": JSONEditorWidget(
  103                 schema=OVERLAY_SEGMENTS_SCHEMA
  104             ),
  105             "key_bindings": JSONEditorWidget(schema=KEY_BINDINGS_SCHEMA),
  106             "default_annotation_color": ColorEditorWidget(format="hex"),
  107             "window_presets": Select2MultipleWidget,
  108             "overlay_luts": Select2MultipleWidget,
  109         }
  110         help_texts = {
  111             "overlay_segments": (
  112                 model._meta.get_field("overlay_segments").help_text
  113                 + ". If an categorical overlay is shown, it is possible to show toggles "
  114                 "to change the visibility of the different overlay categories. To do "
  115                 "so, configure the categories that should be displayed. Data from the"
  116                 " algorithm's output.json can be added as an extra label to each "
  117                 "toggle using jinja templating. "
  118                 'For example: [{ "voxel_value": 0, "name": "Level 0", "visible": '
  119                 'false, "metric_template": "{{metrics.volumes[0]}} mm³"},]'
  120             ),
  121             "key_bindings": model._meta.get_field("key_bindings").help_text
  122             + ". A copy and paste JSON can be obtained from the viewer.",
  123         }
  124
  [end of app/grandchallenge/workstation_configs/forms.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/app/grandchallenge/workstation_configs/forms.py b/app/grandchallenge/workstation_configs/forms.py
  --- a/app/grandchallenge/workstation_configs/forms.py
  +++ b/app/grandchallenge/workstation_configs/forms.py
  @@ -79,7 +79,7 @@
               ),
               Fieldset(
                   "Linking Configuration",
  -                *PLUGIN_FIELDS,
  +                *LINKED_FIELDS,
                   css_class="border rounded px-2 my-4",
               ),
           )
  
verification_info: {"golden_diff": "diff --git a/app/grandchallenge/workstation_configs/forms.py b/app/grandchallenge/workstation_configs/forms.py\n--- a/app/grandchallenge/workstation_configs/forms.py\n+++ b/app/grandchallenge/workstation_configs/forms.py\n@@ -79,7 +79,7 @@\n             ),\n             Fieldset(\n                 \"Linking Configuration\",\n-                *PLUGIN_FIELDS,\n+                *LINKED_FIELDS,\n                 css_class=\"border rounded px-2 my-4\",\n             ),\n         )\n", "issue": "Viewer configuration does not show linking options\n**Describe the bug**\r\nThe view and edit pages for viewer configurations no longer show options to set the linking configuration.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to https://grand-challenge.org/viewer-configurations/demo-rse/\r\n2. Scroll down to 'Linking Configuration'\r\nThe options displayed are duplicates of the 'Plugin and Tools' section.\r\n\r\n**Expected behavior**\r\nA clear and concise description of what you expected to happen.\r\n\r\n**Screenshots**\r\nIf applicable, add screenshots to help explain your problem.\r\n\r\n**Desktop (please complete the following information):**\r\n - OS: [e.g. iOS]\r\n - Browser [e.g. chrome, safari]\r\n - Version [e.g. 22]\r\n\r\n**Smartphone (please complete the following information):**\r\n - Device: [e.g. iPhone6]\r\n - OS: [e.g. iOS8.1]\r\n - Browser [e.g. stock browser, safari]\r\n - Version [e.g. 22]\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.\r\n\n", "before_files": [{"content": "from crispy_forms.helper import FormHelper\nfrom crispy_forms.layout import Fieldset, Layout, Submit\nfrom django.forms import ModelForm\nfrom django_select2.forms import Select2MultipleWidget\n\nfrom grandchallenge.core.forms import SaveFormInitMixin\nfrom grandchallenge.core.widgets import ColorEditorWidget, JSONEditorWidget\nfrom grandchallenge.workstation_configs.models import (\n    KEY_BINDINGS_SCHEMA,\n    OVERLAY_SEGMENTS_SCHEMA,\n    WorkstationConfig,\n)\n\nGENERAL_FIELDS = (\n    \"title\",\n    \"description\",\n    \"image_context\",\n    \"window_presets\",\n    \"default_window_preset\",\n    \"default_slab_thickness_mm\",\n    \"default_slab_render_method\",\n    \"default_orientation\",\n    \"default_image_interpolation\",\n    \"default_limit_view_area_to_image_volume\",\n    \"default_overlay_alpha\",\n    \"ghosting_slice_depth\",\n    \"overlay_luts\",\n    \"default_overlay_lut\",\n    \"default_overlay_interpolation\",\n    \"overlay_segments\",\n    \"key_bindings\",\n    \"default_zoom_scale\",\n    \"default_brush_size\",\n    \"default_annotation_color\",\n    \"default_annotation_line_width\",\n    \"auto_jump_center_of_gravity\",\n    \"point_bounding_box_size_mm\",\n)\nPLUGIN_FIELDS = (\n    \"show_image_info_plugin\",\n    \"show_display_plugin\",\n    \"show_image_switcher_plugin\",\n    \"show_algorithm_output_plugin\",\n    \"show_overlay_plugin\",\n    \"show_annotation_statistics_plugin\",\n    \"show_swivel_tool\",\n    \"show_invert_tool\",\n    \"show_flip_tool\",\n    \"show_window_level_tool\",\n    \"show_reset_tool\",\n    \"show_overlay_selection_tool\",\n    \"show_lut_selection_tool\",\n    \"show_annotation_counter_tool\",\n    \"enable_contrast_enhancement\",\n)\nLINKED_FIELDS = (\n    \"link_images\",\n    \"link_panning\",\n    \"link_zooming\",\n    \"link_slicing\",\n    \"link_orienting\",\n    \"link_windowing\",\n    \"link_inverting\",\n    \"link_flipping\",\n)\n\n\nclass WorkstationConfigForm(SaveFormInitMixin, ModelForm):\n    def __init__(self, *args, read_only=False, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        self.helper = FormHelper(self)\n        self.helper.layout = Layout(\n            Fieldset(\"\", *GENERAL_FIELDS),\n            Fieldset(\n                \"Plugins and Tools\",\n                *PLUGIN_FIELDS,\n                css_class=\"border rounded px-2 my-4\",\n            ),\n            Fieldset(\n                \"Linking Configuration\",\n                *PLUGIN_FIELDS,\n                css_class=\"border rounded px-2 my-4\",\n            ),\n        )\n\n        if read_only:\n            for field in self.fields:\n                self.fields[field].disabled = True\n        else:\n            self.helper.layout.append(Submit(\"save\", \"Save\"))\n\n    class Meta:\n        model = WorkstationConfig\n        fields = (\n            *GENERAL_FIELDS,\n            *PLUGIN_FIELDS,\n            *LINKED_FIELDS,\n        )\n\n        widgets = {\n            \"overlay_segments\": JSONEditorWidget(\n                schema=OVERLAY_SEGMENTS_SCHEMA\n            ),\n            \"key_bindings\": JSONEditorWidget(schema=KEY_BINDINGS_SCHEMA),\n            \"default_annotation_color\": ColorEditorWidget(format=\"hex\"),\n            \"window_presets\": Select2MultipleWidget,\n            \"overlay_luts\": Select2MultipleWidget,\n        }\n        help_texts = {\n            \"overlay_segments\": (\n                model._meta.get_field(\"overlay_segments\").help_text\n                + \". If an categorical overlay is shown, it is possible to show toggles \"\n                \"to change the visibility of the different overlay categories. To do \"\n                \"so, configure the categories that should be displayed. Data from the\"\n                \" algorithm's output.json can be added as an extra label to each \"\n                \"toggle using jinja templating. \"\n                'For example: [{ \"voxel_value\": 0, \"name\": \"Level 0\", \"visible\": '\n                'false, \"metric_template\": \"{{metrics.volumes[0]}} mm\u00b3\"},]'\n            ),\n            \"key_bindings\": model._meta.get_field(\"key_bindings\").help_text\n            + \". A copy and paste JSON can be obtained from the viewer.\",\n        }\n", "path": "app/grandchallenge/workstation_configs/forms.py"}]}