micro-users 1.4.1__py3-none-any.whl → 1.6.1__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.

Potentially problematic release.


This version of micro-users might be problematic. Click here for more details.

Files changed (31) hide show
  1. {micro_users-1.4.1.dist-info → micro_users-1.6.1.dist-info}/METADATA +57 -133
  2. micro_users-1.6.1.dist-info/RECORD +38 -0
  3. users/admin.py +21 -2
  4. users/apps.py +2 -1
  5. users/filters.py +6 -6
  6. users/forms.py +37 -14
  7. users/middleware.py +32 -0
  8. users/migrations/0003_scope_alter_customuser_options_and_more.py +47 -0
  9. users/models.py +20 -1
  10. users/signals.py +107 -9
  11. users/static/img/login_logo.webp +0 -0
  12. users/static/{css → users/css}/login.css +50 -43
  13. users/static/users/css/style.css +201 -0
  14. users/static/users/js/anime.min.js +8 -0
  15. users/static/users/js/login.js +60 -0
  16. users/tables.py +29 -7
  17. users/templates/registration/login.html +29 -69
  18. users/templates/users/manage_users.html +88 -0
  19. users/templates/users/partials/scope_actions.html +9 -0
  20. users/templates/users/partials/scope_form.html +19 -0
  21. users/templates/users/partials/scope_manager.html +12 -0
  22. users/templates/{user_activity_log.html → users/user_activity_log.html} +2 -0
  23. users/urls.py +9 -1
  24. users/views.py +165 -24
  25. micro_users-1.4.1.dist-info/RECORD +0 -29
  26. {micro_users-1.4.1.dist-info → micro_users-1.6.1.dist-info}/LICENSE +0 -0
  27. {micro_users-1.4.1.dist-info → micro_users-1.6.1.dist-info}/WHEEL +0 -0
  28. {micro_users-1.4.1.dist-info → micro_users-1.6.1.dist-info}/top_level.txt +0 -0
  29. /users/templates/users/{user_actions.html → partials/user_actions.html} +0 -0
  30. /users/templates/users/{profile.html → profile/profile.html} +0 -0
  31. /users/templates/users/{profile_edit.html → profile/profile_edit.html} +0 -0
users/signals.py CHANGED
@@ -1,13 +1,27 @@
1
1
  # Imports of the required python modules and libraries
2
2
  ######################################################
3
3
  from django.dispatch import receiver
4
+ from django.db.models.signals import post_save, post_delete, pre_save
4
5
  from django.utils.timezone import now
5
- from .models import UserActivityLog
6
+ from django.apps import apps
6
7
  from django.contrib.auth.signals import user_logged_in, user_logged_out
8
+ from .middleware import get_current_user, get_current_request
9
+
10
+ def get_client_ip(request):
11
+ """Extract client IP address from request."""
12
+ if not request:
13
+ return None
14
+ x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
15
+ if x_forwarded_for:
16
+ ip = x_forwarded_for.split(",")[0]
17
+ else:
18
+ ip = request.META.get("REMOTE_ADDR")
19
+ return ip
7
20
 
8
21
  @receiver(user_logged_in)
9
22
  def log_login(sender, request, user, **kwargs):
10
23
  """Log user login actions."""
24
+ UserActivityLog = apps.get_model('users', 'UserActivityLog')
11
25
  UserActivityLog.objects.create(
12
26
  user=user,
13
27
  action="LOGIN",
@@ -21,6 +35,7 @@ def log_login(sender, request, user, **kwargs):
21
35
  @receiver(user_logged_out)
22
36
  def log_logout(sender, request, user, **kwargs):
23
37
  """Log user logout actions."""
38
+ UserActivityLog = apps.get_model('users', 'UserActivityLog')
24
39
  UserActivityLog.objects.create(
25
40
  user=user,
26
41
  action="LOGOUT",
@@ -31,11 +46,94 @@ def log_logout(sender, request, user, **kwargs):
31
46
  timestamp=now(),
32
47
  )
33
48
 
34
- def get_client_ip(request):
35
- """Extract client IP address from request."""
36
- x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
37
- if x_forwarded_for:
38
- ip = x_forwarded_for.split(",")[0]
39
- else:
40
- ip = request.META.get("REMOTE_ADDR")
41
- return ip
49
+ @receiver(pre_save)
50
+ def capture_soft_delete_state(sender, instance, **kwargs):
51
+ """Capture state to detect soft delete in post_save."""
52
+ if instance.pk and hasattr(instance, 'deleted_at'):
53
+ try:
54
+ old_instance = sender.objects.get(pk=instance.pk)
55
+ instance._was_not_deleted = (old_instance.deleted_at is None)
56
+ except sender.DoesNotExist:
57
+ pass
58
+
59
+ @receiver(post_save)
60
+ def log_save(sender, instance, created, **kwargs):
61
+ """Log create and update actions for all models."""
62
+ # Prevent infinite recursion by skipping the log model itself
63
+ UserActivityLog = apps.get_model('users', 'UserActivityLog')
64
+ if sender == UserActivityLog:
65
+ return
66
+
67
+ # Get the current user from thread locals
68
+ user = get_current_user()
69
+ if not user or not user.is_authenticated:
70
+ return
71
+
72
+ # Ignore implicit updates to last_login (handled by user_logged_in signal)
73
+ update_fields = kwargs.get('update_fields')
74
+ if update_fields and 'last_login' in update_fields and len(update_fields) == 1:
75
+ return
76
+
77
+ action = "CREATE" if created else "UPDATE"
78
+
79
+ # Check for soft delete transition
80
+ if not created and getattr(instance, '_was_not_deleted', False) and getattr(instance, 'deleted_at', None):
81
+ action = "DELETE"
82
+
83
+ model_name = instance._meta.verbose_name
84
+
85
+ # Use string representation of the object for 'number' or reference
86
+ try:
87
+ obj_str = str(instance)
88
+ except TypeError:
89
+ # Fallback if __str__ returns non-string (e.g. int)
90
+ obj_str = str(instance.pk)
91
+
92
+ request = get_current_request()
93
+ ip = get_client_ip(request)
94
+ user_agent = request.META.get("HTTP_USER_AGENT", "") if request else ""
95
+
96
+ UserActivityLog.objects.create(
97
+ user=user,
98
+ action=action,
99
+ model_name=model_name,
100
+ object_id=instance.pk,
101
+ number=obj_str[:50] if obj_str else None,
102
+ ip_address=ip,
103
+ user_agent=user_agent,
104
+ timestamp=now()
105
+ )
106
+
107
+ @receiver(post_delete)
108
+ def log_delete(sender, instance, **kwargs):
109
+ """Log delete actions for all models."""
110
+ UserActivityLog = apps.get_model('users', 'UserActivityLog')
111
+ if sender == UserActivityLog:
112
+ return
113
+
114
+ user = get_current_user()
115
+ if not user or not user.is_authenticated:
116
+ return
117
+
118
+ action = "DELETE"
119
+ model_name = instance._meta.verbose_name
120
+
121
+ try:
122
+ obj_str = str(instance)
123
+ except TypeError:
124
+ obj_str = str(instance.pk)
125
+
126
+ request = get_current_request()
127
+ ip = get_client_ip(request)
128
+ user_agent = request.META.get("HTTP_USER_AGENT", "") if request else ""
129
+
130
+ UserActivityLog.objects.create(
131
+ user=user,
132
+ action=action,
133
+ model_name=model_name,
134
+ object_id=instance.pk,
135
+ number=obj_str[:50] if obj_str else None,
136
+ ip_address=ip,
137
+ user_agent=user_agent,
138
+ timestamp=now()
139
+ )
Binary file
@@ -1,13 +1,24 @@
1
- ::selection {
2
- background: #d4c591;
3
- }
4
- ::-webkit-selection {
5
- background: #d4c591;
6
- }
7
- ::-moz-selection {
8
- background: #c9aa5e;
1
+ :root {
2
+ --selection-bg: #dbdbdb;
3
+ --selection-moz-bg: #dbdbdb;
4
+ --left-bg: white;
5
+ --left-shadow: rgba(0,0,0,0.03);
6
+ --right-bg: #474745;
7
+ --right-shadow: rgba(0,0,0,0.07);
8
+ --right-text: #F1F1F2;
9
+ --label-color: #c2c2c5;
10
+ --input-text: #000000;
11
+ --submit-color: #707075;
12
+ --submit-focus: #575757;
13
+ --submit-active: #4d4d4d;
14
+ --gradient-start: #474745;
15
+ --gradient-end: #a2a2a7;
9
16
  }
10
17
 
18
+ ::selection { background: var(--selection-bg); }
19
+ ::-webkit-selection { background: var(--selection-bg); }
20
+ ::-moz-selection { background: var(--selection-moz-bg); }
21
+
11
22
  .page {
12
23
  display: flex;
13
24
  flex-direction: column;
@@ -16,6 +27,7 @@
16
27
  place-content: center;
17
28
  width: calc(100% - 40px);
18
29
  }
30
+
19
31
  @media (max-width: 767px) {
20
32
  .page {
21
33
  height: auto;
@@ -23,11 +35,13 @@
23
35
  padding-bottom: 20px;
24
36
  }
25
37
  }
38
+
26
39
  .container {
27
40
  height: 320px;
28
41
  margin: 0 auto;
29
42
  width: 640px;
30
43
  }
44
+
31
45
  @media (max-width: 767px) {
32
46
  .container {
33
47
  flex-direction: column;
@@ -35,15 +49,16 @@
35
49
  width: 320px;
36
50
  }
37
51
  }
52
+
38
53
  .left {
39
- background: white;
54
+ background: var(--left-bg);
40
55
  height: calc(100% - 40px);
41
56
  top: 20px;
42
57
  position: relative;
43
58
  width: 60%;
44
- box-shadow: 0px 0px 10px 4px rgba(0,0,0,0.03);
45
-
59
+ box-shadow: 0px 0px 10px 4px var(--left-shadow);
46
60
  }
61
+
47
62
  @media (max-width: 767px) {
48
63
  .left {
49
64
  height: 100%;
@@ -52,23 +67,15 @@
52
67
  max-height: 270px;
53
68
  }
54
69
  }
55
- /* .login {
56
- font-size: 38px;
57
- font-weight: 600;
58
- }
59
- .eula {
60
- color: #adadad;
61
- font-size: 14px;
62
- line-height: 1.5;
63
- margin: 40px;
64
- } */
70
+
65
71
  .right {
66
- background: #cb9447;
67
- box-shadow: 0px 0px 20px 8px rgba(0,0,0,0.07);
68
- color: #F1F1F2;
72
+ background: var(--right-bg);
73
+ box-shadow: 0px 0px 20px 8px var(--right-shadow);
74
+ color: var(--right-text);
69
75
  position: relative;
70
76
  width: 58%;
71
77
  }
78
+
72
79
  @media (max-width: 767px) {
73
80
  .right {
74
81
  flex-shrink: 0;
@@ -77,32 +84,37 @@
77
84
  max-height: 350px;
78
85
  }
79
86
  }
87
+
80
88
  svg {
81
89
  position: absolute;
82
90
  width: 320px;
83
91
  }
92
+
84
93
  path {
85
94
  fill: none;
86
- stroke: url(#linearGradient);;
95
+ stroke: url(#linearGradient);
87
96
  stroke-width: 3;
88
97
  stroke-dasharray: 240 1386;
89
98
  }
99
+
90
100
  .form {
91
101
  margin: 35px 35px 35px 20px;
92
102
  position: absolute;
93
103
  }
104
+
94
105
  label {
95
- color: #c2c2c5;
106
+ color: var(--label-color);
96
107
  display: block;
97
108
  font-size: 14px;
98
109
  height: 16px;
99
110
  margin-top: 20px;
100
111
  margin-bottom: 5px;
101
112
  }
113
+
102
114
  input {
103
115
  background: transparent;
104
116
  border: 0;
105
- color: #2d0202;
117
+ color: var(--input-text);
106
118
  font-size: 20px;
107
119
  height: 30px;
108
120
  line-height: 30px;
@@ -111,24 +123,19 @@ input {
111
123
  margin-top: 30px;
112
124
  margin-bottom: 10px;
113
125
  }
114
- input::-moz-focus-inner {
115
- border: 0;
116
- }
126
+
127
+ input::-moz-focus-inner { border: 0; }
128
+
117
129
  #submit {
118
- color: #707075;
130
+ color: var(--submit-color);
119
131
  margin-top: 40px;
120
132
  transition: color 300ms;
121
133
  }
122
- #submit:focus {
123
- color: #575757;
124
- }
125
- #submit:active {
126
- color: #4d4d4d;
127
- }
128
134
 
129
- .titlebar {
130
- background-color: var(--title);
131
- flex-direction: row;
132
- height: 7vh;
133
- justify-content: center !important
134
- }
135
+ #submit:focus { color: var(--submit-focus); }
136
+ #submit:active { color: var(--submit-active); }
137
+
138
+ /* New Utility Classes for specific elements */
139
+ .login-input { font-size: 28px !important; }
140
+ .login-submit { font-size: 25px !important; }
141
+ .logo-img { width: 100%; }
@@ -0,0 +1,201 @@
1
+ /* Custom styles for Micro Users App */
2
+
3
+ /* Buttons and Colors Usage */
4
+ .btn-primary {
5
+ background-color: var(--primal) !important;
6
+ border-color: var(--primal) !important;
7
+ }
8
+
9
+ .btn-primary:hover {
10
+ background-color: var(--primal_dark) !important;
11
+ border-color: var(--primal_dark) !important;
12
+ }
13
+
14
+ .btn-outline-primary {
15
+ border-color: var(--primal_dark) !important;
16
+ color: var(--primal_dark) !important;
17
+ }
18
+
19
+ .btn-outline-primary:hover {
20
+ background-color: var(--primal_dark) !important;
21
+ color: white !important;
22
+ }
23
+
24
+ .text-bg-primary {
25
+ background-color: var(--primal) !important;
26
+ border-color: var(--primal) !important;
27
+ }
28
+
29
+ .list-group-item.active{
30
+ background-color: var(--htitle) !important;
31
+ border-color: var(--title) !important;
32
+ }
33
+
34
+ .granour { color: var(--granour) !important; }
35
+ .primal { color: var(--primal) !important; }
36
+ .primal:hover { color: var(--primal_dark) !important; }
37
+
38
+ /* Pagination */
39
+ .pagination {
40
+ --bs-pagination-active-bg: var(--primal) !important;
41
+ --bs-pagination-active-border-color: var(--primal) !important;
42
+ --bs-pagination-color: var(--primal) !important;
43
+ }
44
+
45
+ .pagination .next .page-link::before {
46
+ content: ">>";
47
+ font-size: 16px;
48
+ }
49
+ .pagination .previous .page-link::before {
50
+ content: "<<";
51
+ font-size: 16px;
52
+ }
53
+ .pagination .next .page-link,
54
+ .pagination .previous .page-link {
55
+ font-size: 0;
56
+ }
57
+ .pagination .next .page-link span,
58
+ .pagination .previous .page-link span {
59
+ font-size: 16px;
60
+ }
61
+
62
+ /* Inputs */
63
+ input[dir="rtl"], input[type="number"], input[type="email"] {
64
+ text-align: right;
65
+ direction: rtl;
66
+ unicode-bidi: plaintext;
67
+ }
68
+
69
+ input[dir="rtl"]::placeholder {
70
+ text-align: right;
71
+ color: #484848;
72
+ }
73
+
74
+ form label {
75
+ font-weight: 600;
76
+ font-size: 1.2rem;
77
+ }
78
+
79
+ /* Cards */
80
+ .card { --bs-card-border-radius: 0px !important; }
81
+ .icard { transition: all 0.3s ease-in-out; }
82
+ .icard:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.1) !important; }
83
+
84
+ /* Tables */
85
+ .table>tbody>tr:nth-child(odd)>td,
86
+ .table>tbody>tr:nth-child(odd)>th {
87
+ --bs-table-bg-type: white;
88
+ }
89
+
90
+ .table>tbody>tr:nth-child(even)>td,
91
+ .table>tbody>tr:nth-child(even)>th {
92
+ --bs-table-bg-type: whitesmoke;
93
+ }
94
+
95
+ .table thead th {
96
+ background-color: whitesmoke;
97
+ font-size: 20px;
98
+ transition: font-size 0.3s;
99
+ }
100
+
101
+ .table tbody tr td {
102
+ border-style: none;
103
+ font-size: 20px;
104
+ transition: font-size 0.3s;
105
+ }
106
+
107
+ @media (max-width: 900px) {
108
+ .table thead th, .table tbody tr td {
109
+ font-size: 14px !important;
110
+ }
111
+ }
112
+
113
+ th a {
114
+ text-decoration: none;
115
+ color: inherit;
116
+ }
117
+ th a::after {
118
+ font-family: "bootstrap-icons";
119
+ content: "\F238";
120
+ font-size: 14px;
121
+ margin-right: 3px;
122
+ }
123
+ th.asc a::after { content: "\F235"; }
124
+ th.desc a::after { content: "\F229"; }
125
+
126
+ /* Table Danger Fixes */
127
+ .table > tbody > tr.table-danger > td,
128
+ .table > tbody > tr.table-danger > th {
129
+ --bs-table-bg-type: #f8d7da !important;
130
+ }
131
+ .table-hover > tbody > tr.table-danger:hover > td,
132
+ .table-hover > tbody > tr.table-danger:hover > th {
133
+ --bs-table-bg-type: #f1b0b7 !important;
134
+ }
135
+
136
+ /* Utils */
137
+ .dropdown-menu.show{
138
+ --bs-dropdown-min-width: 94px;
139
+ overflow-x:visible;
140
+ }
141
+
142
+ .tooltip-custom .tooltip-inner {
143
+ font-size: 1.2rem;
144
+ background-color: var(--title);
145
+ color: white;
146
+ padding: 8px 12px;
147
+ border-radius: 5px;
148
+ }
149
+
150
+ .button-group{ padding: 10px; }
151
+ .checkbox-inline { display:inline-flex; margin-left: 5px; margin-right: 10px; }
152
+ #id_year { direction: rtl; }
153
+ .option-separator { border-bottom: 1px solid #ddd; padding-bottom: 5px; }
154
+ .option-separator:last-of-type { border-bottom: none; }
155
+ .alert { opacity: 1; transition: opacity 0.5s ease-in-out; }
156
+
157
+ @media print {
158
+ .no-print { display: none !important; }
159
+ .new-page { page-break-inside: avoid; }
160
+ *, .shadow {
161
+ box-shadow: none !important;
162
+ text-shadow: none !important;
163
+ border-color: rgba(0, 0, 0, var(--bs-border-opacity)) !important;
164
+ }
165
+ }
166
+
167
+ /* Main Content Utils */
168
+ .disabler { pointer-events: none !important; cursor: not-allowed !important; }
169
+ .base-link { color: var(--title) !important; }
170
+ .is-placeholder { background-color: rgba(255, 0, 0, 0.1); font-weight: bold; }
171
+ .card_text_big { font-size: 24px; }
172
+ .bi-font { font-size: 16px; }
173
+
174
+
175
+ /* Strikethrough for deleted rows */
176
+ tr.row-deleted {
177
+ color: #aeaeae !important;
178
+ }
179
+
180
+ /* Override bootstrap table striping for deleted rows */
181
+ .table > tbody > tr.row-deleted > td,
182
+ .table > tbody > tr.row-deleted > th {
183
+ --bs-table-bg-type: rgba(0, 0, 0, 0.02) !important;
184
+ color: #aeaeae !important;
185
+ }
186
+
187
+ tr.row-deleted td {
188
+ position: relative;
189
+ }
190
+
191
+ tr.row-deleted td::after {
192
+ content: '';
193
+ position: absolute;
194
+ top: 50%;
195
+ left: 0;
196
+ width: 100%;
197
+ height: 1px;
198
+ background: #aeaeae;
199
+ z-index: 1;
200
+ pointer-events: none;
201
+ }
@@ -0,0 +1,8 @@
1
+ /*
2
+ * anime.js v3.0.1
3
+ * (c) 2019 Julian Garnier
4
+ * Released under the MIT license
5
+ * animejs.com
6
+ */
7
+
8
+ !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):n.anime=e()}(this,function(){"use strict";var n={update:null,begin:null,loopBegin:null,changeBegin:null,change:null,changeComplete:null,loopComplete:null,complete:null,loop:1,direction:"normal",autoplay:!0,timelineOffset:0},e={duration:1e3,delay:0,endDelay:0,easing:"easeOutElastic(1, .5)",round:0},r=["translateX","translateY","translateZ","rotate","rotateX","rotateY","rotateZ","scale","scaleX","scaleY","scaleZ","skew","skewX","skewY","perspective"],t={CSS:{},springs:{}};function a(n,e,r){return Math.min(Math.max(n,e),r)}function o(n,e){return n.indexOf(e)>-1}function i(n,e){return n.apply(null,e)}var u={arr:function(n){return Array.isArray(n)},obj:function(n){return o(Object.prototype.toString.call(n),"Object")},pth:function(n){return u.obj(n)&&n.hasOwnProperty("totalLength")},svg:function(n){return n instanceof SVGElement},inp:function(n){return n instanceof HTMLInputElement},dom:function(n){return n.nodeType||u.svg(n)},str:function(n){return"string"==typeof n},fnc:function(n){return"function"==typeof n},und:function(n){return void 0===n},hex:function(n){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(n)},rgb:function(n){return/^rgb/.test(n)},hsl:function(n){return/^hsl/.test(n)},col:function(n){return u.hex(n)||u.rgb(n)||u.hsl(n)},key:function(r){return!n.hasOwnProperty(r)&&!e.hasOwnProperty(r)&&"targets"!==r&&"keyframes"!==r}};function s(n){var e=/\(([^)]+)\)/.exec(n);return e?e[1].split(",").map(function(n){return parseFloat(n)}):[]}function c(n,e){var r=s(n),o=a(u.und(r[0])?1:r[0],.1,100),i=a(u.und(r[1])?100:r[1],.1,100),c=a(u.und(r[2])?10:r[2],.1,100),f=a(u.und(r[3])?0:r[3],.1,100),l=Math.sqrt(i/o),d=c/(2*Math.sqrt(i*o)),p=d<1?l*Math.sqrt(1-d*d):0,v=1,h=d<1?(d*l-f)/p:-f+l;function g(n){var r=e?e*n/1e3:n;return r=d<1?Math.exp(-r*d*l)*(v*Math.cos(p*r)+h*Math.sin(p*r)):(v+h*r)*Math.exp(-r*l),0===n||1===n?n:1-r}return e?g:function(){var e=t.springs[n];if(e)return e;for(var r=0,a=0;;)if(1===g(r+=1/6)){if(++a>=16)break}else a=0;var o=r*(1/6)*1e3;return t.springs[n]=o,o}}function f(n,e){void 0===n&&(n=1),void 0===e&&(e=.5);var r=a(n,1,10),t=a(e,.1,2);return function(n){return 0===n||1===n?n:-r*Math.pow(2,10*(n-1))*Math.sin((n-1-t/(2*Math.PI)*Math.asin(1/r))*(2*Math.PI)/t)}}function l(n){return void 0===n&&(n=10),function(e){return Math.round(e*n)*(1/n)}}var d=function(){var n=11,e=1/(n-1);function r(n,e){return 1-3*e+3*n}function t(n,e){return 3*e-6*n}function a(n){return 3*n}function o(n,e,o){return((r(e,o)*n+t(e,o))*n+a(e))*n}function i(n,e,o){return 3*r(e,o)*n*n+2*t(e,o)*n+a(e)}return function(r,t,a,u){if(0<=r&&r<=1&&0<=a&&a<=1){var s=new Float32Array(n);if(r!==t||a!==u)for(var c=0;c<n;++c)s[c]=o(c*e,r,a);return function(n){return r===t&&a===u?n:0===n||1===n?n:o(f(n),t,u)}}function f(t){for(var u=0,c=1,f=n-1;c!==f&&s[c]<=t;++c)u+=e;var l=u+(t-s[--c])/(s[c+1]-s[c])*e,d=i(l,r,a);return d>=.001?function(n,e,r,t){for(var a=0;a<4;++a){var u=i(e,r,t);if(0===u)return e;e-=(o(e,r,t)-n)/u}return e}(t,l,r,a):0===d?l:function(n,e,r,t,a){for(var i,u,s=0;(i=o(u=e+(r-e)/2,t,a)-n)>0?r=u:e=u,Math.abs(i)>1e-7&&++s<10;);return u}(t,u,u+e,r,a)}}}(),p=function(){var n=["Quad","Cubic","Quart","Quint","Sine","Expo","Circ","Back","Elastic"],e={In:[[.55,.085,.68,.53],[.55,.055,.675,.19],[.895,.03,.685,.22],[.755,.05,.855,.06],[.47,0,.745,.715],[.95,.05,.795,.035],[.6,.04,.98,.335],[.6,-.28,.735,.045],f],Out:[[.25,.46,.45,.94],[.215,.61,.355,1],[.165,.84,.44,1],[.23,1,.32,1],[.39,.575,.565,1],[.19,1,.22,1],[.075,.82,.165,1],[.175,.885,.32,1.275],function(n,e){return function(r){return 1-f(n,e)(1-r)}}],InOut:[[.455,.03,.515,.955],[.645,.045,.355,1],[.77,0,.175,1],[.86,0,.07,1],[.445,.05,.55,.95],[1,0,0,1],[.785,.135,.15,.86],[.68,-.55,.265,1.55],function(n,e){return function(r){return r<.5?f(n,e)(2*r)/2:1-f(n,e)(-2*r+2)/2}}]},r={linear:[.25,.25,.75,.75]},t=function(t){e[t].forEach(function(e,a){r["ease"+t+n[a]]=e})};for(var a in e)t(a);return r}();function v(n,e){if(u.fnc(n))return n;var r=n.split("(")[0],t=p[r],a=s(n);switch(r){case"spring":return c(n,e);case"cubicBezier":return i(d,a);case"steps":return i(l,a);default:return u.fnc(t)?i(t,a):i(d,t)}}function h(n){try{return document.querySelectorAll(n)}catch(n){return}}function g(n,e){for(var r=n.length,t=arguments.length>=2?arguments[1]:void 0,a=[],o=0;o<r;o++)if(o in n){var i=n[o];e.call(t,i,o,n)&&a.push(i)}return a}function m(n){return n.reduce(function(n,e){return n.concat(u.arr(e)?m(e):e)},[])}function y(n){return u.arr(n)?n:(u.str(n)&&(n=h(n)||n),n instanceof NodeList||n instanceof HTMLCollection?[].slice.call(n):[n])}function b(n,e){return n.some(function(n){return n===e})}function x(n){var e={};for(var r in n)e[r]=n[r];return e}function M(n,e){var r=x(n);for(var t in n)r[t]=e.hasOwnProperty(t)?e[t]:n[t];return r}function w(n,e){var r=x(n);for(var t in e)r[t]=u.und(n[t])?e[t]:n[t];return r}function k(n){return u.rgb(n)?(r=/rgb\((\d+,\s*[\d]+,\s*[\d]+)\)/g.exec(e=n))?"rgba("+r[1]+",1)":e:u.hex(n)?(t=n.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(n,e,r,t){return e+e+r+r+t+t}),a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t),"rgba("+parseInt(a[1],16)+","+parseInt(a[2],16)+","+parseInt(a[3],16)+",1)"):u.hsl(n)?function(n){var e,r,t,a=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(n)||/hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec(n),o=parseInt(a[1],10)/360,i=parseInt(a[2],10)/100,u=parseInt(a[3],10)/100,s=a[4]||1;function c(n,e,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?n+6*(e-n)*r:r<.5?e:r<2/3?n+(e-n)*(2/3-r)*6:n}if(0==i)e=r=t=u;else{var f=u<.5?u*(1+i):u+i-u*i,l=2*u-f;e=c(l,f,o+1/3),r=c(l,f,o),t=c(l,f,o-1/3)}return"rgba("+255*e+","+255*r+","+255*t+","+s+")"}(n):void 0;var e,r,t,a}function C(n){var e=/([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(n);if(e)return e[2]}function O(n,e){return u.fnc(n)?n(e.target,e.id,e.total):n}function P(n,e){return n.getAttribute(e)}function I(n,e,r){if(b([r,"deg","rad","turn"],C(e)))return e;var a=t.CSS[e+r];if(!u.und(a))return a;var o=document.createElement(n.tagName),i=n.parentNode&&n.parentNode!==document?n.parentNode:document.body;i.appendChild(o),o.style.position="absolute",o.style.width=100+r;var s=100/o.offsetWidth;i.removeChild(o);var c=s*parseFloat(e);return t.CSS[e+r]=c,c}function B(n,e,r){if(e in n.style){var t=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),a=n.style[e]||getComputedStyle(n).getPropertyValue(t)||"0";return r?I(n,a,r):a}}function D(n,e){return u.dom(n)&&!u.inp(n)&&(P(n,e)||u.svg(n)&&n[e])?"attribute":u.dom(n)&&b(r,e)?"transform":u.dom(n)&&"transform"!==e&&B(n,e)?"css":null!=n[e]?"object":void 0}function T(n){if(u.dom(n)){for(var e,r=n.style.transform||"",t=/(\w+)\(([^)]*)\)/g,a=new Map;e=t.exec(r);)a.set(e[1],e[2]);return a}}function F(n,e,r,t){var a,i=o(e,"scale")?1:0+(o(a=e,"translate")||"perspective"===a?"px":o(a,"rotate")||o(a,"skew")?"deg":void 0),u=T(n).get(e)||i;return r&&(r.transforms.list.set(e,u),r.transforms.last=e),t?I(n,u,t):u}function N(n,e,r,t){switch(D(n,e)){case"transform":return F(n,e,t,r);case"css":return B(n,e,r);case"attribute":return P(n,e);default:return n[e]||0}}function A(n,e){var r=/^(\*=|\+=|-=)/.exec(n);if(!r)return n;var t=C(n)||0,a=parseFloat(e),o=parseFloat(n.replace(r[0],""));switch(r[0][0]){case"+":return a+o+t;case"-":return a-o+t;case"*":return a*o+t}}function E(n,e){if(u.col(n))return k(n);var r=C(n),t=r?n.substr(0,n.length-r.length):n;return e&&!/\s/g.test(n)?t+e:t}function L(n,e){return Math.sqrt(Math.pow(e.x-n.x,2)+Math.pow(e.y-n.y,2))}function S(n){for(var e,r=n.points,t=0,a=0;a<r.numberOfItems;a++){var o=r.getItem(a);a>0&&(t+=L(e,o)),e=o}return t}function j(n){if(n.getTotalLength)return n.getTotalLength();switch(n.tagName.toLowerCase()){case"circle":return o=n,2*Math.PI*P(o,"r");case"rect":return 2*P(a=n,"width")+2*P(a,"height");case"line":return L({x:P(t=n,"x1"),y:P(t,"y1")},{x:P(t,"x2"),y:P(t,"y2")});case"polyline":return S(n);case"polygon":return r=(e=n).points,S(e)+L(r.getItem(r.numberOfItems-1),r.getItem(0))}var e,r,t,a,o}function q(n,e){var r=e||{},t=r.el||function(n){for(var e=n.parentNode;u.svg(e)&&(e=e.parentNode,u.svg(e.parentNode)););return e}(n),a=t.getBoundingClientRect(),o=P(t,"viewBox"),i=a.width,s=a.height,c=r.viewBox||(o?o.split(" "):[0,0,i,s]);return{el:t,viewBox:c,x:c[0]/1,y:c[1]/1,w:i/c[2],h:s/c[3]}}function $(n,e){function r(r){void 0===r&&(r=0);var t=e+r>=1?e+r:0;return n.el.getPointAtLength(t)}var t=q(n.el,n.svg),a=r(),o=r(-1),i=r(1);switch(n.property){case"x":return(a.x-t.x)*t.w;case"y":return(a.y-t.y)*t.h;case"angle":return 180*Math.atan2(i.y-o.y,i.x-o.x)/Math.PI}}function X(n,e){var r=/-?\d*\.?\d+/g,t=E(u.pth(n)?n.totalLength:n,e)+"";return{original:t,numbers:t.match(r)?t.match(r).map(Number):[0],strings:u.str(n)||e?t.split(r):[]}}function Y(n){return g(n?m(u.arr(n)?n.map(y):y(n)):[],function(n,e,r){return r.indexOf(n)===e})}function Z(n){var e=Y(n);return e.map(function(n,r){return{target:n,id:r,total:e.length,transforms:{list:T(n)}}})}function Q(n,e){var r=x(e);if(/^spring/.test(r.easing)&&(r.duration=c(r.easing)),u.arr(n)){var t=n.length;2===t&&!u.obj(n[0])?n={value:n}:u.fnc(e.duration)||(r.duration=e.duration/t)}var a=u.arr(n)?n:[n];return a.map(function(n,r){var t=u.obj(n)&&!u.pth(n)?n:{value:n};return u.und(t.delay)&&(t.delay=r?0:e.delay),u.und(t.endDelay)&&(t.endDelay=r===a.length-1?e.endDelay:0),t}).map(function(n){return w(n,r)})}function V(n,e){var r=[],t=e.keyframes;for(var a in t&&(e=w(function(n){for(var e=g(m(n.map(function(n){return Object.keys(n)})),function(n){return u.key(n)}).reduce(function(n,e){return n.indexOf(e)<0&&n.push(e),n},[]),r={},t=function(t){var a=e[t];r[a]=n.map(function(n){var e={};for(var r in n)u.key(r)?r==a&&(e.value=n[r]):e[r]=n[r];return e})},a=0;a<e.length;a++)t(a);return r}(t),e)),e)u.key(a)&&r.push({name:a,tweens:Q(e[a],n)});return r}function z(n,e){var r;return n.tweens.map(function(t){var a=function(n,e){var r={};for(var t in n){var a=O(n[t],e);u.arr(a)&&1===(a=a.map(function(n){return O(n,e)})).length&&(a=a[0]),r[t]=a}return r.duration=parseFloat(r.duration),r.delay=parseFloat(r.delay),r}(t,e),o=a.value,i=u.arr(o)?o[1]:o,s=C(i),c=N(e.target,n.name,s,e),f=r?r.to.original:c,l=u.arr(o)?o[0]:f,d=C(l)||C(c),p=s||d;return u.und(i)&&(i=f),a.from=X(l,p),a.to=X(A(i,l),p),a.start=r?r.end:0,a.end=a.start+a.delay+a.duration+a.endDelay,a.easing=v(a.easing,a.duration),a.isPath=u.pth(o),a.isColor=u.col(a.from.original),a.isColor&&(a.round=1),r=a,a})}var H={css:function(n,e,r){return n.style[e]=r},attribute:function(n,e,r){return n.setAttribute(e,r)},object:function(n,e,r){return n[e]=r},transform:function(n,e,r,t,a){if(t.list.set(e,r),e===t.last||a){var o="";t.list.forEach(function(n,e){o+=e+"("+n+") "}),n.style.transform=o}}};function G(n,e){Z(n).forEach(function(n){for(var r in e){var t=O(e[r],n),a=n.target,o=C(t),i=N(a,r,o,n),u=A(E(t,o||C(i)),i),s=D(a,r);H[s](a,r,u,n.transforms,!0)}})}function R(n,e){return g(m(n.map(function(n){return e.map(function(e){return function(n,e){var r=D(n.target,e.name);if(r){var t=z(e,n),a=t[t.length-1];return{type:r,property:e.name,animatable:n,tweens:t,duration:a.end,delay:t[0].delay,endDelay:a.endDelay}}}(n,e)})})),function(n){return!u.und(n)})}function W(n,e){var r=n.length,t=function(n){return n.timelineOffset?n.timelineOffset:0},a={};return a.duration=r?Math.max.apply(Math,n.map(function(n){return t(n)+n.duration})):e.duration,a.delay=r?Math.min.apply(Math,n.map(function(n){return t(n)+n.delay})):e.delay,a.endDelay=r?a.duration-Math.max.apply(Math,n.map(function(n){return t(n)+n.duration-n.endDelay})):e.endDelay,a}var J=0;var K,U=[],_=[],nn=function(){function n(){K=requestAnimationFrame(e)}function e(e){var r=U.length;if(r){for(var t=0;t<r;){var a=U[t];if(a.paused){var o=U.indexOf(a);o>-1&&(U.splice(o,1),r=U.length)}else a.tick(e);t++}n()}else K=cancelAnimationFrame(K)}return n}();function en(r){void 0===r&&(r={});var t,o=0,i=0,u=0,s=0,c=null;function f(n){var e=window.Promise&&new Promise(function(n){return c=n});return n.finished=e,e}var l,d,p,v,h,m,y,b,x=(d=M(n,l=r),p=M(e,l),v=V(p,l),h=Z(l.targets),m=R(h,v),y=W(m,p),b=J,J++,w(d,{id:b,children:[],animatables:h,animations:m,duration:y.duration,delay:y.delay,endDelay:y.endDelay}));f(x);function k(){var n=x.direction;"alternate"!==n&&(x.direction="normal"!==n?"normal":"reverse"),x.reversed=!x.reversed,t.forEach(function(n){return n.reversed=x.reversed})}function C(n){return x.reversed?x.duration-n:n}function O(){o=0,i=C(x.currentTime)*(1/en.speed)}function P(n,e){e&&e.seek(n-e.timelineOffset)}function I(n){for(var e=0,r=x.animations,t=r.length;e<t;){var o=r[e],i=o.animatable,u=o.tweens,s=u.length-1,c=u[s];s&&(c=g(u,function(e){return n<e.end})[0]||c);for(var f=a(n-c.start-c.delay,0,c.duration)/c.duration,l=isNaN(f)?1:c.easing(f),d=c.to.strings,p=c.round,v=[],h=c.to.numbers.length,m=void 0,y=0;y<h;y++){var b=void 0,M=c.to.numbers[y],w=c.from.numbers[y]||0;b=c.isPath?$(c.value,l*M):w+l*(M-w),p&&(c.isColor&&y>2||(b=Math.round(b*p)/p)),v.push(b)}var k=d.length;if(k){m=d[0];for(var C=0;C<k;C++){d[C];var O=d[C+1],P=v[C];isNaN(P)||(m+=O?P+O:P+" ")}}else m=v[0];H[o.type](i.target,o.property,m,i.transforms),o.currentValue=m,e++}}function B(n){x[n]&&!x.passThrough&&x[n](x)}function D(n){var e=x.duration,r=x.delay,l=e-x.endDelay,d=C(n);x.progress=a(d/e*100,0,100),x.reversePlayback=d<x.currentTime,t&&function(n){if(x.reversePlayback)for(var e=s;e--;)P(n,t[e]);else for(var r=0;r<s;r++)P(n,t[r])}(d),!x.began&&x.currentTime>0&&(x.began=!0,B("begin"),B("loopBegin")),d<=r&&0!==x.currentTime&&I(0),(d>=l&&x.currentTime!==e||!e)&&I(e),d>r&&d<l?(x.changeBegan||(x.changeBegan=!0,x.changeCompleted=!1,B("changeBegin")),B("change"),I(d)):x.changeBegan&&(x.changeCompleted=!0,x.changeBegan=!1,B("changeComplete")),x.currentTime=a(d,0,e),x.began&&B("update"),n>=e&&(i=0,x.remaining&&!0!==x.remaining&&x.remaining--,x.remaining?(o=u,B("loopComplete"),B("loopBegin"),"alternate"===x.direction&&k()):(x.paused=!0,x.completed||(x.completed=!0,B("loopComplete"),B("complete"),!x.passThrough&&"Promise"in window&&(c(),f(x)))))}return x.reset=function(){var n=x.direction;x.passThrough=!1,x.currentTime=0,x.progress=0,x.paused=!0,x.began=!1,x.changeBegan=!1,x.completed=!1,x.changeCompleted=!1,x.reversePlayback=!1,x.reversed="reverse"===n,x.remaining=x.loop,t=x.children;for(var e=s=t.length;e--;)x.children[e].reset();(x.reversed&&!0!==x.loop||"alternate"===n&&1===x.loop)&&x.remaining++,I(0)},x.set=function(n,e){return G(n,e),x},x.tick=function(n){u=n,o||(o=u),D((u+(i-o))*en.speed)},x.seek=function(n){D(C(n))},x.pause=function(){x.paused=!0,O()},x.play=function(){x.paused&&(x.completed&&x.reset(),x.paused=!1,U.push(x),O(),K||nn())},x.reverse=function(){k(),O()},x.restart=function(){x.reset(),x.play()},x.reset(),x.autoplay&&x.play(),x}function rn(n,e){for(var r=e.length;r--;)b(n,e[r].animatable.target)&&e.splice(r,1)}return"undefined"!=typeof document&&document.addEventListener("visibilitychange",function(){document.hidden?(U.forEach(function(n){return n.pause()}),_=U.slice(0),U=[]):_.forEach(function(n){return n.play()})}),en.version="3.0.1",en.speed=1,en.running=U,en.remove=function(n){for(var e=Y(n),r=U.length;r--;){var t=U[r],a=t.animations,o=t.children;rn(e,a);for(var i=o.length;i--;){var u=o[i],s=u.animations;rn(e,s),s.length||u.children.length||o.splice(i,1)}a.length||o.length||t.pause()}},en.get=N,en.set=G,en.convertPx=I,en.path=function(n,e){var r=u.str(n)?h(n)[0]:n,t=e||100;return function(n){return{property:n,el:r,svg:q(r),totalLength:j(r)*(t/100)}}},en.setDashoffset=function(n){var e=j(n);return n.setAttribute("stroke-dasharray",e),e},en.stagger=function(n,e){void 0===e&&(e={});var r=e.direction||"normal",t=e.easing?v(e.easing):null,a=e.grid,o=e.axis,i=e.from||0,s="first"===i,c="center"===i,f="last"===i,l=u.arr(n),d=l?parseFloat(n[0]):parseFloat(n),p=l?parseFloat(n[1]):0,h=C(l?n[1]:n)||0,g=e.start||0+(l?d:0),m=[],y=0;return function(n,e,u){if(s&&(i=0),c&&(i=(u-1)/2),f&&(i=u-1),!m.length){for(var v=0;v<u;v++){if(a){var b=c?(a[0]-1)/2:i%a[0],x=c?(a[1]-1)/2:Math.floor(i/a[0]),M=b-v%a[0],w=x-Math.floor(v/a[0]),k=Math.sqrt(M*M+w*w);"x"===o&&(k=-M),"y"===o&&(k=-w),m.push(k)}else m.push(Math.abs(i-v));y=Math.max.apply(Math,m)}t&&(m=m.map(function(n){return t(n/y)*y})),"reverse"===r&&(m=m.map(function(n){return o?n<0?-1*n:-n:Math.abs(y-n)}))}return g+(l?(p-d)/y:d)*(Math.round(100*m[e])/100)+h}},en.timeline=function(n){void 0===n&&(n={});var r=en(n);return r.duration=0,r.add=function(t,a){var o=U.indexOf(r),i=r.children;function s(n){n.passThrough=!0}o>-1&&U.splice(o,1);for(var c=0;c<i.length;c++)s(i[c]);var f=w(t,M(e,n));f.targets=f.targets||n.targets;var l=r.duration;f.autoplay=!1,f.direction=r.direction,f.timelineOffset=u.und(a)?l:A(a,l),s(r),r.seek(f.timelineOffset);var d=en(f);s(d),i.push(d);var p=W(i,n);return r.delay=p.delay,r.endDelay=p.endDelay,r.duration=p.duration,r.seek(0),r.reset(),r.autoplay&&r.play(),r},r},en.easing=v,en.penner=p,en.random=function(n,e){return Math.floor(Math.random()*(e-n+1))+n},en});
@@ -0,0 +1,60 @@
1
+ var current = null;
2
+
3
+ document.querySelector('#username').addEventListener('focus', function(e) {
4
+ if (current) current.pause();
5
+ current = anime({
6
+ targets: 'path',
7
+ strokeDashoffset: {
8
+ value: 0,
9
+ duration: 700,
10
+ easing: 'easeOutQuart'
11
+ },
12
+ strokeDasharray: {
13
+ value: '240 1386',
14
+ duration: 700,
15
+ easing: 'easeOutQuart'
16
+ }
17
+ });
18
+ });
19
+
20
+ document.querySelector('#password').addEventListener('focus', function(e) {
21
+ if (current) current.pause();
22
+ current = anime({
23
+ targets: 'path',
24
+ strokeDashoffset: {
25
+ value: -336,
26
+ duration: 700,
27
+ easing: 'easeOutQuart'
28
+ },
29
+ strokeDasharray: {
30
+ value: '240 1386',
31
+ duration: 700,
32
+ easing: 'easeOutQuart'
33
+ }
34
+ });
35
+ });
36
+
37
+ document.querySelector('#submit').addEventListener('focus', function(e) {
38
+ if (current) current.pause();
39
+ current = anime({
40
+ targets: 'path',
41
+ strokeDashoffset: {
42
+ value: -730,
43
+ duration: 700,
44
+ easing: 'easeOutQuart'
45
+ },
46
+ strokeDasharray: {
47
+ value: '530 1386',
48
+ duration: 700,
49
+ easing: 'easeOutQuart'
50
+ }
51
+ });
52
+ });
53
+
54
+ // Hide the login button in the title bar if present.
55
+ document.addEventListener("DOMContentLoaded", function() {
56
+ var loginTitleButton = document.querySelector(".login-title-btn");
57
+ if (loginTitleButton) {
58
+ loginTitleButton.style.display = "none";
59
+ }
60
+ });