django-spire 0.23.0__py3-none-any.whl → 0.23.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
django_spire/consts.py CHANGED
@@ -1,4 +1,4 @@
1
- __VERSION__ = '0.23.0'
1
+ __VERSION__ = '0.23.3'
2
2
 
3
3
  MAINTENANCE_MODE_SETTINGS_NAME = 'MAINTENANCE_MODE'
4
4
 
@@ -1,7 +1,6 @@
1
- from enum import Enum
1
+ from enum import StrEnum
2
2
 
3
3
 
4
- # Todo: Change to string enum
5
- class SessionFilterActionEnum(Enum):
4
+ class SessionFilterActionEnum(StrEnum):
6
5
  CLEAR = 'Clear'
7
6
  FILTER = 'Filter'
@@ -22,24 +22,35 @@ class SessionFilterQuerySetMixin(QuerySet):
22
22
  ) -> QuerySet:
23
23
  # Session keys must match to process new queryset data
24
24
 
25
- action = request.GET.get('action')
25
+ try:
26
+ action = SessionFilterActionEnum(request.GET.get('action'))
27
+ except ValueError:
28
+ action = None
29
+
26
30
  form = form_class(request.GET)
27
31
 
28
32
  if form.is_valid():
29
33
  session = SessionController(request=request, session_key=session_key)
30
34
 
31
- # Todo: Change actions into an enum
32
- if action == SessionFilterActionEnum.CLEAR.value:
35
+ if action == SessionFilterActionEnum.CLEAR:
33
36
  session.purge()
34
37
  return self
35
38
 
36
- # The user has submitted the filter form
37
- if action == SessionFilterActionEnum.FILTER.value and session_key == request.GET.get('session_filter_key'):
38
-
39
+ # Apply filters when the user submits the filter form
40
+ if (
41
+ action == SessionFilterActionEnum.FILTER
42
+ and session_key == request.GET.get('session_filter_key')
43
+ ):
39
44
  # Update session data
40
45
  for key, value in form.cleaned_data.items():
41
46
  session.add_data(key, value)
42
47
 
48
+ # If the session is expired, return the unfiltered queryset
49
+ if session.is_expired:
50
+ return self
51
+
52
+ # When no new filter data is applied and session is NOT yet expired,
53
+ # return the original queryset
43
54
  return self.bulk_filter(session.data)
44
55
  else:
45
56
  show_form_errors(request, form)
@@ -75,7 +75,6 @@ class SessionController:
75
75
  self._set_modified()
76
76
 
77
77
  def _clean(self) -> None:
78
-
79
78
  if self._TIMEOUT_KEY in self.data and self.is_expired:
80
79
  self.request.session.pop(self.session_key)
81
80
  self._set_modified()
@@ -66,7 +66,8 @@
66
66
  batch_size: this.batch_size
67
67
  });
68
68
 
69
- let url = `${this.endpoint}?${params}`;
69
+ let separator = this.endpoint.includes('?') ? '&' : '?';
70
+ let url = `${this.endpoint}${separator}${params}`;
70
71
  let view = new ViewGlue(url, {});
71
72
 
72
73
  let previous_count = this.loaded_count;
@@ -129,24 +130,13 @@
129
130
  >
130
131
  <div x-ref="content_container"></div>
131
132
 
132
- <div style="height: 10px;" x-ref="infinite_scroll_trigger"></div>
133
- </div>
134
-
135
- <template x-if="show_loading">
136
- <div
137
- class="position-absolute d-flex justify-content-center align-items-center"
138
- style="top: 0; left: 0; right: 0; bottom: 0; background: color-mix(in srgb, var(--app-layer-one) 85%, transparent);"
139
- >
133
+ <div x-cloak x-show="show_loading" class="py-3 text-center">
140
134
  <div class="spinner-border text-app-primary" role="status"></div>
141
135
  </div>
142
- </template>
143
- </div>
144
136
 
145
- <div class="row mt-3">
146
- <div class="col text-start">
147
- <span class="fs-7 text-app-secondary">
148
- Showing <span x-text="loaded_count"></span> of <span x-text="total_count"></span> items
149
- </span>
137
+ <div style="height: 10px;" x-ref="infinite_scroll_trigger"></div>
150
138
  </div>
151
139
  </div>
140
+
141
+ {% include 'django_spire/infinite_scroll/element/footer.html' %}
152
142
  </div>
@@ -0,0 +1,44 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from dandy import Bot, Prompt
6
+
7
+ from django_spire.knowledge.intelligence.intel.answer_intel import AnswerIntel
8
+
9
+ if TYPE_CHECKING:
10
+ from django_spire.knowledge.entry.models import Entry
11
+
12
+
13
+ class KnowledgeAnswerBot(Bot):
14
+ llm_role = 'Knowledge Entry Search Assistant'
15
+ llm_task = 'Read through the knowledge and answer the users request.'
16
+ llm_guidelines = (
17
+ Prompt()
18
+ .list([
19
+ 'Make sure the answer is relevant and reflects knowledge entries.',
20
+ 'Do not make up information use the provided knowledge entries as a source of truth.',
21
+ 'Use line breaks to separate sections of the answer and use 2 if you need to separate the section from the previous.'
22
+ ])
23
+ )
24
+ llm_intel_class = AnswerIntel
25
+
26
+ def process(self, user_input: str, entries: list[Entry]) -> AnswerIntel:
27
+
28
+ entry_prompt = Prompt()
29
+ entry_prompt.sub_heading('User Request')
30
+ entry_prompt.line_break()
31
+ entry_prompt.text(f'{user_input}')
32
+ entry_prompt.line_break()
33
+ entry_prompt.sub_heading('Knowledge')
34
+ entry_prompt.line_break()
35
+
36
+ for entry in entries:
37
+ for version_block in entry.current_version.blocks.all():
38
+ if version_block.render_to_text() != '\n':
39
+ entry_prompt.text(f'{version_block.render_to_text()}')
40
+
41
+ return self.llm.prompt_to_intel(
42
+ prompt=entry_prompt,
43
+ )
44
+
@@ -1,4 +1,5 @@
1
1
  from __future__ import annotations
2
+
2
3
  from typing import TYPE_CHECKING
3
4
 
4
5
  from dandy import Bot, Prompt
@@ -9,14 +10,14 @@ if TYPE_CHECKING:
9
10
  from django_spire.knowledge.entry.models import Entry
10
11
 
11
12
 
12
- class EntriesSearchBot(Bot):
13
+ class KnowledgeEntriesBot(Bot):
13
14
  llm_role = 'Knowledge Entry Search Assistant'
14
- llm_task = 'Read through the knowledge and return information and the block id that relevant to the information request.'
15
+ llm_task = 'Read through the knowledge entries and return the most relevant for the user request.'
15
16
  llm_guidelines = (
16
17
  Prompt()
17
18
  .list([
18
- 'Please read through all the blocks and return 2 of the most relevant ones.',
19
- 'You can add any of the text in the knowledge entries to the 2 responses if it helps.',
19
+ 'Return 1 to 5 of the most relevant knowledge entries using block ids.',
20
+ 'The relevant headings should be the nearest heading above the selected knowledge entry block.',
20
21
  'Make sure the relevant heading text is from a heading with mark down formatting.',
21
22
  'When returning the relevant heading remove any of the markdown formating characters.',
22
23
  ])
@@ -26,7 +27,7 @@ class EntriesSearchBot(Bot):
26
27
  def process(self, user_input: str, entries: list[Entry]) -> EntriesIntel:
27
28
 
28
29
  entry_prompt = Prompt()
29
- entry_prompt.sub_heading('Information Request')
30
+ entry_prompt.sub_heading('User Request')
30
31
  entry_prompt.line_break()
31
32
  entry_prompt.text(f'{user_input}')
32
33
  entry_prompt.line_break()
@@ -0,0 +1,6 @@
1
+ from dandy import BaseIntel
2
+
3
+
4
+
5
+ class AnswerIntel(BaseIntel):
6
+ answer: str
@@ -1,28 +1,17 @@
1
1
  from __future__ import annotations
2
2
 
3
- from enum import Enum
4
3
 
5
4
  from dandy import BaseIntel, BaseListIntel
6
5
 
7
6
  from django_spire.knowledge.entry.models import Entry
8
7
 
9
8
 
10
- class EntryRelevancy(str, Enum):
11
- EXTREMELY = 'Extremely'
12
- VERY = 'Very'
13
- SOMEWHAT = 'Somewhat'
14
- NOT_SO_MUCH = 'Not so much'
15
- NO_RELEVANCE = 'No Relevance'
16
-
17
-
18
9
  class EntryIntel(BaseIntel):
19
10
  relevant_heading_text: str
20
- relevant_text: str
21
11
  relevant_block_id: int
22
- relevancy: EntryRelevancy
23
12
 
24
13
  def __str__(self):
25
- return self.relevant_heading_text + ' ' + self.relevant_text
14
+ return self.relevant_heading_text
26
15
 
27
16
  @property
28
17
  def collection(self):
@@ -1,13 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from django_spire.ai.chat.message_intel import BaseMessageIntel
4
+ from django_spire.knowledge.intelligence.intel.answer_intel import AnswerIntel
4
5
  from django_spire.knowledge.intelligence.intel.entry_intel import EntriesIntel
5
6
 
6
7
 
7
8
  class KnowledgeMessageIntel(BaseMessageIntel):
8
9
  _template: str = 'django_spire/knowledge/message/knowledge_message_intel.html'
9
- body: str
10
+ answer_intel: AnswerIntel
10
11
  entries_intel: EntriesIntel
11
12
 
12
13
  def render_to_str(self) -> str:
13
- return self.body
14
+ return self.answer_intel.answer
@@ -7,7 +7,8 @@ from django.core.handlers.wsgi import WSGIRequest
7
7
  from django_spire.ai.chat.message_intel import DefaultMessageIntel, BaseMessageIntel
8
8
  from django_spire.core.tag.intelligence.tag_set_bot import TagSetBot
9
9
  from django_spire.knowledge.collection.models import Collection
10
- from django_spire.knowledge.intelligence.bots.entries_search_llm_bot import EntriesSearchBot
10
+ from django_spire.knowledge.intelligence.bots.knowledge_answer_bot import KnowledgeAnswerBot
11
+ from django_spire.knowledge.intelligence.bots.knowledge_entries_bot import KnowledgeEntriesBot
11
12
  from django_spire.knowledge.intelligence.intel.message_intel import KnowledgeMessageIntel
12
13
 
13
14
  if TYPE_CHECKING:
@@ -65,12 +66,19 @@ def knowledge_search_workflow(
65
66
  if not entries:
66
67
  return NO_KNOWLEDGE_MESSAGE_INTEL
67
68
 
68
- entries_intel = EntriesSearchBot(llm_temperature=0.0).process(
69
+ answer_intel_future = KnowledgeAnswerBot(llm_temperature=0.5).process_to_future(
69
70
  user_input=user_input,
70
71
  entries=entries
71
72
  )
72
73
 
74
+ entries_intel_future = KnowledgeEntriesBot(llm_temperature=0.5).process_to_future(
75
+ user_input=user_input,
76
+ entries=entries
77
+ )
78
+
79
+ print(entries_intel_future.result)
80
+
73
81
  return KnowledgeMessageIntel(
74
- body=f'{" ".join([str(entry) for entry in entries_intel])}',
75
- entries_intel=entries_intel,
82
+ answer_intel=answer_intel_future.result,
83
+ entries_intel=entries_intel_future.result,
76
84
  )
@@ -74,13 +74,13 @@ function create_editorjs_instance({holder_id, update_url, initial_editor_blocks}
74
74
 
75
75
  if (block_id) {
76
76
  setTimeout(() => {
77
- const element = document.querySelector(`[data-id="${block_id}"]`)
77
+ const element = document.querySelector(`[data-id="${block_id}"]`)?.firstElementChild
78
78
  if (element) {
79
79
  element.scrollIntoView({behavior: 'smooth', block: 'center'})
80
- element.style.transition = 'background-color 1s ease'
81
- element.classList.add('bg-app-accent-soft', 'mx-3', 'rounded-3')
80
+ element.style.transition = 'background-color 1s ease, padding 1s ease'
81
+ element.classList.add('bg-app-accent-soft', 'ps-2', 'rounded-3')
82
82
  setTimeout(() => {
83
- element.classList.remove('bg-app-accent-soft')
83
+ element.classList.remove('bg-app-accent-soft', 'ps-2')
84
84
  }, 4000)
85
85
  }
86
86
  }, 100)
@@ -1,30 +1,32 @@
1
1
  {% extends 'django_spire/ai/chat/message/message.html' %}
2
2
 
3
3
  {% block message_content %}
4
- {% for entry_intel in message_intel.entries_intel %}
5
-
6
- <div class="row">
7
- <div class="col">
8
- {{ entry_intel.relevant_text|linebreaksbr }}
9
- </div>
4
+ <div class="row">
5
+ <div class="col">
6
+ {{ message_intel.answer_intel.answer|linebreaksbr }}
10
7
  </div>
8
+ </div>
11
9
 
12
- <div class="row">
13
- <div class="col pt-1 pb-3 fs-7">
14
- <a href="{% url 'django_spire:knowledge:entry:version:page:editor' pk=entry_intel.entry.id %}?show_sub_nav=false&block_id={{ entry_intel.relevant_block_id }}"
15
- target="_blank">
16
- {{ entry_intel.relevant_heading_text }}
17
- </a>
18
- </div>
19
- </div>
10
+ <div class="row mt-2 p-1" x-data="{show_resources: false}">
11
+ <div class="col-auto mx-2 ps-1 pe-2 py-1 fs-7 rounded-3 border border-primary-subtle">
12
+ <span class="text-muted cursor-pointer" x-on:click="show_resources = !show_resources">
13
+ <i class="bi bi-caret-right" x-show="!show_resources"></i>
14
+ <i class="bi bi-caret-down" x-show="show_resources"></i>
15
+ Sources
16
+ </span>
20
17
 
21
- {% endfor %}
18
+ <ul class="my-0 me-3" x-show="show_resources">
19
+ {% for entry_intel in message_intel.entries_intel %}
20
+ <li class="pb-1">
21
+ <a href="{% url 'django_spire:knowledge:entry:version:page:editor' pk=entry_intel.entry.id %}?show_sub_nav=false&block_id={{ entry_intel.relevant_block_id }}"
22
+ target="_blank">
23
+ {{ entry_intel.relevant_heading_text }}
24
+ </a>
25
+ </li>
26
+ {% endfor %}
27
+ </ul>
22
28
 
23
- <div class="row">
24
- <div class="col">
25
- Is there anything else I can help with?
26
29
  </div>
27
30
  </div>
28
31
 
29
-
30
32
  {% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-spire
3
- Version: 0.23.0
3
+ Version: 0.23.3
4
4
  Summary: A project for Django Spire
5
5
  Author-email: Brayden Carlson <braydenc@stratusadv.com>, Nathan Johnson <nathanj@stratusadv.com>
6
6
  License: Copyright (c) 2024 Stratus Advanced Technologies and Contributors.
@@ -1,6 +1,6 @@
1
1
  django_spire/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  django_spire/conf.py,sha256=c5Hs-7lk9T15254tOasiQ2ZTFLQIVJof9_QJDfm1PAI,933
3
- django_spire/consts.py,sha256=xIvLbayXa8bBS1w8s_UdEMqzBVZIdIBVPm-BNoLz090,171
3
+ django_spire/consts.py,sha256=D5oVj-bY46n7ixDPRAWLe0rXEDktcI1whmswDjdKZOE,171
4
4
  django_spire/exceptions.py,sha256=L5ndRO5ftMmh0pHkO2z_NG3LSGZviJ-dDHNT73SzTNw,48
5
5
  django_spire/settings.py,sha256=B4GPqBGt_dmkt0Ay0j-IP-SZ6mY44m2Ap5kVSON5YLA,1005
6
6
  django_spire/urls.py,sha256=mKeZszb5U4iIGqddMb5Tt5fRC72U2wABEOi6mvOfEBU,656
@@ -355,9 +355,9 @@ django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.j
355
355
  django_spire/contrib/progress/templates/django_spire/contrib/progress/card/card.html,sha256=2Ajv0UBJEGwc4InVe69aLe2u4K56yh2JAuvO6uH24j8,3353
356
356
  django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html,sha256=oZ7mOxzro5809wSHLe4A90PonAqcr_eVawR_xHKXIt8,3682
357
357
  django_spire/contrib/queryset/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
358
- django_spire/contrib/queryset/enums.py,sha256=FhrwaEZ8Ql3AnImDleJFonp11-ObCZT24bC5fCCVBxE,132
358
+ django_spire/contrib/queryset/enums.py,sha256=nGUHwCVOCBfVXo-lrgyqRoEaMq0ZQAGOWnjALSFPjJU,108
359
359
  django_spire/contrib/queryset/filter_tools.py,sha256=o7OBB3Jjtyoj7aaWspkFKS2bv0BeMIigXz7DVvt6Ueo,1087
360
- django_spire/contrib/queryset/mixins.py,sha256=1F8uZihv4kwhlqNsnDKjol1o2OVaxuzoOZLdQebbrtY,1732
360
+ django_spire/contrib/queryset/mixins.py,sha256=Y_tK9ECr1cb_7AywpNaFKmqxRmNzvNuSCDyqVmfNcCE,2096
361
361
  django_spire/contrib/seeding/__init__.py,sha256=mHKO8a7fCAf70BWYjgyGgBDfssPtb3Pp9IxCVVI_4-M,112
362
362
  django_spire/contrib/seeding/field/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
363
363
  django_spire/contrib/seeding/field/base.py,sha256=SK8EYSsLgMRgosY8bRb3X27RpL7cq55VETf6Q_pYYr4,1198
@@ -409,7 +409,7 @@ django_spire/contrib/service/django_model_service.py,sha256=urQoEcrj2w3zxEILX0nr
409
409
  django_spire/contrib/service/exceptions.py,sha256=cQZitr-CiSJ1Aeah3L4kNYcFcicCGMu5AQtEI3TwiUE,113
410
410
  django_spire/contrib/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
411
411
  django_spire/contrib/session/apps.py,sha256=e2lvkf3lZIFYMsgzsdIb97kP3TSYF8W2u26lb0qqZkw,221
412
- django_spire/contrib/session/controller.py,sha256=sa4Pa1mIgcN-njajmF-6jsqJSnrnJssRcWjRgWbk_4Q,2927
412
+ django_spire/contrib/session/controller.py,sha256=wXnBmoRz_HBOvsxjkndv76AEG7itmTwoXZq6LcwPjME,2926
413
413
  django_spire/contrib/session/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
414
414
  django_spire/contrib/session/templatetags/session_tags.py,sha256=wVlW5_d6AMsMWqCwCgX39r6nS5NS6vbl7hmi_ZrVKmg,459
415
415
  django_spire/contrib/session/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -665,7 +665,7 @@ django_spire/core/templates/django_spire/forms/elements/list_element.html,sha256
665
665
  django_spire/core/templates/django_spire/forms/elements/value_element.html,sha256=LaOR2ggmf-J_cPCVHjNoD4l_858zHCRA58T_ZB3EIkE,57
666
666
  django_spire/core/templates/django_spire/forms/widgets/json_tree_widget.html,sha256=dykf6xYRZ477i6SgcGR3TSnxDwLsu2p3FR45hEr4DF8,1489
667
667
  django_spire/core/templates/django_spire/infinite_scroll/base.html,sha256=x4JJgXTnWXTRz2laFHBW5jpD4D9sU-P8eAUDgEc3-UU,10875
668
- django_spire/core/templates/django_spire/infinite_scroll/scroll.html,sha256=fF_U1EPoZbkhK0zh-Q7ggrvR12yCsT1UOY2z63uM8es,4668
668
+ django_spire/core/templates/django_spire/infinite_scroll/scroll.html,sha256=osZx9nsCypvnZY3dva_52MoZQRkLK0kOCMnGxHvhsUw,4311
669
669
  django_spire/core/templates/django_spire/infinite_scroll/element/footer.html,sha256=22yxDuYB2vKqaDaMsARStrYTYoHtPGYmK6Xl9XQdwH8,391
670
670
  django_spire/core/templates/django_spire/item/infinite_scroll_item.html,sha256=NMx3jQwtcKJiKtzbQXaXI3eWOtnJFiZhCI13tLTxSnc,1011
671
671
  django_spire/core/templates/django_spire/item/item.html,sha256=9AD6qRcYIb7q-EcmWlRUFiK8XfnmPBSS5NOsXdKEAAA,1217
@@ -966,12 +966,14 @@ django_spire/knowledge/entry/views/template_views.py,sha256=Y-3JnslI_hj4WesN8dJb
966
966
  django_spire/knowledge/intelligence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
967
967
  django_spire/knowledge/intelligence/router.py,sha256=4nPcIJJPHtwGgBXrLZiZaSNrfHDADrE5wCznvQOOm2s,802
968
968
  django_spire/knowledge/intelligence/bots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
969
- django_spire/knowledge/intelligence/bots/entries_search_llm_bot.py,sha256=Pnpbu9mzEm2_vKvUNz4DIqZL_XzZx4L44LQ2vIqDPnk,1664
969
+ django_spire/knowledge/intelligence/bots/knowledge_answer_bot.py,sha256=VGS8w25OoJjflBIrPOo9WOvWxceSIIwJ77c-FxSExJk,1501
970
+ django_spire/knowledge/intelligence/bots/knowledge_entries_bot.py,sha256=B8GBBZdpN-PIu1o_N1X55yvelJWC8U7yxRu_0ruwvxU,1642
970
971
  django_spire/knowledge/intelligence/intel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
971
- django_spire/knowledge/intelligence/intel/entry_intel.py,sha256=7B7qLqNl39VFQKq_e5m1ShhSNgN2AV2gqesKRCnXid0,844
972
- django_spire/knowledge/intelligence/intel/message_intel.py,sha256=iYXdOkS1KfP3QH3-KsTSJ_BspRh1vPw-zG7uJMNOWf8,419
972
+ django_spire/knowledge/intelligence/intel/answer_intel.py,sha256=wEo6uqj4bbv6IoYYPA1fD3Q-8UocS2dURa_jJHYuRcU,77
973
+ django_spire/knowledge/intelligence/intel/entry_intel.py,sha256=VgP8l5i8JML6G12kj2nwxP85Cknv00ktb6nrKzInJTE,569
974
+ django_spire/knowledge/intelligence/intel/message_intel.py,sha256=24z1dindbrHGLJH0e8oILxOQopnggLJeam8MMvdgUTc,529
973
975
  django_spire/knowledge/intelligence/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
974
- django_spire/knowledge/intelligence/workflows/knowledge_workflow.py,sha256=55e_zFeeKBglQ73hi3d71Zc7WLUuWO5SwvFLCP5rUDg,2449
976
+ django_spire/knowledge/intelligence/workflows/knowledge_workflow.py,sha256=zfEEDB6b4OI07YtAvzzpCHTssIrdt7twg2_t7iofIpY,2745
975
977
  django_spire/knowledge/migrations/0001_initial.py,sha256=0oAx4e0Tu1wbcMwQZ4I_B2X_EGdEA9Qz_UBdVNGc3yE,5487
976
978
  django_spire/knowledge/migrations/0002_alter_entryversionblock_type.py,sha256=Eg8tLjDO0nJ3go_jgVvoqwYKFOpYUUyNtZtLI2V3IQQ,527
977
979
  django_spire/knowledge/migrations/0003_alter_collection_order_alter_entry_order_and_more.py,sha256=nIIUg1lHQ1iLbPlOulwZgzHrP1erGMYVXDaEdDXv4ik,749
@@ -987,7 +989,7 @@ django_spire/knowledge/static/django_spire/knowledge/collection/js/managers.js,s
987
989
  django_spire/knowledge/static/django_spire/knowledge/collection/js/x_component.js,sha256=avczuHac3i58k06wA-LPpgupedCYbuDVTjTYVjEho18,898
988
990
  django_spire/knowledge/static/django_spire/knowledge/css/editor.css,sha256=9iDzPcMvf462CjfnOkdAFHBfRFt2io8HAyIQfwoSlug,2189
989
991
  django_spire/knowledge/static/django_spire/knowledge/css/navigation_items.css,sha256=jhjW4fiQI13PUAkSupLrLn-Fu9nzAVqMezK8EkJnGZ8,178
990
- django_spire/knowledge/static/django_spire/knowledge/entry/version/js/editor.js,sha256=zDK9PNO7XR0j95I17uBmfguSF8LzYijx3irM2my3IqA,3798
992
+ django_spire/knowledge/static/django_spire/knowledge/entry/version/js/editor.js,sha256=uxkJKCHyAgvVGv3s1MpDvcEYhAuecuoVMFOQMmIe7E0,3842
991
993
  django_spire/knowledge/static/django_spire/knowledge/entry/version/js/managers.js,sha256=q-HiSnOnMMomxU0EAWSbQO55HMVvb8wPxA0KCP3VyP4,2772
992
994
  django_spire/knowledge/static/django_spire/knowledge/entry/version/js/null_paragraph.js,sha256=Bc0oslLdlLcncbcUklhU1RF4PGiByC-mH-ENq1S1Niw,211
993
995
  django_spire/knowledge/templates/django_spire/knowledge/collection/card/form_card.html,sha256=Fm1PFgMJO0B1ji86pjeL_KbGkKq-ho7n6v9gtCODlzU,154
@@ -1015,7 +1017,7 @@ django_spire/knowledge/templates/django_spire/knowledge/entry/page/form_page.htm
1015
1017
  django_spire/knowledge/templates/django_spire/knowledge/entry/page/import_form_page.html,sha256=TK8Bc7mUZwsmV1Xm9FPyWz7Hws68Ijy4c55orvNoOC4,308
1016
1018
  django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/editor_container.html,sha256=-fPVVnCdDUMA0AoKjQ3bA7gRrbnggPRlRlPqYvgIoKA,3153
1017
1019
  django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/editor_page.html,sha256=uAIz2OP9AXah7xbZv_ukjGuKwPH330CqTBmnWGNXBMs,3262
1018
- django_spire/knowledge/templates/django_spire/knowledge/message/knowledge_message_intel.html,sha256=kOSsRJHkh8hFYp1k1Y0wc-wh75VVjdXldEKErkfANGY,855
1020
+ django_spire/knowledge/templates/django_spire/knowledge/message/knowledge_message_intel.html,sha256=n7Lbe_wvLR30B4Ko0Of_Ry20H8IzU4lQ1BsJyaX4J08,1283
1019
1021
  django_spire/knowledge/templates/django_spire/knowledge/page/full_page.html,sha256=vz3WQ6SAL43QALRf0haaLfNkUfIQQemR0FAZQ2tznV4,1331
1020
1022
  django_spire/knowledge/templates/django_spire/knowledge/page/home_page.html,sha256=LMGSoPuP4N0NMX9QB1r5qJaExDvt6IKlJNp69Dt2EeQ,293
1021
1023
  django_spire/knowledge/templates/django_spire/knowledge/sub_navigation/element/collection_sub_navigation_ellipsis_dropdown.html,sha256=DeM7yRcjRN25eRvdOK-3Ae0kbYaMWvk7Ufbc8AZphgk,1023
@@ -1193,8 +1195,8 @@ django_spire/theme/urls/page_urls.py,sha256=S8nkKkgbhG3XHI3uMUL-piOjXIrRkuY2UlM_
1193
1195
  django_spire/theme/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1194
1196
  django_spire/theme/views/json_views.py,sha256=PWwVTaty0BVGbj65L5cxex6JNhc-xVAI_rEYjbJWqEM,1893
1195
1197
  django_spire/theme/views/page_views.py,sha256=WenjOa6Welpu3IMolY56ZwBjy4aK9hpbiMNuygjAl1A,3922
1196
- django_spire-0.23.0.dist-info/licenses/LICENSE.md,sha256=tlTbOtgKoy-xAQpUk9gPeh9O4oRXCOzoWdW3jJz0wnA,1091
1197
- django_spire-0.23.0.dist-info/METADATA,sha256=D_Ci76LXS9AAtpSki9idJoi2EBdAta3wPc3OluSfq5A,5127
1198
- django_spire-0.23.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1199
- django_spire-0.23.0.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
1200
- django_spire-0.23.0.dist-info/RECORD,,
1198
+ django_spire-0.23.3.dist-info/licenses/LICENSE.md,sha256=tlTbOtgKoy-xAQpUk9gPeh9O4oRXCOzoWdW3jJz0wnA,1091
1199
+ django_spire-0.23.3.dist-info/METADATA,sha256=jiN0athZqM7GqaqMwLkR09-VP5oNYXUUT3PnQfGzbAw,5127
1200
+ django_spire-0.23.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1201
+ django_spire-0.23.3.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
1202
+ django_spire-0.23.3.dist-info/RECORD,,