micro-sidebar 1.2.2__py3-none-any.whl → 2.2.0__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.
- {micro_sidebar-1.2.2.dist-info → micro_sidebar-2.2.0.dist-info}/METADATA +117 -1
- micro_sidebar-2.2.0.dist-info/RECORD +31 -0
- sidebar/apps.py +10 -0
- sidebar/context_processors.py +127 -0
- sidebar/discovery.py +151 -0
- sidebar/static/sidebar/css/reorder.css +91 -0
- sidebar/static/sidebar/css/theme_picker.css +165 -0
- sidebar/static/sidebar/js/reorder.js +267 -0
- sidebar/static/sidebar/js/theme_picker.js +58 -0
- sidebar/static/sidebar/sidebar.css +34 -8
- sidebar/static/sidebar/sidebar.js +15 -40
- sidebar/static/themes/blue.css +51 -0
- sidebar/static/themes/dark.css +501 -0
- sidebar/static/themes/gold.css +51 -0
- sidebar/static/themes/green.css +63 -0
- sidebar/static/themes/light.css +51 -0
- sidebar/static/themes/main.css +6 -0
- sidebar/static/themes/main.js +41 -0
- sidebar/static/themes/red.css +51 -0
- sidebar/templates/sidebar/auto.html +15 -0
- sidebar/templates/sidebar/extra_groups.html +34 -0
- sidebar/templates/sidebar/main.html +94 -5
- sidebar/templatetags/__init__.py +1 -0
- sidebar/templatetags/sidebar_tags.py +74 -0
- micro_sidebar-1.2.2.dist-info/RECORD +0 -13
- {micro_sidebar-1.2.2.dist-info → micro_sidebar-2.2.0.dist-info}/LICENSE +0 -0
- {micro_sidebar-1.2.2.dist-info → micro_sidebar-2.2.0.dist-info}/WHEEL +0 -0
- {micro_sidebar-1.2.2.dist-info → micro_sidebar-2.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
2
|
+
const root = document.documentElement;
|
|
3
|
+
const themes = ['light', 'blue', 'gold', 'green', 'red', 'dark'];
|
|
4
|
+
|
|
5
|
+
// Load saved theme
|
|
6
|
+
const savedTheme = localStorage.getItem('appTheme');
|
|
7
|
+
if (savedTheme && themes.includes(savedTheme)) {
|
|
8
|
+
root.classList.add(`theme-${savedTheme}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Global function to set theme
|
|
12
|
+
window.setTheme = function(theme) {
|
|
13
|
+
// Remove all current theme classes
|
|
14
|
+
themes.forEach(t => root.classList.remove(`theme-${t}`));
|
|
15
|
+
|
|
16
|
+
if (theme && themes.includes(theme)) {
|
|
17
|
+
root.classList.add(`theme-${theme}`);
|
|
18
|
+
localStorage.setItem('appTheme', theme);
|
|
19
|
+
} else {
|
|
20
|
+
localStorage.removeItem('appTheme');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Visual Update: Highlight active theme circle
|
|
24
|
+
updateActiveThemeUI(theme || 'light');
|
|
25
|
+
|
|
26
|
+
// Dispatch event for components that might need resizing (like Plotly)
|
|
27
|
+
window.dispatchEvent(new Event('resize'));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function updateActiveThemeUI(activeTheme) {
|
|
31
|
+
document.querySelectorAll('.theme-preview').forEach(el => {
|
|
32
|
+
el.classList.remove('active');
|
|
33
|
+
if (el.getAttribute('data-theme') === activeTheme) {
|
|
34
|
+
el.classList.add('active');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Initialize UI on load
|
|
40
|
+
updateActiveThemeUI(savedTheme || 'light');
|
|
41
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* --- Red Theme (Bordeaux) --- */
|
|
2
|
+
:root.theme-red {
|
|
3
|
+
--title: #7f1d1d;
|
|
4
|
+
--body: #fef2f28b;
|
|
5
|
+
--htitle: #991b1b;
|
|
6
|
+
--hbody: #fee2e2db;
|
|
7
|
+
--table-row: #fdeded;
|
|
8
|
+
--table-row-hover: #fcdbdb;
|
|
9
|
+
--primal: #ef4444;
|
|
10
|
+
--primal_dark: #dc2626;
|
|
11
|
+
--primal-rgb: 239, 68, 68;
|
|
12
|
+
--btn-primary-shadow: rgba(239, 68, 68, 0.4);
|
|
13
|
+
|
|
14
|
+
/* Login Theme Variables */
|
|
15
|
+
--bg-gradient: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
|
|
16
|
+
--right-bg: var(--title);
|
|
17
|
+
--primary-color: var(--primal);
|
|
18
|
+
|
|
19
|
+
/* Bootstrap Overrides */
|
|
20
|
+
--bs-primary: var(--primal);
|
|
21
|
+
--bs-primary-rgb: var(--primal-rgb);
|
|
22
|
+
--bs-btn-bg: var(--primal);
|
|
23
|
+
--bs-btn-border-color: var(--primal);
|
|
24
|
+
--bs-btn-hover-bg: var(--primal_dark);
|
|
25
|
+
--bs-btn-hover-border-color: var(--primal_dark);
|
|
26
|
+
--bs-link-color: var(--primal);
|
|
27
|
+
--bs-link-hover-color: var(--primal_dark);
|
|
28
|
+
}
|
|
29
|
+
:root.theme-red .titlebar {
|
|
30
|
+
background: linear-gradient(90deg, #ffffff 10%, #fdeded 90%) !important;
|
|
31
|
+
}
|
|
32
|
+
:root.theme-red #sidebar {
|
|
33
|
+
background: linear-gradient(180deg, #ffffff 10%, #fdeded 100%) !important;
|
|
34
|
+
border-left: 1px solid #fcdbdb !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
:root.theme-red .page .right {
|
|
38
|
+
background: var(--primal_dark) !important; /* Darker logo container */
|
|
39
|
+
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
|
|
40
|
+
color: #e2e8f0 !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Red Overrides */
|
|
44
|
+
:root.theme-red .dropdown-item:hover {
|
|
45
|
+
background-color: rgba(239, 68, 68, 0.08) !important;
|
|
46
|
+
color: #dc2626 !important;
|
|
47
|
+
}
|
|
48
|
+
:root.theme-red .titlebar .btn-light:hover {
|
|
49
|
+
background-color: rgba(239, 68, 68, 0.08) !important;
|
|
50
|
+
color: #dc2626 !important;
|
|
51
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<div class="sidebar-auto-items" id="sidebarAutoItems">
|
|
2
|
+
{% for item in items %}
|
|
3
|
+
<a href="{{ item.url }}"
|
|
4
|
+
class="list-group-item list-group-item-action{% if item.active %} active{% endif %}"
|
|
5
|
+
data-url-name="{{ item.url_name }}">
|
|
6
|
+
<i class="bi {{ item.icon }} me-2" style="font-size: 24px;"></i>
|
|
7
|
+
<span>{{ item.label }}</span>
|
|
8
|
+
</a>
|
|
9
|
+
{% empty %}
|
|
10
|
+
<div class="p-3 text-center text-muted small">
|
|
11
|
+
<i class="bi bi-inbox mb-2" style="font-size: 24px;"></i>
|
|
12
|
+
<p class="mb-0">لا توجد عناصر</p>
|
|
13
|
+
</div>
|
|
14
|
+
{% endfor %}
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{% if groups %}
|
|
2
|
+
<div class="accordion accordion-flush" id="sidebarExtraAccordion">
|
|
3
|
+
{% for group_name, group in groups.items %}
|
|
4
|
+
<div class="accordion-item">
|
|
5
|
+
<h2 class="accordion-header">
|
|
6
|
+
<button class="accordion-button{% if not group.has_active %} collapsed{% endif %}"
|
|
7
|
+
type="button"
|
|
8
|
+
data-bs-toggle="collapse"
|
|
9
|
+
data-bs-target="#extraGroup{{ forloop.counter }}"
|
|
10
|
+
aria-expanded="{% if group.has_active %}true{% else %}false{% endif %}"
|
|
11
|
+
aria-controls="extraGroup{{ forloop.counter }}">
|
|
12
|
+
<i class="bi {{ group.icon }} me-2" style="font-size: 24px;"></i>
|
|
13
|
+
<span>{{ group_name }}</span>
|
|
14
|
+
</button>
|
|
15
|
+
</h2>
|
|
16
|
+
<div id="extraGroup{{ forloop.counter }}"
|
|
17
|
+
class="accordion-collapse collapse{% if group.has_active %} show{% endif %}"
|
|
18
|
+
data-bs-parent="#sidebarExtraAccordion">
|
|
19
|
+
<div class="accordion-body p-0" data-group-name="{{ group_name|slugify }}">
|
|
20
|
+
{% for item in group.items %}
|
|
21
|
+
<a href="{{ item.url }}"
|
|
22
|
+
class="list-group-item list-group-item-action{% if item.active %} active{% endif %}"
|
|
23
|
+
data-url-name="{{ item.url_name }}">
|
|
24
|
+
<i class="bi {{ item.icon }} me-2" style="font-size: 24px;"></i>
|
|
25
|
+
<span>{{ item.label }}</span>
|
|
26
|
+
</a>
|
|
27
|
+
{% endfor %}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
{% endfor %}
|
|
32
|
+
</div>
|
|
33
|
+
{% endif %}
|
|
34
|
+
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{% load static %}
|
|
2
2
|
<link rel="stylesheet" href="{% static 'sidebar/sidebar.css' %}">
|
|
3
|
+
<link rel="stylesheet" href="{% static 'sidebar/css/theme_picker.css' %}">
|
|
4
|
+
<link rel="stylesheet" href="{% static 'sidebar/css/reorder.css' %}">
|
|
5
|
+
<link rel="stylesheet" href="{% static 'themes/main.css' %}">
|
|
3
6
|
<script src="{% static 'sidebar/sidebar.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
7
|
+
<script src="{% static 'themes/main.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
8
|
+
<script src="{% static 'sidebar/js/theme_picker.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
9
|
+
<script src="{% static 'sidebar/js/reorder.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
|
|
4
10
|
<!-- Ghost Sidebar for small screens layout stability -->
|
|
5
|
-
|
|
11
|
+
{% if request.user.is_authenticated %}
|
|
12
|
+
<!-- <div class="sidebar-ghost"></div> -->
|
|
6
13
|
|
|
7
14
|
<!-- sidebar.html -->
|
|
8
15
|
<div class="col-2 flex-column shadow-sm sidebar {% if request.session.sidebarCollapsed %}collapsed{% endif %} no-print"
|
|
@@ -26,7 +33,7 @@
|
|
|
26
33
|
{% block items %}
|
|
27
34
|
|
|
28
35
|
<!-- DEFAULT CONTENT / INSTRUCTIONS -->
|
|
29
|
-
<div class="p-3 text-center text-muted">
|
|
36
|
+
<!-- <div class="p-3 text-center text-muted">
|
|
30
37
|
<i class="bi bi-info-circle mb-2" style="font-size: 24px;"></i>
|
|
31
38
|
<p class="small">
|
|
32
39
|
<strong>Default Sidebar</strong><br>
|
|
@@ -34,13 +41,95 @@
|
|
|
34
41
|
<code>sidebar/main.html</code><br>
|
|
35
42
|
and override the <code>items</code> block.
|
|
36
43
|
</p>
|
|
37
|
-
</div>
|
|
44
|
+
</div> -->
|
|
38
45
|
|
|
39
|
-
<a href="#" class="list-group-item list-group-item-action">
|
|
46
|
+
<!-- <a href="#" class="list-group-item list-group-item-action">
|
|
40
47
|
<i class="bi bi-house me-2" style="font-size: 24px;"></i>
|
|
41
48
|
<span>Example Home</span>
|
|
42
|
-
</a>
|
|
49
|
+
</a> -->
|
|
43
50
|
|
|
44
51
|
{% endblock %}
|
|
45
52
|
</div>
|
|
53
|
+
<script nonce="{{ request.csp_nonce }}">
|
|
54
|
+
// Immediate order restore to prevent FOUC - runs before browser paint
|
|
55
|
+
(function() {
|
|
56
|
+
var STORAGE_KEY_AUTO = 'sidebar_auto_order';
|
|
57
|
+
var STORAGE_KEY_PREFIX_EXTRA = 'sidebar_extra_';
|
|
58
|
+
|
|
59
|
+
function restoreContainer(container, storageKey) {
|
|
60
|
+
var saved;
|
|
61
|
+
try {
|
|
62
|
+
saved = localStorage.getItem(storageKey);
|
|
63
|
+
if (!saved) return;
|
|
64
|
+
saved = JSON.parse(saved);
|
|
65
|
+
} catch(e) { return; }
|
|
66
|
+
if (!Array.isArray(saved) || saved.length === 0) return;
|
|
67
|
+
|
|
68
|
+
var items = container.querySelectorAll(':scope > .list-group-item[data-url-name]');
|
|
69
|
+
var itemMap = {};
|
|
70
|
+
for (var i = 0; i < items.length; i++) {
|
|
71
|
+
itemMap[items[i].dataset.urlName] = items[i];
|
|
72
|
+
}
|
|
73
|
+
for (var j = 0; j < saved.length; j++) {
|
|
74
|
+
var item = itemMap[saved[j]];
|
|
75
|
+
if (item) {
|
|
76
|
+
container.appendChild(item);
|
|
77
|
+
delete itemMap[saved[j]];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
for (var key in itemMap) {
|
|
81
|
+
container.appendChild(itemMap[key]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function slugify(text) {
|
|
86
|
+
return text.toString().toLowerCase().trim()
|
|
87
|
+
.replace(/\s+/g, '-').replace(/[^\w\-]+/g, '').replace(/\-\-+/g, '-');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Restore auto items
|
|
91
|
+
var autoContainer = document.getElementById('sidebarAutoItems');
|
|
92
|
+
if (autoContainer) {
|
|
93
|
+
restoreContainer(autoContainer, STORAGE_KEY_AUTO);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Restore extra groups
|
|
97
|
+
var accordionBodies = document.querySelectorAll('.sidebar .accordion-body');
|
|
98
|
+
for (var k = 0; k < accordionBodies.length; k++) {
|
|
99
|
+
var body = accordionBodies[k];
|
|
100
|
+
var groupName = body.dataset.groupName;
|
|
101
|
+
if (!groupName) {
|
|
102
|
+
var btn = body.closest('.accordion-item');
|
|
103
|
+
if (btn) {
|
|
104
|
+
var span = btn.querySelector('.accordion-button span');
|
|
105
|
+
if (span) groupName = span.textContent.trim();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (groupName) {
|
|
109
|
+
restoreContainer(body, STORAGE_KEY_PREFIX_EXTRA + slugify(groupName));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
window._sidebarOrderRestored = true;
|
|
114
|
+
})();
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<!-- Sidebar Toolbar (Theme Picker, Reorder, etc.) -->
|
|
118
|
+
<div class="sidebar-toolbar no-print">
|
|
119
|
+
<i class="bi bi-arrows-move reorder-toggle" id="sidebarReorderToggle" title="إعادة الترتيب"></i>
|
|
120
|
+
<i class="bi bi-chevron-up theme-arrow" id="sidebarThemeArrow"></i>
|
|
121
|
+
<div class="current-theme-indicator" id="sidebarThemeIndicator" title="تغيير المظهر"></div>
|
|
122
|
+
<div class="theme-popup" id="sidebarThemePopup">
|
|
123
|
+
<div class="small fw-bold mb-2 text-center border-bottom pb-1">اختر اللون</div>
|
|
124
|
+
<div class="theme-options-grid">
|
|
125
|
+
<div class="theme-option-circle theme-circle-light" data-theme="light" title="أبيض"></div>
|
|
126
|
+
<div class="theme-option-circle theme-circle-blue" data-theme="blue" title="ملكي"></div>
|
|
127
|
+
<div class="theme-option-circle theme-circle-gold" data-theme="gold" title="ذهبي"></div>
|
|
128
|
+
<div class="theme-option-circle theme-circle-green" data-theme="green" title="أخضر"></div>
|
|
129
|
+
<div class="theme-option-circle theme-circle-red" data-theme="red" title="أحمر"></div>
|
|
130
|
+
<div class="theme-option-circle theme-circle-dark" data-theme="dark" title="ليلي"></div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
46
134
|
</div>
|
|
135
|
+
{% endif %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# This file makes templatetags a Python package
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Template tags for the sidebar app.
|
|
3
|
+
|
|
4
|
+
Provides the {% auto_sidebar %} tag for rendering auto-discovered
|
|
5
|
+
navigation items.
|
|
6
|
+
"""
|
|
7
|
+
from django import template
|
|
8
|
+
from django.urls import reverse, NoReverseMatch
|
|
9
|
+
|
|
10
|
+
register = template.Library()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@register.inclusion_tag('sidebar/auto.html', takes_context=True)
|
|
14
|
+
def auto_sidebar(context):
|
|
15
|
+
"""
|
|
16
|
+
Render auto-discovered sidebar items.
|
|
17
|
+
|
|
18
|
+
Uses items from sidebar_auto_items context variable (provided by
|
|
19
|
+
the context processor) and adds resolved URLs and active state.
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
{% load sidebar_tags %}
|
|
23
|
+
{% auto_sidebar %}
|
|
24
|
+
"""
|
|
25
|
+
request = context.get('request')
|
|
26
|
+
items = list(context.get('sidebar_auto_items', []))
|
|
27
|
+
|
|
28
|
+
# Add resolved URLs and active state
|
|
29
|
+
for item in items:
|
|
30
|
+
try:
|
|
31
|
+
item['url'] = reverse(item['url_name'])
|
|
32
|
+
# Check if current path matches or starts with this URL
|
|
33
|
+
item['active'] = request.path == item['url'] or request.path.startswith(item['url'].rstrip('/') + '/')
|
|
34
|
+
except NoReverseMatch:
|
|
35
|
+
item['url'] = '#'
|
|
36
|
+
item['active'] = False
|
|
37
|
+
|
|
38
|
+
return {'items': items, 'request': request}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@register.simple_tag(takes_context=True)
|
|
42
|
+
def sidebar_item_class(context, url_name):
|
|
43
|
+
"""
|
|
44
|
+
Return 'active' class if current path matches the given URL name.
|
|
45
|
+
|
|
46
|
+
Usage:
|
|
47
|
+
<a href="{% url 'decree_list' %}" class="list-group-item {% sidebar_item_class 'decree_list' %}">
|
|
48
|
+
"""
|
|
49
|
+
request = context.get('request')
|
|
50
|
+
try:
|
|
51
|
+
url = reverse(url_name)
|
|
52
|
+
if request.path == url or request.path.startswith(url.rstrip('/') + '/'):
|
|
53
|
+
return 'active'
|
|
54
|
+
except NoReverseMatch:
|
|
55
|
+
pass
|
|
56
|
+
return ''
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@register.inclusion_tag('sidebar/extra_groups.html', takes_context=True)
|
|
60
|
+
def extra_sidebar(context):
|
|
61
|
+
"""
|
|
62
|
+
Render extra sidebar items grouped in accordions.
|
|
63
|
+
|
|
64
|
+
Uses sidebar_extra_groups from context (provided by context processor).
|
|
65
|
+
Groups are rendered as Bootstrap accordions at the end of the sidebar.
|
|
66
|
+
|
|
67
|
+
Usage:
|
|
68
|
+
{% load sidebar_tags %}
|
|
69
|
+
{% extra_sidebar %}
|
|
70
|
+
"""
|
|
71
|
+
groups = context.get('sidebar_extra_groups', {})
|
|
72
|
+
request = context.get('request')
|
|
73
|
+
return {'groups': groups, 'request': request}
|
|
74
|
+
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
sidebar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
sidebar/apps.py,sha256=4UjKXHoBGKRLxpC9AY6eaq8YZx8unirUz_8u-IrlfVQ,145
|
|
3
|
-
sidebar/urls.py,sha256=UL_9e1RLNMxZXkah65m7GRU1dbViZRGeNPBIiSZpOYg,142
|
|
4
|
-
sidebar/views.py,sha256=MebyJ1ZiylSOPESXFkkQ8QTg-ClrkJn-oYLN6KrcgiM,418
|
|
5
|
-
sidebar/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
sidebar/static/sidebar/sidebar.css,sha256=f6xLSC3JiZFABkxWlFesuzAZZtAT3WW1nZBFMDQNS6Y,5283
|
|
7
|
-
sidebar/static/sidebar/sidebar.js,sha256=xDp038tlscz5KeTjBiEQTzZ2T7a8k4NY3rC6e9NvMsM,6314
|
|
8
|
-
sidebar/templates/sidebar/main.html,sha256=zp_ENJberDGhPERxnzDMwLsjwr5_uTAKd3UpDFNUW-k,1944
|
|
9
|
-
micro_sidebar-1.2.2.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
|
|
10
|
-
micro_sidebar-1.2.2.dist-info/METADATA,sha256=35UC3_f-k_PQ1mh1c3FIyUn5-ORTgJQKU72tJqKc320,4431
|
|
11
|
-
micro_sidebar-1.2.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
12
|
-
micro_sidebar-1.2.2.dist-info/top_level.txt,sha256=ih69sjMhU1wOB9HzUV90yEY98aiPuGhzPBBBE-YtJ3w,8
|
|
13
|
-
micro_sidebar-1.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|