Commit 6b94127b3df5d75cb1158b70aa526c5ab23954b7
Exists in
master
and in
39 other branches
Merge pull request #5 from TracyWebTech/master
Last update from PNUD contract
Showing
48 changed files
with
1831 additions
and
351 deletions
Show diff stats
puppet/modules/colab/manifests/cronjobs.pp
@@ -47,15 +47,15 @@ class colab::cronjobs { | @@ -47,15 +47,15 @@ class colab::cronjobs { | ||
47 | require => File['/mnt/mailman/'], | 47 | require => File['/mnt/mailman/'], |
48 | } | 48 | } |
49 | 49 | ||
50 | - cron { 'mount-sshfs': | ||
51 | - command => 'test -e /mnt/mailman/archives/flag || sshfs root@listas.interlegis.gov.br:/var/lib/mailman/archives/private /mnt/mailman/archives/ -o ro,nosuid,nodev,max_read=65536,allow_other,IdentityFile=/root/.ssh/id_rsa && touch /mnt/mailman/archives/flag &> /dev/null', | ||
52 | - minute => '*/5', | ||
53 | - user => 'root', | ||
54 | - require => [ | ||
55 | - File['/mnt/mailman/archives/'], | ||
56 | - #File['root-ssh-private-key'], | ||
57 | - Package['sshfs'], | ||
58 | - ], | ||
59 | - } | 50 | + #cron { 'mount-sshfs': |
51 | + # command => 'test -e /mnt/mailman/archives/flag || sshfs root@listas.interlegis.gov.br:/var/lib/mailman/archives/private /mnt/mailman/archives/ -o ro,nosuid,nodev,max_read=65536,allow_other,IdentityFile=/root/.ssh/id_rsa && touch /mnt/mailman/archives/flag &> /dev/null', | ||
52 | + # minute => '*/5', | ||
53 | + # user => 'root', | ||
54 | + # require => [ | ||
55 | + # File['/mnt/mailman/archives/'], | ||
56 | + # #File['root-ssh-private-key'], | ||
57 | + # Package['sshfs'], | ||
58 | + # ], | ||
59 | + #} | ||
60 | 60 | ||
61 | } | 61 | } |
puppet/modules/colab/manifests/init.pp
@@ -20,11 +20,13 @@ class colab { | @@ -20,11 +20,13 @@ class colab { | ||
20 | } | 20 | } |
21 | 21 | ||
22 | Mailalias { | 22 | Mailalias { |
23 | - notify => Exec['newaliases'], | 23 | + notify => Exec['newaliases'], |
24 | + require => Class['postfix'], | ||
24 | } | 25 | } |
25 | 26 | ||
26 | exec { 'newaliases': | 27 | exec { 'newaliases': |
27 | - path => '/usr/bin/newaliases', | 28 | + command => 'sendmail -bi', |
29 | + path => '/usr/sbin', | ||
28 | refreshonly => true, | 30 | refreshonly => true, |
29 | } | 31 | } |
30 | 32 |
puppet/modules/colab/manifests/requirements.pp
@@ -25,7 +25,6 @@ class colab::requirements { | @@ -25,7 +25,6 @@ class colab::requirements { | ||
25 | # XMPP connection manager | 25 | # XMPP connection manager |
26 | package { 'punjab': | 26 | package { 'punjab': |
27 | ensure => installed, | 27 | ensure => installed, |
28 | - source => 'git+https://github.com/twonds/punjab@c96ffe4#egg=punjab', | ||
29 | provider => pip, | 28 | provider => pip, |
30 | require => Package['python-pip'], | 29 | require => Package['python-pip'], |
31 | } | 30 | } |
requirements.txt
1 | -Django>=1.6,<1.7 | 1 | +Django>=1.6.1,<1.7 |
2 | South==0.8.1 | 2 | South==0.8.1 |
3 | psycopg2==2.5.1 | 3 | psycopg2==2.5.1 |
4 | django-piston==0.2.3 | 4 | django-piston==0.2.3 |
@@ -17,6 +17,7 @@ python-memcached==1.53 | @@ -17,6 +17,7 @@ python-memcached==1.53 | ||
17 | django-hitcounter==0.1.1 | 17 | django-hitcounter==0.1.1 |
18 | Pillow==2.2.1 | 18 | Pillow==2.2.1 |
19 | django-i18n-model==0.0.7 | 19 | django-i18n-model==0.0.7 |
20 | +django-tastypie==0.11.0 | ||
20 | 21 | ||
21 | gunicorn==18.0 | 22 | gunicorn==18.0 |
22 | gevent==0.13.8 | 23 | gevent==0.13.8 |
@@ -31,7 +32,7 @@ git+https://github.com/mozilla/django-browserid | @@ -31,7 +32,7 @@ git+https://github.com/mozilla/django-browserid | ||
31 | django-revproxy==0.2.7 | 32 | django-revproxy==0.2.7 |
32 | 33 | ||
33 | # Converse.js (XMPP client) | 34 | # Converse.js (XMPP client) |
34 | -django-conversejs==0.2.9 | 35 | +django-conversejs==0.3 |
35 | git+https://github.com/TracyWebTech/SleekXMPP@fix-gevent | 36 | git+https://github.com/TracyWebTech/SleekXMPP@fix-gevent |
36 | 37 | ||
37 | # Feedzilla (planet) and deps | 38 | # Feedzilla (planet) and deps |
src/accounts/forms.py
@@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _ | @@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _ | ||
6 | 6 | ||
7 | from conversejs.models import XMPPAccount | 7 | from conversejs.models import XMPPAccount |
8 | 8 | ||
9 | +from accounts.utils import mailman | ||
9 | from super_archives.models import MailingList | 10 | from super_archives.models import MailingList |
10 | from .utils.validators import validate_social_account | 11 | from .utils.validators import validate_social_account |
11 | 12 | ||
@@ -49,19 +50,29 @@ class UserCreationForm(UserForm): | @@ -49,19 +50,29 @@ class UserCreationForm(UserForm): | ||
49 | 50 | ||
50 | 51 | ||
51 | class UserUpdateForm(UserForm): | 52 | class UserUpdateForm(UserForm): |
53 | + bio = forms.CharField( | ||
54 | + widget=forms.Textarea(attrs={'rows': '6', 'maxlength': '200'}), | ||
55 | + max_length=200, | ||
56 | + label=_(u'Bio'), | ||
57 | + help_text=_(u'Write something about you in 200 characters or less.'), | ||
58 | + required=False, | ||
59 | + ) | ||
52 | 60 | ||
53 | class Meta: | 61 | class Meta: |
54 | model = User | 62 | model = User |
55 | fields = ('first_name', 'last_name', | 63 | fields = ('first_name', 'last_name', |
56 | 'institution', 'role', 'twitter', 'facebook', | 64 | 'institution', 'role', 'twitter', 'facebook', |
57 | - 'google_talk', 'webpage') | 65 | + 'google_talk', 'github', 'webpage', 'bio') |
58 | 66 | ||
59 | twitter = SocialAccountField(url='https://twitter.com/', required=False) | 67 | twitter = SocialAccountField(url='https://twitter.com/', required=False) |
60 | facebook = SocialAccountField(url='https://graph.facebook.com/', required=False) | 68 | facebook = SocialAccountField(url='https://graph.facebook.com/', required=False) |
61 | 69 | ||
62 | 70 | ||
63 | class ListsForm(forms.Form): | 71 | class ListsForm(forms.Form): |
64 | - LISTS_NAMES = ((list.name, list.name) for list in MailingList.objects.all()) | 72 | + LISTS_NAMES = (( |
73 | + listname, u'{} ({})'.format(listname, description) | ||
74 | + ) for listname, description in mailman.all_lists(description=True)) | ||
75 | + | ||
65 | lists = forms.MultipleChoiceField(label=_(u'Mailing lists'), | 76 | lists = forms.MultipleChoiceField(label=_(u'Mailing lists'), |
66 | required=False, | 77 | required=False, |
67 | widget=forms.CheckboxSelectMultiple, | 78 | widget=forms.CheckboxSelectMultiple, |
@@ -0,0 +1,69 @@ | @@ -0,0 +1,69 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +import datetime | ||
3 | +from south.db import db | ||
4 | +from south.v2 import DataMigration | ||
5 | +from django.db import models | ||
6 | + | ||
7 | +class Migration(DataMigration): | ||
8 | + | ||
9 | + def forwards(self, orm): | ||
10 | + "Write your forwards methods here." | ||
11 | + # Note: Don't use "from appname.models import ModelName". | ||
12 | + # Use orm.ModelName to refer to models in this application, | ||
13 | + # and orm['appname.ModelName'] for models in other applications. | ||
14 | + for u in orm.User.objects.filter(username__contains='@'): | ||
15 | + u.username = u.username.split('@')[0] | ||
16 | + u.save() | ||
17 | + | ||
18 | + def backwards(self, orm): | ||
19 | + pass | ||
20 | + | ||
21 | + models = { | ||
22 | + u'accounts.user': { | ||
23 | + 'Meta': {'object_name': 'User'}, | ||
24 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
25 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | ||
26 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
27 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
28 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | ||
29 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | ||
30 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
31 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
32 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
33 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
34 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
35 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
36 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
37 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), | ||
38 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
39 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
40 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
41 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | ||
42 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | ||
43 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | ||
44 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | ||
45 | + }, | ||
46 | + u'auth.group': { | ||
47 | + 'Meta': {'object_name': 'Group'}, | ||
48 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
49 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
50 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
51 | + }, | ||
52 | + u'auth.permission': { | ||
53 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | ||
54 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
55 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | ||
56 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
57 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
58 | + }, | ||
59 | + u'contenttypes.contenttype': { | ||
60 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
61 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
62 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
63 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
64 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
65 | + } | ||
66 | + } | ||
67 | + | ||
68 | + complete_apps = ['accounts'] | ||
69 | + symmetrical = True |
src/accounts/migrations/0008_auto__add_field_user_bio.py
0 → 100644
@@ -0,0 +1,70 @@ | @@ -0,0 +1,70 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +import datetime | ||
3 | +from south.db import db | ||
4 | +from south.v2 import SchemaMigration | ||
5 | +from django.db import models | ||
6 | + | ||
7 | + | ||
8 | +class Migration(SchemaMigration): | ||
9 | + | ||
10 | + def forwards(self, orm): | ||
11 | + # Adding field 'User.bio' | ||
12 | + db.add_column(u'accounts_user', 'bio', | ||
13 | + self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True), | ||
14 | + keep_default=False) | ||
15 | + | ||
16 | + | ||
17 | + def backwards(self, orm): | ||
18 | + # Deleting field 'User.bio' | ||
19 | + db.delete_column(u'accounts_user', 'bio') | ||
20 | + | ||
21 | + | ||
22 | + models = { | ||
23 | + u'accounts.user': { | ||
24 | + 'Meta': {'object_name': 'User'}, | ||
25 | + 'bio': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | ||
26 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
27 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | ||
28 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
29 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
30 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | ||
31 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | ||
32 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
33 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
34 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
35 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
36 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
37 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
38 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
39 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), | ||
40 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
41 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
42 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
43 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | ||
44 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | ||
45 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | ||
46 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | ||
47 | + }, | ||
48 | + u'auth.group': { | ||
49 | + 'Meta': {'object_name': 'Group'}, | ||
50 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
51 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
52 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
53 | + }, | ||
54 | + u'auth.permission': { | ||
55 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | ||
56 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
57 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | ||
58 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
59 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
60 | + }, | ||
61 | + u'contenttypes.contenttype': { | ||
62 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
63 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
64 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
65 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
66 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
67 | + } | ||
68 | + } | ||
69 | + | ||
70 | + complete_apps = ['accounts'] | ||
0 | \ No newline at end of file | 71 | \ No newline at end of file |
src/accounts/migrations/0009_auto__add_field_user_identi_ca.py
0 → 100644
@@ -0,0 +1,71 @@ | @@ -0,0 +1,71 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +import datetime | ||
3 | +from south.db import db | ||
4 | +from south.v2 import SchemaMigration | ||
5 | +from django.db import models | ||
6 | + | ||
7 | + | ||
8 | +class Migration(SchemaMigration): | ||
9 | + | ||
10 | + def forwards(self, orm): | ||
11 | + # Adding field 'User.identi_ca' | ||
12 | + db.add_column(u'accounts_user', 'identi_ca', | ||
13 | + self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True), | ||
14 | + keep_default=False) | ||
15 | + | ||
16 | + | ||
17 | + def backwards(self, orm): | ||
18 | + # Deleting field 'User.identi_ca' | ||
19 | + db.delete_column(u'accounts_user', 'identi_ca') | ||
20 | + | ||
21 | + | ||
22 | + models = { | ||
23 | + u'accounts.user': { | ||
24 | + 'Meta': {'object_name': 'User'}, | ||
25 | + 'bio': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | ||
26 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
27 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | ||
28 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
29 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
30 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | ||
31 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | ||
32 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
33 | + 'identi_ca': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
34 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
35 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
36 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
37 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
38 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
39 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
40 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), | ||
41 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
42 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
43 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
44 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | ||
45 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | ||
46 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | ||
47 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | ||
48 | + }, | ||
49 | + u'auth.group': { | ||
50 | + 'Meta': {'object_name': 'Group'}, | ||
51 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
52 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
53 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
54 | + }, | ||
55 | + u'auth.permission': { | ||
56 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | ||
57 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
58 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | ||
59 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
60 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
61 | + }, | ||
62 | + u'contenttypes.contenttype': { | ||
63 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
64 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
65 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
66 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
67 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
68 | + } | ||
69 | + } | ||
70 | + | ||
71 | + complete_apps = ['accounts'] | ||
0 | \ No newline at end of file | 72 | \ No newline at end of file |
src/accounts/migrations/0010_auto__del_field_user_identi_ca__add_field_user_github.py
0 → 100644
@@ -0,0 +1,79 @@ | @@ -0,0 +1,79 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +import datetime | ||
3 | +from south.db import db | ||
4 | +from south.v2 import SchemaMigration | ||
5 | +from django.db import models | ||
6 | + | ||
7 | + | ||
8 | +class Migration(SchemaMigration): | ||
9 | + | ||
10 | + def forwards(self, orm): | ||
11 | + # Deleting field 'User.identi_ca' | ||
12 | + db.delete_column(u'accounts_user', 'identi_ca') | ||
13 | + | ||
14 | + # Adding field 'User.github' | ||
15 | + db.add_column(u'accounts_user', 'github', | ||
16 | + self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True), | ||
17 | + keep_default=False) | ||
18 | + | ||
19 | + | ||
20 | + def backwards(self, orm): | ||
21 | + # Adding field 'User.identi_ca' | ||
22 | + db.add_column(u'accounts_user', 'identi_ca', | ||
23 | + self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True), | ||
24 | + keep_default=False) | ||
25 | + | ||
26 | + # Deleting field 'User.github' | ||
27 | + db.delete_column(u'accounts_user', 'github') | ||
28 | + | ||
29 | + | ||
30 | + models = { | ||
31 | + u'accounts.user': { | ||
32 | + 'Meta': {'object_name': 'User'}, | ||
33 | + 'bio': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | ||
34 | + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
35 | + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}), | ||
36 | + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
37 | + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
38 | + 'github': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
39 | + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), | ||
40 | + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), | ||
41 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
42 | + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
43 | + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
44 | + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
45 | + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
46 | + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
47 | + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
48 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), | ||
49 | + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
50 | + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
51 | + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), | ||
52 | + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), | ||
53 | + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), | ||
54 | + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), | ||
55 | + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}) | ||
56 | + }, | ||
57 | + u'auth.group': { | ||
58 | + 'Meta': {'object_name': 'Group'}, | ||
59 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
60 | + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
61 | + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
62 | + }, | ||
63 | + u'auth.permission': { | ||
64 | + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, | ||
65 | + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
66 | + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | ||
67 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
68 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
69 | + }, | ||
70 | + u'contenttypes.contenttype': { | ||
71 | + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
72 | + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
73 | + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
74 | + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
75 | + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
76 | + } | ||
77 | + } | ||
78 | + | ||
79 | + complete_apps = ['accounts'] | ||
0 | \ No newline at end of file | 80 | \ No newline at end of file |
src/accounts/models.py
@@ -5,7 +5,9 @@ import urlparse | @@ -5,7 +5,9 @@ import urlparse | ||
5 | from django.db import models, DatabaseError | 5 | from django.db import models, DatabaseError |
6 | from django.contrib.auth.hashers import check_password | 6 | from django.contrib.auth.hashers import check_password |
7 | from django.contrib.auth.models import AbstractUser | 7 | from django.contrib.auth.models import AbstractUser |
8 | +from django.core import validators | ||
8 | from django.core.urlresolvers import reverse | 9 | from django.core.urlresolvers import reverse |
10 | +from django.utils.translation import ugettext_lazy as _ | ||
9 | 11 | ||
10 | from conversejs import xmpp | 12 | from conversejs import xmpp |
11 | 13 | ||
@@ -18,9 +20,12 @@ class User(AbstractUser): | @@ -18,9 +20,12 @@ class User(AbstractUser): | ||
18 | twitter = models.CharField(max_length=128, null=True, blank=True) | 20 | twitter = models.CharField(max_length=128, null=True, blank=True) |
19 | facebook = models.CharField(max_length=128, null=True, blank=True) | 21 | facebook = models.CharField(max_length=128, null=True, blank=True) |
20 | google_talk = models.EmailField(null=True, blank=True) | 22 | google_talk = models.EmailField(null=True, blank=True) |
23 | + github = models.CharField(max_length=128, null=True, blank=True, | ||
24 | + verbose_name=u'github') | ||
21 | webpage = models.CharField(max_length=256, null=True, blank=True) | 25 | webpage = models.CharField(max_length=256, null=True, blank=True) |
22 | verification_hash = models.CharField(max_length=32, null=True, blank=True) | 26 | verification_hash = models.CharField(max_length=32, null=True, blank=True) |
23 | modified = models.DateTimeField(auto_now=True) | 27 | modified = models.DateTimeField(auto_now=True) |
28 | + bio = models.CharField(max_length=200, null=True, blank=True) | ||
24 | 29 | ||
25 | def check_password(self, raw_password): | 30 | def check_password(self, raw_password): |
26 | 31 | ||
@@ -50,3 +55,12 @@ class User(AbstractUser): | @@ -50,3 +55,12 @@ class User(AbstractUser): | ||
50 | # The following workaroud allows to change email field to unique | 55 | # The following workaroud allows to change email field to unique |
51 | # without having to rewrite all AbstractUser here | 56 | # without having to rewrite all AbstractUser here |
52 | User._meta.get_field('email')._unique = True | 57 | User._meta.get_field('email')._unique = True |
58 | +User._meta.get_field('username').help_text = _( | ||
59 | + u'Required. 30 characters or fewer. Letters, digits and ' | ||
60 | + u'./+/-/_ only.' | ||
61 | +) | ||
62 | +User._meta.get_field('username').validators[0] = validators.RegexValidator( | ||
63 | + r'^[\w.+-]+$', | ||
64 | + _('Enter a valid username.'), | ||
65 | + 'invalid' | ||
66 | +) |
src/accounts/search_indexes.py
@@ -41,9 +41,6 @@ class UserIndex(indexes.SearchIndex, indexes.Indexable): | @@ -41,9 +41,6 @@ class UserIndex(indexes.SearchIndex, indexes.Indexable): | ||
41 | self._badge_counters = get_users_counters() | 41 | self._badge_counters = get_users_counters() |
42 | return self._badge_counters | 42 | return self._badge_counters |
43 | 43 | ||
44 | - def get_updated_field(self): | ||
45 | - return 'modified' | ||
46 | - | ||
47 | def prepare(self, obj): | 44 | def prepare(self, obj): |
48 | prepared_data = super(UserIndex, self).prepare(obj) | 45 | prepared_data = super(UserIndex, self).prepare(obj) |
49 | 46 |
src/accounts/templates/accounts/manage_subscriptions.html
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | 3 | ||
4 | {% block main-content %} | 4 | {% block main-content %} |
5 | 5 | ||
6 | - <h2>{% blocktrans %}Mailing List Subscriptions{% endblocktrans %}</h2> | 6 | + <h2>{% blocktrans %}Group Subscriptions{% endblocktrans %}</h2> |
7 | <h3>{% gravatar user_.email 50 %} {{ user_.get_full_name }} ({{ user_.username }})</h3> | 7 | <h3>{% gravatar user_.email 50 %} {{ user_.get_full_name }} ({{ user_.username }})</h3> |
8 | <br> | 8 | <br> |
9 | 9 | ||
@@ -19,9 +19,9 @@ | @@ -19,9 +19,9 @@ | ||
19 | </div> | 19 | </div> |
20 | <div class="panel-body"> | 20 | <div class="panel-body"> |
21 | {% for list, checked in lists %} | 21 | {% for list, checked in lists %} |
22 | - <div class="checkbox"> | 22 | + <div class="checkbox" title="{{ list.description }}"> |
23 | <label> | 23 | <label> |
24 | - <input name="{{ email }}" value="{{ list }}" type="checkbox" {% if checked %}checked{% endif%}>{{ list }}</input> | 24 | + <input name="{{ email }}" value="{{ list.listname }}" type="checkbox" {% if checked %}checked{% endif%}>{{ list.listname }}</input> |
25 | </label> | 25 | </label> |
26 | </div> | 26 | </div> |
27 | {% endfor %} | 27 | {% endfor %} |
src/accounts/templates/accounts/user_create_form.html
@@ -43,7 +43,7 @@ | @@ -43,7 +43,7 @@ | ||
43 | <div class="col-md-6 col-lg-6 col-sm-6 col-xs-12" style="display: inline-block; vertical-align:top;"> | 43 | <div class="col-md-6 col-lg-6 col-sm-6 col-xs-12" style="display: inline-block; vertical-align:top;"> |
44 | <div class="well"> | 44 | <div class="well"> |
45 | <fieldset> | 45 | <fieldset> |
46 | - <legend>{% trans 'Subscribe to mail lists' %}</legend> | 46 | + <legend>{% trans 'Subscribe to groups' %}</legend> |
47 | {% for choice in lists_form.lists %} | 47 | {% for choice in lists_form.lists %} |
48 | <div class="checkbox">{{ choice }}</div> | 48 | <div class="checkbox">{{ choice }}</div> |
49 | {% endfor %} | 49 | {% endfor %} |
src/accounts/templates/accounts/user_detail.html
@@ -4,8 +4,11 @@ | @@ -4,8 +4,11 @@ | ||
4 | 4 | ||
5 | 5 | ||
6 | {% block head_js %} | 6 | {% block head_js %} |
7 | - {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=300 %} | ||
8 | - {% include "pizza-chart.html" with chart_data=list_activity chart_div="collabs2" chart_height=300 %} | 7 | + {% trans "Messages" as group_collabs %} |
8 | + {% trans "Contributions" as type_collabs %} | ||
9 | + | ||
10 | + {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=300 name=type_collabs %} | ||
11 | + {% include "pizza-chart.html" with chart_data=list_activity chart_div="collabs2" chart_height=300 name=group_collabs %} | ||
9 | {% endblock %} | 12 | {% endblock %} |
10 | 13 | ||
11 | {% block main-content %} | 14 | {% block main-content %} |
@@ -22,16 +25,26 @@ | @@ -22,16 +25,26 @@ | ||
22 | </h1> | 25 | </h1> |
23 | 26 | ||
24 | {% if request.user == user_ or request.user.is_superuser %} | 27 | {% if request.user == user_ or request.user.is_superuser %} |
25 | - <a class="btn btn-info" href="{% url 'user_profile_update' user_ %}"><span class="glyphicon glyphicon-pencil"></span> {% trans "profile"|title %}</a> | ||
26 | - <a class="btn btn-info" href="{% url 'user_list_subscriptions' user_ %}"><span class="glyphicon glyphicon-pencil"></span> {% trans "list membership"|title %}</a> | 28 | + <a class="btn btn-info" href="{% url 'user_profile_update' user_ %}"><span class="glyphicon glyphicon-pencil"></span> {% trans "edit profile"|title %}</a> |
29 | + <a class="btn btn-info" href="{% url 'user_list_subscriptions' user_ %}"><span class="glyphicon glyphicon-pencil"></span> {% trans "group membership"|title %}</a> | ||
30 | + {% endif %} | ||
31 | + | ||
32 | + {% if request.user.is_active %} | ||
33 | + {% if user_.bio %} | ||
34 | + <div class="divider"></div> | ||
35 | + <ul class="unstyled-list"> | ||
36 | + <li> | ||
37 | + <strong>{% trans 'Bio' %}</strong> | ||
38 | + </li> | ||
39 | + <li class="text-muted"> {{ user_.bio }}</li> | ||
40 | + </ul> | ||
41 | + {% endif %} | ||
27 | {% endif %} | 42 | {% endif %} |
28 | 43 | ||
29 | <div class="divider"></div> | 44 | <div class="divider"></div> |
30 | {% if request.user.is_active %} | 45 | {% if request.user.is_active %} |
31 | <ul class="unstyled-list"> | 46 | <ul class="unstyled-list"> |
32 | - {% for email in user_.emails.iterator %} | ||
33 | - <li><span class="icon-envelope icon-fixed-width"></span> {{ email.address }}</li> | ||
34 | - {% endfor %} | 47 | + <li><span class="icon-envelope icon-fixed-width"></span> <a href="mailto:{{ user_.email }}">{{ user_.email }}</a></li> |
35 | </ul> | 48 | </ul> |
36 | <div class="divider"></div> | 49 | <div class="divider"></div> |
37 | {% endif %} | 50 | {% endif %} |
@@ -48,26 +61,31 @@ | @@ -48,26 +61,31 @@ | ||
48 | {% if request.user.is_active %} | 61 | {% if request.user.is_active %} |
49 | <li> | 62 | <li> |
50 | {% if user_.twitter %} | 63 | {% if user_.twitter %} |
51 | - <span class="icon-twitter icon-fixed-width"></span> <a target="_blank" href="{{ user_.twitter_link }}" title="{% trans 'Twitter account' %}">{{ user_.twitter }}</a> | 64 | + <span class="icon-twitter icon-fixed-width" title="{% trans 'Twitter account' %}"></span> <a target="_blank" href="{{ user_.twitter_link }}" title="{% trans 'Twitter account' %}">{{ user_.twitter }}</a> |
52 | {% endif %} | 65 | {% endif %} |
53 | {% if user_.facebook %} | 66 | {% if user_.facebook %} |
54 | - <span class="icon-facebook icon-fixed-width"></span> <a target="_blank" href="{{ user_.facebook_link }}" title="{% trans 'Facebook account' %}">{{ user_.facebook }}</a> | 67 | + <span class="icon-facebook icon-fixed-width" title="{% trans 'Facebook account' %}"></span> <a target="_blank" href="{{ user_.facebook_link }}" title="{% trans 'Facebook account' %}">{{ user_.facebook }}</a> |
55 | {% endif %} | 68 | {% endif %} |
56 | </li> | 69 | </li> |
57 | 70 | ||
58 | {% if user_.google_talk %} | 71 | {% if user_.google_talk %} |
59 | - <li><span class="icon-google-plus icon-fixed-width"></span> {{ user_.google_talk }}</li> | 72 | + <li><span class="icon-google-plus icon-fixed-width" title="{% trans 'Google talk account' %}"></span> {{ user_.google_talk }}</li> |
73 | + {% endif %} | ||
74 | + | ||
75 | + {% if user_.github %} | ||
76 | + <li><span class="icon-github icon-fixed-width" title="{% trans 'Github account' %}"></span> <a target="_blank" href="https://github.com/{{ user_.github }}">{{ user_.github }}</a></li> | ||
60 | {% endif %} | 77 | {% endif %} |
78 | + | ||
61 | {% if user_.webpage %} | 79 | {% if user_.webpage %} |
62 | - <li><span class="icon-link icon-fixed-width"></span> <a target="_blank" href="{{ user_.webpage }}" title="{% trans 'Personal webpage' %}">{{ user_.webpage }}</a></li> | 80 | + <li><span class="icon-link icon-fixed-width" title="{% trans 'Personal webpage' %}"></span> <a target="_blank" href="{{ user_.webpage }}" title="{% trans 'Personal webpage' %}">{{ user_.webpage }}</a></li> |
63 | {% endif %} | 81 | {% endif %} |
64 | {% endif %} | 82 | {% endif %} |
65 | </ul> | 83 | </ul> |
66 | 84 | ||
67 | {% if user_.mailinglists %} | 85 | {% if user_.mailinglists %} |
68 | - <b>{% trans 'Subscribes: ' %}</b> | 86 | + <b>{% trans 'Groups: ' %}</b> |
69 | {% for list in user_.mailinglists %} | 87 | {% for list in user_.mailinglists %} |
70 | - <span class="label label-primary">{{ list }}</span> | 88 | + <a href="{% url 'haystack_search' %}?order=latest&type=thread&list={{ list }}"><span class="label label-primary">{{ list }}</span></a> |
71 | {% endfor %} | 89 | {% endfor %} |
72 | {% endif %} | 90 | {% endif %} |
73 | 91 | ||
@@ -78,7 +96,7 @@ | @@ -78,7 +96,7 @@ | ||
78 | <div class="col-lg-4 col-md-4 col-sm-7"> | 96 | <div class="col-lg-4 col-md-4 col-sm-7"> |
79 | <div class="panel panel-default"> | 97 | <div class="panel panel-default"> |
80 | <div class="panel-heading"> | 98 | <div class="panel-heading"> |
81 | - <h3 class="panel-title">{% trans "Contributions by Area" %}</h3> | 99 | + <h3 class="panel-title">{% trans "Contributions by Type" %}</h3> |
82 | </div> | 100 | </div> |
83 | <div class="panel-body"> | 101 | <div class="panel-body"> |
84 | <div id="collabs"></div> | 102 | <div id="collabs"></div> |
@@ -90,7 +108,7 @@ | @@ -90,7 +108,7 @@ | ||
90 | <div class="col-lg-4 col-md-4 col-sm-7"> | 108 | <div class="col-lg-4 col-md-4 col-sm-7"> |
91 | <div class="panel panel-default"> | 109 | <div class="panel panel-default"> |
92 | <div class="panel-heading"> | 110 | <div class="panel-heading"> |
93 | - <h3 class="panel-title">{% trans "Mailing list Participation" %}</h3> | 111 | + <h3 class="panel-title">{% trans "Participation by Group" %}</h3> |
94 | </div> | 112 | </div> |
95 | <div class="panel-body"> | 113 | <div class="panel-body"> |
96 | <div id="collabs2"></div> | 114 | <div id="collabs2"></div> |
@@ -130,6 +148,10 @@ | @@ -130,6 +148,10 @@ | ||
130 | <li>{% trans "There are no posts by this user so far." %}</li> | 148 | <li>{% trans "There are no posts by this user so far." %}</li> |
131 | {% endfor %} | 149 | {% endfor %} |
132 | </ul> | 150 | </ul> |
151 | + <a href="{% url 'haystack_search' %}?type=thread&author={{ user_.username }}"> | ||
152 | + {% trans "View more discussions..." %} | ||
153 | + </a> | ||
154 | + <div> </div> | ||
133 | </div> | 155 | </div> |
134 | 156 | ||
135 | <div class="col-lg-6 col-md-6 col-sm-12"> | 157 | <div class="col-lg-6 col-md-6 col-sm-12"> |
@@ -141,6 +163,10 @@ | @@ -141,6 +163,10 @@ | ||
141 | <li>{% trans "No contributions of this user so far." %}</li> | 163 | <li>{% trans "No contributions of this user so far." %}</li> |
142 | {% endfor %} | 164 | {% endfor %} |
143 | </ul> | 165 | </ul> |
166 | + <a href="{% url 'haystack_search' %}?order=latest&collaborators={{ user_.username }}"> | ||
167 | + {% trans "View more contributions..." %} | ||
168 | + </a> | ||
169 | + <div> </div> | ||
144 | </div> | 170 | </div> |
145 | 171 | ||
146 | </div> | 172 | </div> |
src/accounts/templates/accounts/user_update_form.html
@@ -178,22 +178,26 @@ $(function() { | @@ -178,22 +178,26 @@ $(function() { | ||
178 | </div> | 178 | </div> |
179 | </div> | 179 | </div> |
180 | </div> | 180 | </div> |
181 | + </div> | ||
181 | 182 | ||
182 | - <div class="col-lg-4 col-md-5 col-sm-12 col-xm-12"> | ||
183 | - <div class="panel panel-default"> | ||
184 | - <div class="panel-heading"> | ||
185 | - <h3 class="panel-title">{% trans "Change SVN and XMPP Client password" %}</h3> | ||
186 | - </div> | ||
187 | - <div class="panel-body"> | ||
188 | - <div class="form-group"> | ||
189 | - {% trans "You don't need to change this password. Change it only if you really know what you are doing." %} | ||
190 | - </div> | ||
191 | - <a href="{% url 'change_password' %}" class="btn btn-primary pull-right">{% trans "Change Password" %}</a> | 183 | + <div class="row"> |
184 | + <div class="col-lg-12"> | ||
185 | + <div class="panel panel-default"> | ||
186 | + <div class="panel-heading"> | ||
187 | + <h3 class="panel-title"> | ||
188 | + {% blocktrans %}Change <a href="http://repositorio.interlegis.gov.br/">SVN</a> and <a href="http://mensageiro.interlegis.gov.br/">XMPP Client</a> password{% endblocktrans %} | ||
189 | + </h3> | ||
190 | + </div> | ||
191 | + <div class="panel-body"> | ||
192 | + <div class="form-group"> | ||
193 | + {% trans "This feature is available only for who needs to change the password for some reason as having an old user with the same username, forgot your password to commit, usage of other XMPP Client for connection. Usually, you won't need to change this password. Only change it if you are sure about what you are doing." %} | ||
192 | </div> | 194 | </div> |
195 | + <a href="{% url 'change_password' %}" class="btn btn-default pull-right"><span class="icon-warning-sign"></span> {% trans "Change Password" %}</a> | ||
193 | </div> | 196 | </div> |
194 | </div> | 197 | </div> |
195 | - | 198 | + </div> |
196 | </div> | 199 | </div> |
200 | + | ||
197 | <div class="row"> | 201 | <div class="row"> |
198 | <div class="submit"> | 202 | <div class="submit"> |
199 | <button type="submit" class="btn btn-primary btn-lg btn-block">{% trans "Update" %}</button> | 203 | <button type="submit" class="btn btn-primary btn-lg btn-block">{% trans "Update" %}</button> |
src/accounts/utils/mailman.py
@@ -44,18 +44,22 @@ def update_subscription(address, lists): | @@ -44,18 +44,22 @@ def update_subscription(address, lists): | ||
44 | subscribe(maillist, address) | 44 | subscribe(maillist, address) |
45 | 45 | ||
46 | 46 | ||
47 | -def address_lists(address): | 47 | +def address_lists(address, description=''): |
48 | url = get_url() | 48 | url = get_url() |
49 | + | ||
50 | + params = {'address': address, | ||
51 | + 'description': description} | ||
52 | + | ||
49 | try: | 53 | try: |
50 | - lists = requests.get(url, timeout=TIMEOUT, params={'address': address}) | 54 | + lists = requests.get(url, timeout=TIMEOUT, params=params) |
51 | except requests.exceptions.RequestException: | 55 | except requests.exceptions.RequestException: |
52 | return [] | 56 | return [] |
53 | 57 | ||
54 | return lists.json() | 58 | return lists.json() |
55 | 59 | ||
56 | 60 | ||
57 | -def all_lists(): | ||
58 | - return address_lists('') | 61 | +def all_lists(*args, **kwargs): |
62 | + return address_lists('', *args, **kwargs) | ||
59 | 63 | ||
60 | 64 | ||
61 | def user_lists(user): | 65 | def user_lists(user): |
@@ -65,3 +69,12 @@ def user_lists(user): | @@ -65,3 +69,12 @@ def user_lists(user): | ||
65 | list_set.update(address_lists(email)) | 69 | list_set.update(address_lists(email)) |
66 | 70 | ||
67 | return tuple(list_set) | 71 | return tuple(list_set) |
72 | + | ||
73 | + | ||
74 | +def get_list_description(listname, lists=None): | ||
75 | + if not lists: | ||
76 | + lists = dict(all_lists(description=True)) | ||
77 | + elif not isinstance(lists, dict): | ||
78 | + lists = dict(lists) | ||
79 | + | ||
80 | + return lists.get(listname) |
src/accounts/views.py
@@ -23,6 +23,7 @@ from haystack.query import SearchQuerySet | @@ -23,6 +23,7 @@ from haystack.query import SearchQuerySet | ||
23 | from super_archives.models import EmailAddress, Message | 23 | from super_archives.models import EmailAddress, Message |
24 | from super_archives.utils.email import send_email_lists | 24 | from super_archives.utils.email import send_email_lists |
25 | from search.utils import trans | 25 | from search.utils import trans |
26 | +from proxy.models import WikiCollabCount, TicketCollabCount | ||
26 | from .forms import (UserCreationForm, ListsForm, UserUpdateForm, | 27 | from .forms import (UserCreationForm, ListsForm, UserUpdateForm, |
27 | ChangeXMPPPasswordForm) | 28 | ChangeXMPPPasswordForm) |
28 | from .errors import XMPPChangePwdException | 29 | from .errors import XMPPChangePwdException |
@@ -65,11 +66,28 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): | @@ -65,11 +66,28 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): | ||
65 | {'fullname_and_username__contains': user.username}, | 66 | {'fullname_and_username__contains': user.username}, |
66 | ) | 67 | ) |
67 | 68 | ||
69 | + counter_class = { | ||
70 | + 'wiki': WikiCollabCount, | ||
71 | + 'ticket': TicketCollabCount, | ||
72 | + } | ||
73 | + | ||
74 | + messages = Message.objects.filter(from_address__user__pk=user.pk) | ||
68 | for type in ['thread', 'ticket', 'wiki', 'changeset', 'attachment']: | 75 | for type in ['thread', 'ticket', 'wiki', 'changeset', 'attachment']: |
69 | - sqs = SearchQuerySet() | ||
70 | - for filter_or in fields_or_lookup: | ||
71 | - sqs = sqs.filter_or(type=type, **filter_or) | ||
72 | - count_types[trans(type)] = sqs.count() | 76 | + CounterClass = counter_class.get(type) |
77 | + if CounterClass: | ||
78 | + try: | ||
79 | + counter = CounterClass.objects.get(author=user.username) | ||
80 | + except CounterClass.DoesNotExist: | ||
81 | + count_types[trans(type)] = 0 | ||
82 | + else: | ||
83 | + count_types[trans(type)] = counter.count | ||
84 | + elif type == 'thread': | ||
85 | + count_types[trans(type)] = messages.count() | ||
86 | + else: | ||
87 | + sqs = SearchQuerySet() | ||
88 | + for filter_or in fields_or_lookup: | ||
89 | + sqs = sqs.filter_or(type=type, **filter_or) | ||
90 | + count_types[trans(type)] = sqs.count() | ||
73 | 91 | ||
74 | context['type_count'] = count_types | 92 | context['type_count'] = count_types |
75 | 93 | ||
@@ -85,7 +103,6 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): | @@ -85,7 +103,6 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): | ||
85 | context['emails'] = query[:10] | 103 | context['emails'] = query[:10] |
86 | 104 | ||
87 | count_by = 'thread__mailinglist__name' | 105 | count_by = 'thread__mailinglist__name' |
88 | - messages = Message.objects.filter(from_address__user__pk=user.pk) | ||
89 | context['list_activity'] = dict(messages.values_list(count_by)\ | 106 | context['list_activity'] = dict(messages.values_list(count_by)\ |
90 | .annotate(Count(count_by))\ | 107 | .annotate(Count(count_by))\ |
91 | .order_by(count_by)) | 108 | .order_by(count_by)) |
@@ -157,17 +174,20 @@ class ManageUserSubscriptionsView(UserProfileBaseMixin, DetailView): | @@ -157,17 +174,20 @@ class ManageUserSubscriptionsView(UserProfileBaseMixin, DetailView): | ||
157 | 174 | ||
158 | user = self.get_object() | 175 | user = self.get_object() |
159 | emails = user.emails.values_list('address', flat=True) | 176 | emails = user.emails.values_list('address', flat=True) |
160 | - all_lists = mailman.all_lists() | 177 | + all_lists = mailman.all_lists(description=True) |
161 | 178 | ||
162 | for email in emails: | 179 | for email in emails: |
163 | lists = [] | 180 | lists = [] |
164 | lists_for_address = mailman.address_lists(email) | 181 | lists_for_address = mailman.address_lists(email) |
165 | - for listname in all_lists: | 182 | + for listname, description in all_lists: |
166 | if listname in lists_for_address: | 183 | if listname in lists_for_address: |
167 | checked = True | 184 | checked = True |
168 | else: | 185 | else: |
169 | checked = False | 186 | checked = False |
170 | - lists.append((listname, checked)) | 187 | + lists.append(( |
188 | + {'listname': listname, 'description': description}, | ||
189 | + checked | ||
190 | + )) | ||
171 | 191 | ||
172 | context['membership'].update({email: lists}) | 192 | context['membership'].update({email: lists}) |
173 | 193 |
@@ -0,0 +1,121 @@ | @@ -0,0 +1,121 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | + | ||
3 | +from django.contrib.auth import get_user_model | ||
4 | + | ||
5 | +from tastypie import fields | ||
6 | +from tastypie.constants import ALL_WITH_RELATIONS, ALL | ||
7 | +from tastypie.resources import ModelResource | ||
8 | + | ||
9 | +from super_archives.models import Message, EmailAddress | ||
10 | +from proxy.models import Revision, Ticket, Wiki | ||
11 | + | ||
12 | + | ||
13 | +User = get_user_model() | ||
14 | + | ||
15 | + | ||
16 | +class UserResource(ModelResource): | ||
17 | + class Meta: | ||
18 | + queryset = User.objects.filter(is_active=True) | ||
19 | + resource_name = 'user' | ||
20 | + fields = ['username', 'institution', 'role', 'bio', 'first_name', | ||
21 | + 'last_name', 'email'] | ||
22 | + allowed_methods = ['get', ] | ||
23 | + filtering = { | ||
24 | + 'email': ('exact', ), | ||
25 | + 'username': ALL, | ||
26 | + 'institution': ALL, | ||
27 | + 'role': ALL, | ||
28 | + 'bio': ALL, | ||
29 | + } | ||
30 | + | ||
31 | + def dehydrate_email(self, bundle): | ||
32 | + return '' | ||
33 | + | ||
34 | + | ||
35 | +class EmailAddressResource(ModelResource): | ||
36 | + user = fields.ForeignKey(UserResource, 'user', full=False, null=True) | ||
37 | + | ||
38 | + class Meta: | ||
39 | + queryset = EmailAddress.objects.all() | ||
40 | + resource_name = 'emailaddress' | ||
41 | + excludes = ['md5', ] | ||
42 | + allowed_methods = ['get', ] | ||
43 | + filtering = { | ||
44 | + 'address': ('exact', ), | ||
45 | + 'user': ALL_WITH_RELATIONS, | ||
46 | + 'real_name': ALL, | ||
47 | + } | ||
48 | + | ||
49 | + def dehydrate_address(self, bundle): | ||
50 | + return '' | ||
51 | + | ||
52 | + | ||
53 | +class MessageResource(ModelResource): | ||
54 | + from_address = fields.ForeignKey(EmailAddressResource, 'from_address', | ||
55 | + full=False) | ||
56 | + | ||
57 | + class Meta: | ||
58 | + queryset = Message.objects.all() | ||
59 | + resource_name = 'message' | ||
60 | + excludes = ['spam', 'subject_clean', 'message_id'] | ||
61 | + filtering = { | ||
62 | + 'from_address': ALL_WITH_RELATIONS, | ||
63 | + 'subject': ALL, | ||
64 | + 'body': ALL, | ||
65 | + 'received_time': ALL, | ||
66 | + } | ||
67 | + | ||
68 | + | ||
69 | +class RevisionResource(ModelResource): | ||
70 | + class Meta: | ||
71 | + queryset = Revision.objects.all() | ||
72 | + resource_name = 'revision' | ||
73 | + excludes = ['collaborators', ] | ||
74 | + filtering = { | ||
75 | + 'key': ALL, | ||
76 | + 'rev': ALL, | ||
77 | + 'author': ALL, | ||
78 | + 'message': ALL, | ||
79 | + 'repository_name': ALL, | ||
80 | + 'created': ALL, | ||
81 | + } | ||
82 | + | ||
83 | + | ||
84 | +class TicketResource(ModelResource): | ||
85 | + class Meta: | ||
86 | + queryset = Ticket.objects.all() | ||
87 | + resource_name = 'ticket' | ||
88 | + excludes = ['collaborators', ] | ||
89 | + filtering = { | ||
90 | + 'id': ALL, | ||
91 | + 'summary': ALL, | ||
92 | + 'description': ALL, | ||
93 | + 'milestone': ALL, | ||
94 | + 'priority': ALL, | ||
95 | + 'component': ALL, | ||
96 | + 'version': ALL, | ||
97 | + 'severity': ALL, | ||
98 | + 'reporter': ALL, | ||
99 | + 'author': ALL, | ||
100 | + 'status': ALL, | ||
101 | + 'keywords': ALL, | ||
102 | + 'created': ALL, | ||
103 | + 'modified': ALL, | ||
104 | + 'modified_by': ALL, | ||
105 | + } | ||
106 | + | ||
107 | + | ||
108 | +class WikiResource(ModelResource): | ||
109 | + class Meta: | ||
110 | + queryset = Wiki.objects.all() | ||
111 | + resource_name = 'wiki' | ||
112 | + excludes = ['collaborators', ] | ||
113 | + filtering = { | ||
114 | + 'name': ALL, | ||
115 | + 'wiki_text': ALL, | ||
116 | + 'author': ALL, | ||
117 | + 'name': ALL, | ||
118 | + 'created': ALL, | ||
119 | + 'modified': ALL, | ||
120 | + 'modified_by': ALL, | ||
121 | + } |
src/api/urls.py
1 | +# -*- coding: utf-8 -*- | ||
1 | 2 | ||
2 | from django.conf.urls import patterns, include, url | 3 | from django.conf.urls import patterns, include, url |
3 | 4 | ||
5 | +from tastypie.api import Api | ||
6 | + | ||
7 | +from .resources import (UserResource, EmailAddressResource, MessageResource, | ||
8 | + RevisionResource, TicketResource, WikiResource) | ||
4 | from .views import VoteView | 9 | from .views import VoteView |
5 | 10 | ||
6 | 11 | ||
12 | +api = Api(api_name='v1') | ||
13 | +api.register(UserResource()) | ||
14 | +api.register(EmailAddressResource()) | ||
15 | +api.register(MessageResource()) | ||
16 | +api.register(RevisionResource()) | ||
17 | +api.register(TicketResource()) | ||
18 | +api.register(WikiResource()) | ||
19 | + | ||
20 | + | ||
7 | urlpatterns = patterns('', | 21 | urlpatterns = patterns('', |
8 | url(r'message/(?P<msg_id>\d+)/vote$', VoteView.as_view()), | 22 | url(r'message/(?P<msg_id>\d+)/vote$', VoteView.as_view()), |
23 | + | ||
24 | + # tastypie urls | ||
25 | + url(r'', include(api.urls)), | ||
9 | ) | 26 | ) |
src/badger/utils.py
@@ -2,16 +2,14 @@ | @@ -2,16 +2,14 @@ | ||
2 | 2 | ||
3 | from django.db.models import Count | 3 | from django.db.models import Count |
4 | 4 | ||
5 | -from proxy.models import Revision, Ticket, Wiki | 5 | +from proxy.models import (Revision, Ticket, Wiki, |
6 | + WikiCollabCount, TicketCollabCount) | ||
6 | from accounts.models import User | 7 | from accounts.models import User |
7 | 8 | ||
8 | 9 | ||
9 | def get_wiki_counters(): | 10 | def get_wiki_counters(): |
10 | - return { | ||
11 | - author: count for author, count in Wiki.objects.values_list( | ||
12 | - 'author' | ||
13 | - ).annotate(count=Count('author')) | ||
14 | - } | 11 | + return {author: count for author, count in |
12 | + WikiCollabCount.objects.values_list()} | ||
15 | 13 | ||
16 | 14 | ||
17 | def get_revision_counters(): | 15 | def get_revision_counters(): |
@@ -23,11 +21,8 @@ def get_revision_counters(): | @@ -23,11 +21,8 @@ def get_revision_counters(): | ||
23 | 21 | ||
24 | 22 | ||
25 | def get_ticket_counters(): | 23 | def get_ticket_counters(): |
26 | - return { | ||
27 | - author: count for author, count in Ticket.objects.values_list( | ||
28 | - 'author' | ||
29 | - ).annotate(count=Count('author')) | ||
30 | - } | 24 | + return {author: count for author, count in |
25 | + TicketCollabCount.objects.values_list()} | ||
31 | 26 | ||
32 | 27 | ||
33 | def get_users_counters(): | 28 | def get_users_counters(): |
src/colab/custom_settings.py
@@ -210,6 +210,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( | @@ -210,6 +210,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( | ||
210 | 'django_browserid.context_processors.browserid', | 210 | 'django_browserid.context_processors.browserid', |
211 | 'django_mobile.context_processors.is_mobile', | 211 | 'django_mobile.context_processors.is_mobile', |
212 | 'super_archives.context_processors.mailarchive', | 212 | 'super_archives.context_processors.mailarchive', |
213 | + 'home.context_processors.robots', | ||
213 | ) | 214 | ) |
214 | 215 | ||
215 | MIDDLEWARE_CLASSES = ( | 216 | MIDDLEWARE_CLASSES = ( |
@@ -294,6 +295,12 @@ REVPROXY_ADD_REMOTE_USER = True | @@ -294,6 +295,12 @@ REVPROXY_ADD_REMOTE_USER = True | ||
294 | CONVERSEJS_BOSH_SERVICE_URL = SITE_URL + '/http-bind' | 295 | CONVERSEJS_BOSH_SERVICE_URL = SITE_URL + '/http-bind' |
295 | 296 | ||
296 | CONVERSEJS_AUTO_REGISTER = 'mensageiro.interlegis.gov.br' | 297 | CONVERSEJS_AUTO_REGISTER = 'mensageiro.interlegis.gov.br' |
298 | +CONVERSEJS_ALLOW_CONTACT_REQUESTS = False | ||
299 | +CONVERSEJS_SHOW_ONLY_ONLINE_USERS = True | ||
300 | + | ||
301 | + | ||
302 | +# Tastypie settings | ||
303 | +TASTYPIE_DEFAULT_FORMATS = ['json', ] | ||
297 | 304 | ||
298 | 305 | ||
299 | try: | 306 | try: |
src/colab/local_settings-dev.py
src/colab/urls.py
@@ -12,6 +12,10 @@ admin.autodiscover() | @@ -12,6 +12,10 @@ admin.autodiscover() | ||
12 | 12 | ||
13 | urlpatterns = patterns('', | 13 | urlpatterns = patterns('', |
14 | url(r'^$', 'home.views.index', name='home'), | 14 | url(r'^$', 'home.views.index', name='home'), |
15 | + url(r'^robots.txt$', 'home.views.robots', name='robots'), | ||
16 | + | ||
17 | + url(r'^open-data/$', TemplateView.as_view(template_name='open-data.html'), | ||
18 | + name='opendata'), | ||
15 | 19 | ||
16 | url(r'^search/', include('search.urls')), | 20 | url(r'^search/', include('search.urls')), |
17 | url(r'^archives/', include('super_archives.urls')), | 21 | url(r'^archives/', include('super_archives.urls')), |
src/home/views.py
1 | 1 | ||
2 | from collections import OrderedDict | 2 | from collections import OrderedDict |
3 | 3 | ||
4 | +from django.conf import settings | ||
5 | +from django.core.cache import cache | ||
4 | from django.shortcuts import render | 6 | from django.shortcuts import render |
5 | -from django.utils import timezone | 7 | +from django.http import HttpResponse, Http404 |
6 | 8 | ||
7 | from search.utils import trans | 9 | from search.utils import trans |
8 | from haystack.query import SearchQuerySet | 10 | from haystack.query import SearchQuerySet |
9 | 11 | ||
12 | +from proxy.models import WikiCollabCount, TicketCollabCount | ||
10 | from super_archives.models import Thread | 13 | from super_archives.models import Thread |
11 | 14 | ||
12 | 15 | ||
@@ -17,13 +20,22 @@ def index(request): | @@ -17,13 +20,22 @@ def index(request): | ||
17 | latest_threads = Thread.objects.all()[:6] | 20 | latest_threads = Thread.objects.all()[:6] |
18 | hottest_threads = Thread.highest_score.from_haystack()[:6] | 21 | hottest_threads = Thread.highest_score.from_haystack()[:6] |
19 | 22 | ||
20 | - count_types = OrderedDict() | ||
21 | - six_months = timezone.now() - timezone.timedelta(days=180) | ||
22 | - for type in ['thread', 'ticket', 'wiki', 'changeset', 'attachment']: | ||
23 | - count_types[trans(type)] = SearchQuerySet().filter( | ||
24 | - type=type, | ||
25 | - modified__gte=six_months, | ||
26 | - ).count() | 23 | + count_types = cache.get('home_chart') |
24 | + if count_types is None: | ||
25 | + count_types = OrderedDict() | ||
26 | + for type in ['thread', 'changeset', 'attachment']: | ||
27 | + count_types[trans(type)] = SearchQuerySet().filter( | ||
28 | + type=type, | ||
29 | + ).count() | ||
30 | + | ||
31 | + count_types[trans('ticket')] = sum([ | ||
32 | + ticket.count for ticket in TicketCollabCount.objects.all() | ||
33 | + ]) | ||
34 | + | ||
35 | + count_types[trans('wiki')] = sum([ | ||
36 | + wiki.count for wiki in WikiCollabCount.objects.all() | ||
37 | + ]) | ||
38 | + cache.set('home_chart', count_types) | ||
27 | 39 | ||
28 | context = { | 40 | context = { |
29 | 'hottest_threads': hottest_threads[:6], | 41 | 'hottest_threads': hottest_threads[:6], |
@@ -34,3 +46,11 @@ def index(request): | @@ -34,3 +46,11 @@ def index(request): | ||
34 | )[:6], | 46 | )[:6], |
35 | } | 47 | } |
36 | return render(request, 'home.html', context) | 48 | return render(request, 'home.html', context) |
49 | + | ||
50 | + | ||
51 | +def robots(request): | ||
52 | + if getattr(settings, 'ROBOTS_NOINDEX', False): | ||
53 | + return HttpResponse('User-agent: *\nDisallow: /', | ||
54 | + content_type='text/plain') | ||
55 | + | ||
56 | + raise Http404 |
src/locale/pt_BR/LC_MESSAGES/django.mo
No preview for this file type
src/locale/pt_BR/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid "" | @@ -7,7 +7,7 @@ msgid "" | ||
7 | msgstr "" | 7 | msgstr "" |
8 | "Project-Id-Version: PACKAGE VERSION\n" | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
9 | "Report-Msgid-Bugs-To: \n" | 9 | "Report-Msgid-Bugs-To: \n" |
10 | -"POT-Creation-Date: 2013-11-26 13:17+0000\n" | 10 | +"POT-Creation-Date: 2013-12-19 11:20+0000\n" |
11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
13 | "Language-Team: LANGUAGE <LL@li.org>\n" | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
@@ -29,35 +29,52 @@ msgstr "Permissões" | @@ -29,35 +29,52 @@ msgstr "Permissões" | ||
29 | msgid "Important dates" | 29 | msgid "Important dates" |
30 | msgstr "Datas importantes" | 30 | msgstr "Datas importantes" |
31 | 31 | ||
32 | -#: accounts/forms.py:24 | 32 | +#: accounts/forms.py:25 |
33 | msgid "Social account does not exist" | 33 | msgid "Social account does not exist" |
34 | msgstr "Conta social não existe" | 34 | msgstr "Conta social não existe" |
35 | 35 | ||
36 | -#: accounts/forms.py:65 | 36 | +#: accounts/forms.py:56 accounts/templates/accounts/user_detail.html:34 |
37 | +msgid "Bio" | ||
38 | +msgstr "Bio" | ||
39 | + | ||
40 | +#: accounts/forms.py:57 | ||
41 | +msgid "Write something about you in 200 characters or less." | ||
42 | +msgstr "Escreva algo sobre você em 200 caracteres ou menos." | ||
43 | + | ||
44 | +#: accounts/forms.py:76 | ||
37 | msgid "Mailing lists" | 45 | msgid "Mailing lists" |
38 | msgstr "Listas de e-mail" | 46 | msgstr "Listas de e-mail" |
39 | 47 | ||
40 | -#: accounts/forms.py:72 | 48 | +#: accounts/forms.py:83 |
41 | msgid "Password" | 49 | msgid "Password" |
42 | msgstr "Senha" | 50 | msgstr "Senha" |
43 | 51 | ||
44 | -#: accounts/forms.py:74 | 52 | +#: accounts/forms.py:85 |
45 | msgid "Password confirmation" | 53 | msgid "Password confirmation" |
46 | msgstr "Confirmação de senha" | 54 | msgstr "Confirmação de senha" |
47 | 55 | ||
48 | -#: accounts/forms.py:76 | 56 | +#: accounts/forms.py:87 |
49 | msgid "Enter the same password as above, for verification." | 57 | msgid "Enter the same password as above, for verification." |
50 | msgstr "Digite a mesma senha que acima, para verificação." | 58 | msgstr "Digite a mesma senha que acima, para verificação." |
51 | 59 | ||
52 | -#: accounts/forms.py:94 | 60 | +#: accounts/forms.py:105 |
53 | msgid "Password mismatch" | 61 | msgid "Password mismatch" |
54 | msgstr "Senhas diferentes" | 62 | msgstr "Senhas diferentes" |
55 | 63 | ||
56 | -#: accounts/views.py:127 | 64 | +#: accounts/models.py:59 |
65 | +msgid "Required. 30 characters or fewer. Letters, digits and ./+/-/_ only." | ||
66 | +msgstr "" | ||
67 | +"Obrigatório. 30 caracteres ou menos. Letras, números e ./+/-/_ somente." | ||
68 | + | ||
69 | +#: accounts/models.py:64 | ||
70 | +msgid "Enter a valid username." | ||
71 | +msgstr "Insira um nome de usuário válido." | ||
72 | + | ||
73 | +#: accounts/views.py:144 | ||
57 | msgid "Your profile has been created!" | 74 | msgid "Your profile has been created!" |
58 | msgstr "Seu perfil foi criado!" | 75 | msgstr "Seu perfil foi criado!" |
59 | 76 | ||
60 | -#: accounts/views.py:128 | 77 | +#: accounts/views.py:145 |
61 | msgid "" | 78 | msgid "" |
62 | "You must login to validated your profile. Profiles not validated are deleted " | 79 | "You must login to validated your profile. Profiles not validated are deleted " |
63 | "in 24h." | 80 | "in 24h." |
@@ -65,12 +82,12 @@ msgstr "" | @@ -65,12 +82,12 @@ msgstr "" | ||
65 | "Você deve se logar para validar seu perfil. Perfis não validados serão " | 82 | "Você deve se logar para validar seu perfil. Perfis não validados serão " |
66 | "deletados em 24h." | 83 | "deletados em 24h." |
67 | 84 | ||
68 | -#: accounts/views.py:209 | 85 | +#: accounts/views.py:229 |
69 | msgid "Could not change your password. Please, try again later." | 86 | msgid "Could not change your password. Please, try again later." |
70 | msgstr "" | 87 | msgstr "" |
71 | "Não conseguimos alterar sua senha. Por favor, tente novamente mais tarde." | 88 | "Não conseguimos alterar sua senha. Por favor, tente novamente mais tarde." |
72 | 89 | ||
73 | -#: accounts/views.py:218 | 90 | +#: accounts/views.py:238 |
74 | msgid "You've changed your password successfully!" | 91 | msgid "You've changed your password successfully!" |
75 | msgstr "Senha alterada com sucesso!" | 92 | msgstr "Senha alterada com sucesso!" |
76 | 93 | ||
@@ -81,16 +98,16 @@ msgstr "%(count)s usuários deletados." | @@ -81,16 +98,16 @@ msgstr "%(count)s usuários deletados." | ||
81 | 98 | ||
82 | #: accounts/templates/accounts/change_password.html:8 | 99 | #: accounts/templates/accounts/change_password.html:8 |
83 | msgid "Change XMPP Client and SVN Password" | 100 | msgid "Change XMPP Client and SVN Password" |
84 | -msgstr "Trocar senha do SVN e do Mensageiro" | 101 | +msgstr "Trocar senha do Repositório e do Mensageiro" |
85 | 102 | ||
86 | #: accounts/templates/accounts/change_password.html:17 | 103 | #: accounts/templates/accounts/change_password.html:17 |
87 | -#: accounts/templates/accounts/user_update_form.html:191 | 104 | +#: accounts/templates/accounts/user_update_form.html:195 |
88 | msgid "Change Password" | 105 | msgid "Change Password" |
89 | msgstr "Trocar senha" | 106 | msgstr "Trocar senha" |
90 | 107 | ||
91 | #: accounts/templates/accounts/manage_subscriptions.html:6 | 108 | #: accounts/templates/accounts/manage_subscriptions.html:6 |
92 | -msgid "Mailing List Subscriptions" | ||
93 | -msgstr "Inscrições em listas de e-mails" | 109 | +msgid "Group Subscriptions" |
110 | +msgstr "Inscrições em grupos" | ||
94 | 111 | ||
95 | #: accounts/templates/accounts/manage_subscriptions.html:36 | 112 | #: accounts/templates/accounts/manage_subscriptions.html:36 |
96 | msgid "Update subscriptions" | 113 | msgid "Update subscriptions" |
@@ -113,65 +130,82 @@ msgid "Personal Information" | @@ -113,65 +130,82 @@ msgid "Personal Information" | ||
113 | msgstr "Informações pessoais" | 130 | msgstr "Informações pessoais" |
114 | 131 | ||
115 | #: accounts/templates/accounts/user_create_form.html:46 | 132 | #: accounts/templates/accounts/user_create_form.html:46 |
116 | -msgid "Subscribe to mail lists" | ||
117 | -msgstr "Inscreva-se para listas de e-mails" | 133 | +msgid "Subscribe to groups" |
134 | +msgstr "Inscreva-se nos grupos" | ||
118 | 135 | ||
119 | -#: accounts/templates/accounts/user_create_form.html:60 templates/base.html:97 | 136 | +#: accounts/templates/accounts/user_create_form.html:60 templates/base.html:98 |
120 | msgid "Register" | 137 | msgid "Register" |
121 | msgstr "Cadastre-se" | 138 | msgstr "Cadastre-se" |
122 | 139 | ||
123 | #: accounts/templates/accounts/user_detail.html:25 | 140 | #: accounts/templates/accounts/user_detail.html:25 |
124 | -msgid "profile" | ||
125 | -msgstr "perfil" | 141 | +msgid "edit profile" |
142 | +msgstr "editar perfil" | ||
126 | 143 | ||
127 | #: accounts/templates/accounts/user_detail.html:26 | 144 | #: accounts/templates/accounts/user_detail.html:26 |
128 | -msgid "list membership" | ||
129 | -msgstr "participação em listas" | 145 | +msgid "group membership" |
146 | +msgstr "Inscrições nos grupos" | ||
130 | 147 | ||
131 | -#: accounts/templates/accounts/user_detail.html:51 | 148 | +#: accounts/templates/accounts/user_detail.html:61 |
132 | msgid "Twitter account" | 149 | msgid "Twitter account" |
133 | msgstr "Conta Twitter" | 150 | msgstr "Conta Twitter" |
134 | 151 | ||
135 | -#: accounts/templates/accounts/user_detail.html:54 | 152 | +#: accounts/templates/accounts/user_detail.html:64 |
136 | msgid "Facebook account" | 153 | msgid "Facebook account" |
137 | msgstr "Conta Facebook" | 154 | msgstr "Conta Facebook" |
138 | 155 | ||
139 | -#: accounts/templates/accounts/user_detail.html:62 | 156 | +#: accounts/templates/accounts/user_detail.html:69 |
157 | +msgid "Google talk account" | ||
158 | +msgstr "Conta Google" | ||
159 | + | ||
160 | +#: accounts/templates/accounts/user_detail.html:73 | ||
161 | +msgid "Github account" | ||
162 | +msgstr "Conta Github" | ||
163 | + | ||
164 | +#: accounts/templates/accounts/user_detail.html:77 | ||
140 | msgid "Personal webpage" | 165 | msgid "Personal webpage" |
141 | msgstr "Página web pessoal" | 166 | msgstr "Página web pessoal" |
142 | 167 | ||
143 | -#: accounts/templates/accounts/user_detail.html:68 | ||
144 | -msgid "Subscribes: " | ||
145 | -msgstr "Inscrições: " | 168 | +#: accounts/templates/accounts/user_detail.html:83 |
169 | +msgid "Groups: " | ||
170 | +msgstr "Grupos: " | ||
146 | 171 | ||
147 | -#: accounts/templates/accounts/user_detail.html:81 | ||
148 | -msgid "Contributions by Area" | ||
149 | -msgstr "Contribuições por área" | 172 | +#: accounts/templates/accounts/user_detail.html:96 |
173 | +msgid "Contributions by Type" | ||
174 | +msgstr "Contribuições por tipo" | ||
150 | 175 | ||
151 | -#: accounts/templates/accounts/user_detail.html:93 | ||
152 | -msgid "Mailing list Participation" | ||
153 | -msgstr "Participação em listas de e-mail" | 176 | +#: accounts/templates/accounts/user_detail.html:108 |
177 | +msgid "Participation by Group" | ||
178 | +msgstr "Participação por grupo" | ||
154 | 179 | ||
155 | -#: accounts/templates/accounts/user_detail.html:106 badger/models.py:71 | 180 | +#: accounts/templates/accounts/user_detail.html:121 badger/models.py:70 |
156 | msgid "Badges" | 181 | msgid "Badges" |
157 | msgstr "Medalhas" | 182 | msgstr "Medalhas" |
158 | 183 | ||
159 | -#: accounts/templates/accounts/user_detail.html:125 | 184 | +#: accounts/templates/accounts/user_detail.html:140 |
160 | msgid "Latest posted" | 185 | msgid "Latest posted" |
161 | msgstr "Últimas postagens" | 186 | msgstr "Últimas postagens" |
162 | 187 | ||
163 | -#: accounts/templates/accounts/user_detail.html:130 | 188 | +#: accounts/templates/accounts/user_detail.html:145 |
164 | msgid "There are no posts by this user so far." | 189 | msgid "There are no posts by this user so far." |
165 | msgstr "Não há posts deste usuário até agora." | 190 | msgstr "Não há posts deste usuário até agora." |
166 | 191 | ||
167 | -#: accounts/templates/accounts/user_detail.html:136 badger/models.py:24 | 192 | +#: accounts/templates/accounts/user_detail.html:149 templates/home.html:57 |
193 | +#: templates/home.html.py:76 | ||
194 | +msgid "View more discussions..." | ||
195 | +msgstr "Ver mais discussões..." | ||
196 | + | ||
197 | +#: accounts/templates/accounts/user_detail.html:155 badger/models.py:23 | ||
168 | msgid "Contributions" | 198 | msgid "Contributions" |
169 | msgstr "Contribuições" | 199 | msgstr "Contribuições" |
170 | 200 | ||
171 | -#: accounts/templates/accounts/user_detail.html:141 | 201 | +#: accounts/templates/accounts/user_detail.html:160 |
172 | msgid "No contributions of this user so far." | 202 | msgid "No contributions of this user so far." |
173 | msgstr "Não há posts deste usuário até agora." | 203 | msgstr "Não há posts deste usuário até agora." |
174 | 204 | ||
205 | +#: accounts/templates/accounts/user_detail.html:164 | ||
206 | +msgid "View more contributions..." | ||
207 | +msgstr "Ver mais colaborações..." | ||
208 | + | ||
175 | #: accounts/templates/accounts/user_update_form.html:65 | 209 | #: accounts/templates/accounts/user_update_form.html:65 |
176 | msgid "We sent a verification email to " | 210 | msgid "We sent a verification email to " |
177 | msgstr "Enviamos um email de verificação para " | 211 | msgstr "Enviamos um email de verificação para " |
@@ -229,96 +263,115 @@ msgstr "Adicionar outro endereço de e-mail" | @@ -229,96 +263,115 @@ msgstr "Adicionar outro endereço de e-mail" | ||
229 | msgid "Add" | 263 | msgid "Add" |
230 | msgstr "Adicionar" | 264 | msgstr "Adicionar" |
231 | 265 | ||
232 | -#: accounts/templates/accounts/user_update_form.html:185 | ||
233 | -msgid "Change SVN and XMPP Client password" | ||
234 | -msgstr "Trocar a senha do SVN e do Mensageiro" | 266 | +#: accounts/templates/accounts/user_update_form.html:188 |
267 | +msgid "" | ||
268 | +"Change <a href=\"http://repositorio.interlegis.gov.br/\">SVN</a> and <a href=" | ||
269 | +"\"http://mensageiro.interlegis.gov.br/\">XMPP Client</a> password" | ||
270 | +msgstr "" | ||
271 | +"Trocar a senha do <a href=\"http://repositorio.interlegis.gov.br/" | ||
272 | +"\">Repositório</a> e do <a href=\"http://mensageiro.interlegis.gov.br/" | ||
273 | +"\">Mensageiro</a>" | ||
235 | 274 | ||
236 | -#: accounts/templates/accounts/user_update_form.html:189 | 275 | +#: accounts/templates/accounts/user_update_form.html:193 |
237 | msgid "" | 276 | msgid "" |
238 | -"You don't need to change this password. Change it only if you really know " | ||
239 | -"what you are doing." | 277 | +"This feature is available only for who needs to change the password for some " |
278 | +"reason as having an old user with the same username, forgot your password to " | ||
279 | +"commit, usage of other XMPP Client for connection. Usually, you won't need " | ||
280 | +"to change this password. Only change it if you are sure about what you are " | ||
281 | +"doing." | ||
240 | msgstr "" | 282 | msgstr "" |
241 | -"Você não precisa trocar essa senha. Troque-a somente se tem certeza do que " | ||
242 | -"está fazendo." | 283 | +"Este recurso está disponível para quem precisa trocar a senha por algum " |
284 | +"motivo como ter um usuário antigo com mesmo nome de usuário, esqueceu da " | ||
285 | +"senha antiga para commit, uso de outro cliente XMPP para conexão. " | ||
286 | +"Normalmente, você não terá que trocar essa senha. Somente troque essa senha " | ||
287 | +"se tiver certeza do que está fazendo." | ||
243 | 288 | ||
244 | -#: accounts/templates/accounts/user_update_form.html:199 | 289 | +#: accounts/templates/accounts/user_update_form.html:203 |
245 | msgid "Update" | 290 | msgid "Update" |
246 | msgstr "Atualizar" | 291 | msgstr "Atualizar" |
247 | 292 | ||
248 | -#: badger/models.py:13 | 293 | +#: badger/forms.py:19 badger/models.py:40 colab/custom_settings.py:53 |
294 | +msgid "Image" | ||
295 | +msgstr "Imagem" | ||
296 | + | ||
297 | +#: badger/forms.py:30 | ||
298 | +msgid "You must add an Image" | ||
299 | +msgstr "Você deve adicionar uma imagem" | ||
300 | + | ||
301 | +#: badger/models.py:12 | ||
249 | msgid "Greater than or equal" | 302 | msgid "Greater than or equal" |
250 | msgstr "Maior que ou igual" | 303 | msgstr "Maior que ou igual" |
251 | 304 | ||
252 | -#: badger/models.py:14 | 305 | +#: badger/models.py:13 |
253 | msgid "less than or equal" | 306 | msgid "less than or equal" |
254 | msgstr "menor que ou igual" | 307 | msgstr "menor que ou igual" |
255 | 308 | ||
256 | -#: badger/models.py:15 | 309 | +#: badger/models.py:14 |
257 | msgid "Equal" | 310 | msgid "Equal" |
258 | msgstr "Igual" | 311 | msgstr "Igual" |
259 | 312 | ||
260 | -#: badger/models.py:16 | 313 | +#: badger/models.py:15 |
261 | msgid "Biggest" | 314 | msgid "Biggest" |
262 | msgstr "Maior" | 315 | msgstr "Maior" |
263 | 316 | ||
264 | -#: badger/models.py:19 | 317 | +#: badger/models.py:18 |
265 | msgid "Automatically" | 318 | msgid "Automatically" |
266 | msgstr "Automaticamente" | 319 | msgstr "Automaticamente" |
267 | 320 | ||
268 | -#: badger/models.py:20 | 321 | +#: badger/models.py:19 |
269 | msgid "Manual" | 322 | msgid "Manual" |
270 | msgstr "Manual" | 323 | msgstr "Manual" |
271 | 324 | ||
272 | -#: badger/models.py:23 super_archives/models.py:258 | 325 | +#: badger/models.py:22 super_archives/models.py:258 |
273 | msgid "Messages" | 326 | msgid "Messages" |
274 | msgstr "Mensagens" | 327 | msgstr "Mensagens" |
275 | 328 | ||
276 | -#: badger/models.py:25 | 329 | +#: badger/models.py:24 |
277 | msgid "Wikis" | 330 | msgid "Wikis" |
278 | msgstr "Wikis" | 331 | msgstr "Wikis" |
279 | 332 | ||
280 | -#: badger/models.py:26 | 333 | +#: badger/models.py:25 |
281 | msgid "Revisions" | 334 | msgid "Revisions" |
282 | msgstr "Conjunto de mudanças" | 335 | msgstr "Conjunto de mudanças" |
283 | 336 | ||
284 | -#: badger/models.py:27 search/views.py:42 | 337 | +#: badger/models.py:26 search/views.py:42 |
285 | #: search/templates/search/includes/search_filters.html:124 | 338 | #: search/templates/search/includes/search_filters.html:124 |
286 | msgid "Ticket" | 339 | msgid "Ticket" |
287 | msgstr "Tíquetes" | 340 | msgstr "Tíquetes" |
288 | 341 | ||
289 | -#: badger/models.py:37 | 342 | +#: badger/models.py:36 |
290 | msgid "Title" | 343 | msgid "Title" |
291 | msgstr "Título" | 344 | msgstr "Título" |
292 | 345 | ||
293 | -#: badger/models.py:39 | 346 | +#: badger/models.py:38 |
294 | msgid "Description" | 347 | msgid "Description" |
295 | msgstr "Descrição" | 348 | msgstr "Descrição" |
296 | 349 | ||
297 | -#: badger/models.py:42 search/forms.py:18 | 350 | +#: badger/models.py:41 search/forms.py:18 |
298 | msgid "Type" | 351 | msgid "Type" |
299 | msgstr "Tipo" | 352 | msgstr "Tipo" |
300 | 353 | ||
301 | -#: badger/models.py:44 | 354 | +#: badger/models.py:43 |
302 | msgid "User attribute" | 355 | msgid "User attribute" |
303 | msgstr "Atributo do usuário" | 356 | msgstr "Atributo do usuário" |
304 | 357 | ||
305 | -#: badger/models.py:50 | 358 | +#: badger/models.py:49 |
306 | msgid "Comparison" | 359 | msgid "Comparison" |
307 | msgstr "Comparação" | 360 | msgstr "Comparação" |
308 | 361 | ||
309 | -#: badger/models.py:57 | 362 | +#: badger/models.py:56 |
310 | msgid "Value" | 363 | msgid "Value" |
311 | msgstr "Valor" | 364 | msgstr "Valor" |
312 | 365 | ||
313 | -#: badger/models.py:63 | 366 | +#: badger/models.py:62 |
314 | msgid "Awardees" | 367 | msgid "Awardees" |
315 | msgstr "Premiados" | 368 | msgstr "Premiados" |
316 | 369 | ||
317 | -#: badger/models.py:67 | 370 | +#: badger/models.py:66 |
318 | msgid "Order" | 371 | msgid "Order" |
319 | msgstr "Ordem" | 372 | msgstr "Ordem" |
320 | 373 | ||
321 | -#: badger/models.py:70 | 374 | +#: badger/models.py:69 |
322 | msgid "Badge" | 375 | msgid "Badge" |
323 | msgstr "Medalha" | 376 | msgstr "Medalha" |
324 | 377 | ||
@@ -362,19 +415,15 @@ msgstr "Código" | @@ -362,19 +415,15 @@ msgstr "Código" | ||
362 | msgid "Compressed" | 415 | msgid "Compressed" |
363 | msgstr "Compactado" | 416 | msgstr "Compactado" |
364 | 417 | ||
365 | -#: colab/custom_settings.py:53 | ||
366 | -msgid "Image" | ||
367 | -msgstr "Imagem" | ||
368 | - | ||
369 | #: colab/custom_settings.py:55 | 418 | #: colab/custom_settings.py:55 |
370 | msgid "Spreadsheet" | 419 | msgid "Spreadsheet" |
371 | msgstr "Planilha" | 420 | msgstr "Planilha" |
372 | 421 | ||
373 | -#: colab/custom_settings.py:263 | 422 | +#: colab/custom_settings.py:265 |
374 | msgid "Planet Colab" | 423 | msgid "Planet Colab" |
375 | msgstr "" | 424 | msgstr "" |
376 | 425 | ||
377 | -#: colab/custom_settings.py:264 | 426 | +#: colab/custom_settings.py:266 |
378 | msgid "Colab blog aggregator" | 427 | msgid "Colab blog aggregator" |
379 | msgstr "Agregador de blog Colab" | 428 | msgstr "Agregador de blog Colab" |
380 | 429 | ||
@@ -390,9 +439,9 @@ msgstr "em" | @@ -390,9 +439,9 @@ msgstr "em" | ||
390 | msgid "Read original" | 439 | msgid "Read original" |
391 | msgstr "Leia o original" | 440 | msgstr "Leia o original" |
392 | 441 | ||
393 | -#: planet/templates/feedzilla/base.html:5 templates/base.html:75 | ||
394 | -msgid "Planet" | ||
395 | -msgstr "" | 442 | +#: planet/templates/feedzilla/base.html:5 |
443 | +msgid "Planet - Community Blogs" | ||
444 | +msgstr "Planet - Blogs da comunidade" | ||
396 | 445 | ||
397 | #: planet/templates/feedzilla/base.html:15 | 446 | #: planet/templates/feedzilla/base.html:15 |
398 | msgid "Tags" | 447 | msgid "Tags" |
@@ -402,7 +451,7 @@ msgstr "Etiquetas" | @@ -402,7 +451,7 @@ msgstr "Etiquetas" | ||
402 | msgid "Source Blogs" | 451 | msgid "Source Blogs" |
403 | msgstr "Blogs de origem" | 452 | msgstr "Blogs de origem" |
404 | 453 | ||
405 | -#: planet/templates/feedzilla/base.html:22 | 454 | +#: planet/templates/feedzilla/base.html:23 |
406 | #: planet/templates/feedzilla/submit_blog.html:5 | 455 | #: planet/templates/feedzilla/submit_blog.html:5 |
407 | msgid "Submit a blog" | 456 | msgid "Submit a blog" |
408 | msgstr "Sugerir um blog" | 457 | msgstr "Sugerir um blog" |
@@ -456,7 +505,7 @@ msgid "Latest collaborations" | @@ -456,7 +505,7 @@ msgid "Latest collaborations" | ||
456 | msgstr "Últimas colaborações" | 505 | msgstr "Últimas colaborações" |
457 | 506 | ||
458 | #: search/forms.py:16 search/templates/search/search.html:41 | 507 | #: search/forms.py:16 search/templates/search/search.html:41 |
459 | -#: templates/base.html:91 | 508 | +#: templates/base.html:92 |
460 | msgid "Search" | 509 | msgid "Search" |
461 | msgstr "Busca" | 510 | msgstr "Busca" |
462 | 511 | ||
@@ -465,89 +514,93 @@ msgstr "Busca" | @@ -465,89 +514,93 @@ msgstr "Busca" | ||
465 | msgid "Author" | 514 | msgid "Author" |
466 | msgstr "Autor" | 515 | msgstr "Autor" |
467 | 516 | ||
468 | -#: search/forms.py:21 search/views.py:70 | 517 | +#: search/forms.py:20 |
518 | +msgid "Modified by" | ||
519 | +msgstr "Modificado por" | ||
520 | + | ||
521 | +#: search/forms.py:22 search/views.py:70 | ||
469 | msgid "Status" | 522 | msgid "Status" |
470 | msgstr "" | 523 | msgstr "" |
471 | 524 | ||
472 | -#: search/forms.py:25 search/views.py:36 | 525 | +#: search/forms.py:26 search/views.py:36 |
473 | msgid "Mailinglist" | 526 | msgid "Mailinglist" |
474 | msgstr "Lista de email" | 527 | msgstr "Lista de email" |
475 | 528 | ||
476 | -#: search/forms.py:29 search/views.py:46 | 529 | +#: search/forms.py:30 search/views.py:46 |
477 | msgid "Milestone" | 530 | msgid "Milestone" |
478 | msgstr "Etapa" | 531 | msgstr "Etapa" |
479 | 532 | ||
480 | -#: search/forms.py:30 search/views.py:51 | 533 | +#: search/forms.py:31 search/views.py:51 |
481 | msgid "Priority" | 534 | msgid "Priority" |
482 | msgstr "Prioridade" | 535 | msgstr "Prioridade" |
483 | 536 | ||
484 | -#: search/forms.py:31 search/views.py:56 | 537 | +#: search/forms.py:32 search/views.py:56 |
485 | msgid "Component" | 538 | msgid "Component" |
486 | msgstr "Componente" | 539 | msgstr "Componente" |
487 | 540 | ||
488 | -#: search/forms.py:32 search/views.py:61 | 541 | +#: search/forms.py:33 search/views.py:61 |
489 | msgid "Severity" | 542 | msgid "Severity" |
490 | msgstr "Seriedade" | 543 | msgstr "Seriedade" |
491 | 544 | ||
492 | -#: search/forms.py:33 search/views.py:66 | 545 | +#: search/forms.py:34 search/views.py:66 |
493 | msgid "Reporter" | 546 | msgid "Reporter" |
494 | msgstr "Relator" | 547 | msgstr "Relator" |
495 | 548 | ||
496 | -#: search/forms.py:34 search/views.py:73 | 549 | +#: search/forms.py:35 search/views.py:73 |
497 | msgid "Keywords" | 550 | msgid "Keywords" |
498 | msgstr "Palavras chaves" | 551 | msgstr "Palavras chaves" |
499 | 552 | ||
500 | -#: search/forms.py:35 search/views.py:25 search/views.py:78 | 553 | +#: search/forms.py:36 search/views.py:25 search/views.py:78 |
501 | msgid "Collaborators" | 554 | msgid "Collaborators" |
502 | msgstr "Colaboradores" | 555 | msgstr "Colaboradores" |
503 | 556 | ||
504 | -#: search/forms.py:36 search/views.py:89 | 557 | +#: search/forms.py:37 search/views.py:89 |
505 | msgid "Repository" | 558 | msgid "Repository" |
506 | msgstr "Repositório" | 559 | msgstr "Repositório" |
507 | 560 | ||
508 | -#: search/forms.py:37 search/views.py:99 | 561 | +#: search/forms.py:38 search/views.py:99 |
509 | msgid "Username" | 562 | msgid "Username" |
510 | msgstr "Usuário" | 563 | msgstr "Usuário" |
511 | 564 | ||
512 | -#: search/forms.py:38 search/views.py:102 | 565 | +#: search/forms.py:39 search/views.py:102 |
513 | msgid "Name" | 566 | msgid "Name" |
514 | msgstr "Nome" | 567 | msgstr "Nome" |
515 | 568 | ||
516 | -#: search/forms.py:39 search/views.py:105 | 569 | +#: search/forms.py:40 search/views.py:105 |
517 | msgid "Institution" | 570 | msgid "Institution" |
518 | msgstr "Instituição" | 571 | msgstr "Instituição" |
519 | 572 | ||
520 | -#: search/forms.py:40 search/views.py:108 | 573 | +#: search/forms.py:41 search/views.py:108 |
521 | msgid "Role" | 574 | msgid "Role" |
522 | msgstr "Cargo" | 575 | msgstr "Cargo" |
523 | 576 | ||
524 | -#: search/forms.py:41 search/templates/search/includes/search_filters.html:151 | 577 | +#: search/forms.py:42 search/templates/search/includes/search_filters.html:151 |
525 | #: search/templates/search/includes/search_filters.html:153 | 578 | #: search/templates/search/includes/search_filters.html:153 |
526 | #: search/templates/search/includes/search_filters.html:185 | 579 | #: search/templates/search/includes/search_filters.html:185 |
527 | #: search/templates/search/includes/search_filters.html:186 | 580 | #: search/templates/search/includes/search_filters.html:186 |
528 | msgid "Since" | 581 | msgid "Since" |
529 | msgstr "Desde" | 582 | msgstr "Desde" |
530 | 583 | ||
531 | -#: search/forms.py:42 search/templates/search/includes/search_filters.html:160 | 584 | +#: search/forms.py:43 search/templates/search/includes/search_filters.html:160 |
532 | #: search/templates/search/includes/search_filters.html:162 | 585 | #: search/templates/search/includes/search_filters.html:162 |
533 | #: search/templates/search/includes/search_filters.html:189 | 586 | #: search/templates/search/includes/search_filters.html:189 |
534 | #: search/templates/search/includes/search_filters.html:190 | 587 | #: search/templates/search/includes/search_filters.html:190 |
535 | msgid "Until" | 588 | msgid "Until" |
536 | msgstr "Até" | 589 | msgstr "Até" |
537 | 590 | ||
538 | -#: search/forms.py:43 search/views.py:116 | 591 | +#: search/forms.py:44 search/views.py:116 |
539 | msgid "Filename" | 592 | msgid "Filename" |
540 | msgstr "Nome do arquivo" | 593 | msgstr "Nome do arquivo" |
541 | 594 | ||
542 | -#: search/forms.py:44 search/views.py:122 | 595 | +#: search/forms.py:45 search/views.py:122 |
543 | msgid "Used by" | 596 | msgid "Used by" |
544 | msgstr "Usado por" | 597 | msgstr "Usado por" |
545 | 598 | ||
546 | -#: search/forms.py:45 search/views.py:125 | 599 | +#: search/forms.py:46 search/views.py:125 |
547 | msgid "File type" | 600 | msgid "File type" |
548 | msgstr "Tipo do arquivo" | 601 | msgstr "Tipo do arquivo" |
549 | 602 | ||
550 | -#: search/forms.py:46 search/views.py:128 | 603 | +#: search/forms.py:47 search/views.py:128 |
551 | msgid "Size" | 604 | msgid "Size" |
552 | msgstr "Tamanho" | 605 | msgstr "Tamanho" |
553 | 606 | ||
@@ -627,7 +680,9 @@ msgstr "Ordenar por" | @@ -627,7 +680,9 @@ msgstr "Ordenar por" | ||
627 | msgid "Types" | 680 | msgid "Types" |
628 | msgstr "Tipos" | 681 | msgstr "Tipos" |
629 | 682 | ||
630 | -#: super_archives/models.py:62 super_archives/templates/message-thread.html:4 | 683 | +#: super_archives/models.py:62 |
684 | +#: super_archives/templates/message-preview.html:62 | ||
685 | +#: super_archives/templates/message-thread.html:4 | ||
631 | msgid "Anonymous" | 686 | msgid "Anonymous" |
632 | msgstr "Anônimo" | 687 | msgstr "Anônimo" |
633 | 688 | ||
@@ -683,35 +738,37 @@ msgstr "Por favor, digite o corpo da mensagem" | @@ -683,35 +738,37 @@ msgstr "Por favor, digite o corpo da mensagem" | ||
683 | msgid "Message" | 738 | msgid "Message" |
684 | msgstr "Mensagem" | 739 | msgstr "Mensagem" |
685 | 740 | ||
686 | -#: super_archives/views.py:90 | 741 | +#: super_archives/views.py:92 |
687 | msgid "Error trying to connect to Mailman API" | 742 | msgid "Error trying to connect to Mailman API" |
688 | msgstr "Erro na conexão com a API do Mailman" | 743 | msgstr "Erro na conexão com a API do Mailman" |
689 | 744 | ||
690 | -#: super_archives/views.py:93 | 745 | +#: super_archives/views.py:95 |
691 | msgid "Timeout trying to connect to Mailman API" | 746 | msgid "Timeout trying to connect to Mailman API" |
692 | msgstr "Tempo de espera esgotado na conexão com a API do Mailman" | 747 | msgstr "Tempo de espera esgotado na conexão com a API do Mailman" |
693 | 748 | ||
694 | -#: super_archives/views.py:96 | 749 | +#: super_archives/views.py:99 |
695 | msgid "" | 750 | msgid "" |
696 | -"Your message was sent. It may take some minutes before it's delivered. Why " | ||
697 | -"don't you breath some fresh air in the meanwhile?" | 751 | +"Your message was sent to this topic. It may take some minutes before it's " |
752 | +"delivered by email to the group. Why don't you breath some fresh air in the " | ||
753 | +"meanwhile?" | ||
698 | msgstr "" | 754 | msgstr "" |
699 | -"Sua mensagem foi enviada. Pode levar alguns minutos antes de ser entregue. " | ||
700 | -"Por quê você respira um ar fresco enquanto isso?" | 755 | +"Sua mensagem foi enviada para esse tópico. Pode levar alguns minutos até ser " |
756 | +"entregue via e-mail para o grupo. Por quê você não respira um ar fresco " | ||
757 | +"enquanto isso?" | ||
701 | 758 | ||
702 | -#: super_archives/views.py:104 | 759 | +#: super_archives/views.py:108 |
703 | msgid "You cannot send an empty email" | 760 | msgid "You cannot send an empty email" |
704 | msgstr "Você não pode enviar um e-mail vazio" | 761 | msgstr "Você não pode enviar um e-mail vazio" |
705 | 762 | ||
706 | -#: super_archives/views.py:106 | 763 | +#: super_archives/views.py:110 |
707 | msgid "Mailing list does not exist" | 764 | msgid "Mailing list does not exist" |
708 | msgstr "Lista de e-mail não existe" | 765 | msgstr "Lista de e-mail não existe" |
709 | 766 | ||
710 | -#: super_archives/views.py:108 | 767 | +#: super_archives/views.py:112 |
711 | msgid "Unknown error trying to connect to Mailman API" | 768 | msgid "Unknown error trying to connect to Mailman API" |
712 | msgstr "Erro desconhecido na conexão com a API do Mailman" | 769 | msgstr "Erro desconhecido na conexão com a API do Mailman" |
713 | 770 | ||
714 | -#: super_archives/views.py:143 | 771 | +#: super_archives/views.py:151 |
715 | msgid "" | 772 | msgid "" |
716 | "The email address you are trying to verify either has already been verified " | 773 | "The email address you are trying to verify either has already been verified " |
717 | "or does not exist." | 774 | "or does not exist." |
@@ -719,7 +776,7 @@ msgstr "" | @@ -719,7 +776,7 @@ msgstr "" | ||
719 | "O endereço de e-mail que você está tentando verificar ou já foi verificado " | 776 | "O endereço de e-mail que você está tentando verificar ou já foi verificado " |
720 | "ou não existe." | 777 | "ou não existe." |
721 | 778 | ||
722 | -#: super_archives/views.py:154 | 779 | +#: super_archives/views.py:162 |
723 | msgid "" | 780 | msgid "" |
724 | "The email address you are trying to verify is already an active email " | 781 | "The email address you are trying to verify is already an active email " |
725 | "address." | 782 | "address." |
@@ -727,73 +784,78 @@ msgstr "" | @@ -727,73 +784,78 @@ msgstr "" | ||
727 | "O endereço de e-mail que você está tentando verificar já é um endereço de e-" | 784 | "O endereço de e-mail que você está tentando verificar já é um endereço de e-" |
728 | "mail ativo" | 785 | "mail ativo" |
729 | 786 | ||
730 | -#: super_archives/views.py:164 | 787 | +#: super_archives/views.py:172 |
731 | msgid "Email address verified!" | 788 | msgid "Email address verified!" |
732 | msgstr "Endereço de e-mail verificado!" | 789 | msgstr "Endereço de e-mail verificado!" |
733 | 790 | ||
791 | +#: super_archives/management/commands/import_emails.py:205 | ||
792 | +msgid "[Colab] Warning - Email sent with a blank subject." | ||
793 | +msgstr "[Colab] Aviso - E-mail enviado com o campo assunto em branco." | ||
794 | + | ||
734 | #: super_archives/templates/message-preview.html:42 | 795 | #: super_archives/templates/message-preview.html:42 |
796 | +#: super_archives/templates/message-preview.html:62 | ||
735 | msgid "by" | 797 | msgid "by" |
736 | msgstr "por" | 798 | msgstr "por" |
737 | 799 | ||
738 | -#: super_archives/templates/message-preview.html:57 | ||
739 | -#: super_archives/templates/message-thread.html:157 | 800 | +#: super_archives/templates/message-preview.html:65 |
801 | +#: super_archives/templates/message-thread.html:161 | ||
740 | msgid "ago" | 802 | msgid "ago" |
741 | msgstr "atrás" | 803 | msgstr "atrás" |
742 | 804 | ||
743 | -#: super_archives/templates/message-thread.html:33 | 805 | +#: super_archives/templates/message-thread.html:35 |
744 | msgid "You must login before voting." | 806 | msgid "You must login before voting." |
745 | msgstr "Você deve estar logado antes de votar." | 807 | msgstr "Você deve estar logado antes de votar." |
746 | 808 | ||
747 | -#: super_archives/templates/message-thread.html:128 | 809 | +#: super_archives/templates/message-thread.html:132 |
748 | msgid "Order by" | 810 | msgid "Order by" |
749 | msgstr "Ordernar por" | 811 | msgstr "Ordernar por" |
750 | 812 | ||
751 | -#: super_archives/templates/message-thread.html:132 | 813 | +#: super_archives/templates/message-thread.html:136 |
752 | msgid "Votes" | 814 | msgid "Votes" |
753 | msgstr "Votos" | 815 | msgstr "Votos" |
754 | 816 | ||
755 | -#: super_archives/templates/message-thread.html:136 | 817 | +#: super_archives/templates/message-thread.html:140 |
756 | msgid "Date" | 818 | msgid "Date" |
757 | msgstr "Data" | 819 | msgstr "Data" |
758 | 820 | ||
759 | -#: super_archives/templates/message-thread.html:141 | 821 | +#: super_archives/templates/message-thread.html:145 |
760 | msgid "Related:" | 822 | msgid "Related:" |
761 | msgstr "Relacionado:" | 823 | msgstr "Relacionado:" |
762 | 824 | ||
763 | -#: super_archives/templates/message-thread.html:152 | 825 | +#: super_archives/templates/message-thread.html:156 |
764 | msgid "Statistics:" | 826 | msgid "Statistics:" |
765 | msgstr "Estátisticas:" | 827 | msgstr "Estátisticas:" |
766 | 828 | ||
767 | -#: super_archives/templates/message-thread.html:156 | 829 | +#: super_archives/templates/message-thread.html:160 |
768 | msgid "started at" | 830 | msgid "started at" |
769 | msgstr "começou às" | 831 | msgstr "começou às" |
770 | 832 | ||
771 | -#: super_archives/templates/message-thread.html:162 | 833 | +#: super_archives/templates/message-thread.html:166 |
772 | msgid "viewed" | 834 | msgid "viewed" |
773 | msgstr "visualizado" | 835 | msgstr "visualizado" |
774 | 836 | ||
775 | -#: super_archives/templates/message-thread.html:163 | ||
776 | -#: super_archives/templates/message-thread.html:168 | ||
777 | -#: super_archives/templates/message-thread.html:173 | 837 | +#: super_archives/templates/message-thread.html:167 |
838 | +#: super_archives/templates/message-thread.html:172 | ||
839 | +#: super_archives/templates/message-thread.html:177 | ||
778 | msgid "times" | 840 | msgid "times" |
779 | msgstr "vezes" | 841 | msgstr "vezes" |
780 | 842 | ||
781 | -#: super_archives/templates/message-thread.html:167 | 843 | +#: super_archives/templates/message-thread.html:171 |
782 | msgid "answered" | 844 | msgid "answered" |
783 | msgstr "respondido" | 845 | msgstr "respondido" |
784 | 846 | ||
785 | -#: super_archives/templates/message-thread.html:172 | 847 | +#: super_archives/templates/message-thread.html:176 |
786 | msgid "voted" | 848 | msgid "voted" |
787 | msgstr "votado" | 849 | msgstr "votado" |
788 | 850 | ||
789 | -#: super_archives/templates/message-thread.html:178 | 851 | +#: super_archives/templates/message-thread.html:182 |
790 | msgid "Tags:" | 852 | msgid "Tags:" |
791 | msgstr "Etiquetas:" | 853 | msgstr "Etiquetas:" |
792 | 854 | ||
793 | #: super_archives/templates/superarchives/thread-dashboard.html:5 | 855 | #: super_archives/templates/superarchives/thread-dashboard.html:5 |
794 | -#: templates/base.html:72 | ||
795 | -msgid "Discussions" | ||
796 | -msgstr "Discussões" | 856 | +#: templates/base.html:73 |
857 | +msgid "Groups" | ||
858 | +msgstr "Grupos" | ||
797 | 859 | ||
798 | #: super_archives/templates/superarchives/thread-dashboard.html:15 | 860 | #: super_archives/templates/superarchives/thread-dashboard.html:15 |
799 | msgid "latest" | 861 | msgid "latest" |
@@ -808,6 +870,33 @@ msgstr "mais..." | @@ -808,6 +870,33 @@ msgstr "mais..." | ||
808 | msgid "most relevant" | 870 | msgid "most relevant" |
809 | msgstr "mais relevantes" | 871 | msgstr "mais relevantes" |
810 | 872 | ||
873 | +#: super_archives/templates/superarchives/emails/email_blank_subject.txt:2 | ||
874 | +msgid "Hello" | ||
875 | +msgstr "Olá" | ||
876 | + | ||
877 | +#: super_archives/templates/superarchives/emails/email_blank_subject.txt:3 | ||
878 | +#, python-format | ||
879 | +msgid "" | ||
880 | +"\n" | ||
881 | +"You've sent an email to %(mailinglist)s with a blank subject and the " | ||
882 | +"following content:\n" | ||
883 | +"\n" | ||
884 | +"\"%(body)s\"\n" | ||
885 | +"\n" | ||
886 | +"Please, fill the subject in every email you send it.\n" | ||
887 | +"\n" | ||
888 | +"Thank you.\n" | ||
889 | +msgstr "" | ||
890 | +"\n" | ||
891 | +"Você enviou um e-mail para %(mailinglist)s com o campo Assunto em branco e o " | ||
892 | +"seguinte conteúdo:\n" | ||
893 | +"\n" | ||
894 | +"\"%(body)s\"\n" | ||
895 | +"\n" | ||
896 | +"Por favor, preencha o assunto em todos os e-mails que você enviar.\n" | ||
897 | +"\n" | ||
898 | +"Obrigado.\n" | ||
899 | + | ||
811 | #: super_archives/templates/superarchives/emails/email_verification.txt:2 | 900 | #: super_archives/templates/superarchives/emails/email_verification.txt:2 |
812 | #, python-format | 901 | #, python-format |
813 | msgid "" | 902 | msgid "" |
@@ -826,15 +915,20 @@ msgstr "" | @@ -826,15 +915,20 @@ msgstr "" | ||
826 | "Se você não é %(username)s ou não pediu uma verificação você pode ignorar " | 915 | "Se você não é %(username)s ou não pediu uma verificação você pode ignorar " |
827 | "esse e-mail" | 916 | "esse e-mail" |
828 | 917 | ||
829 | -#: super_archives/templates/superarchives/includes/message.html:39 | 918 | +#: super_archives/templates/superarchives/includes/message.html:17 |
919 | +#: super_archives/templates/superarchives/includes/message.html:18 | ||
920 | +msgid "Link to this message" | ||
921 | +msgstr "Link para essa mensagem" | ||
922 | + | ||
923 | +#: super_archives/templates/superarchives/includes/message.html:46 | ||
830 | msgid "Reply" | 924 | msgid "Reply" |
831 | msgstr "Responder" | 925 | msgstr "Responder" |
832 | 926 | ||
833 | -#: super_archives/templates/superarchives/includes/message.html:56 | 927 | +#: super_archives/templates/superarchives/includes/message.html:63 |
834 | msgid "Send a message" | 928 | msgid "Send a message" |
835 | msgstr "Enviar uma mensagem" | 929 | msgstr "Enviar uma mensagem" |
836 | 930 | ||
837 | -#: super_archives/templates/superarchives/includes/message.html:59 | 931 | +#: super_archives/templates/superarchives/includes/message.html:66 |
838 | msgid "" | 932 | msgid "" |
839 | "After sending a message it will take few minutes before it shows up in here. " | 933 | "After sending a message it will take few minutes before it shows up in here. " |
840 | "Why don't you grab a coffee?" | 934 | "Why don't you grab a coffee?" |
@@ -842,7 +936,7 @@ msgstr "" | @@ -842,7 +936,7 @@ msgstr "" | ||
842 | "Depois de enviar uma mensagem levará alguns minutos antes dela aparecer " | 936 | "Depois de enviar uma mensagem levará alguns minutos antes dela aparecer " |
843 | "aqui. Por que você não pega um café?" | 937 | "aqui. Por que você não pega um café?" |
844 | 938 | ||
845 | -#: super_archives/templates/superarchives/includes/message.html:62 | 939 | +#: super_archives/templates/superarchives/includes/message.html:69 |
846 | msgid "Send" | 940 | msgid "Send" |
847 | msgstr "Enviar" | 941 | msgstr "Enviar" |
848 | 942 | ||
@@ -862,51 +956,63 @@ msgstr "Não encontrado. Continue procurando! :)" | @@ -862,51 +956,63 @@ msgstr "Não encontrado. Continue procurando! :)" | ||
862 | msgid "Ooopz... something went wrong!" | 956 | msgid "Ooopz... something went wrong!" |
863 | msgstr "Opa... algo saiu errado!" | 957 | msgstr "Opa... algo saiu errado!" |
864 | 958 | ||
865 | -#: templates/base.html:78 | 959 | +#: templates/base.html:76 |
960 | +msgid "Planet" | ||
961 | +msgstr "" | ||
962 | + | ||
963 | +#: templates/base.html:79 | ||
866 | msgid "Contribute" | 964 | msgid "Contribute" |
867 | msgstr "Contribua" | 965 | msgstr "Contribua" |
868 | 966 | ||
869 | #: templates/base.html:82 | 967 | #: templates/base.html:82 |
870 | -msgid "New Ticket" | ||
871 | -msgstr "Novo Tíquete" | ||
872 | - | ||
873 | -#: templates/base.html:84 | ||
874 | msgid "Timeline" | 968 | msgid "Timeline" |
875 | msgstr "Histórico" | 969 | msgstr "Histórico" |
876 | 970 | ||
877 | -#: templates/base.html:85 | 971 | +#: templates/base.html:83 |
878 | msgid "Roadmap" | 972 | msgid "Roadmap" |
879 | msgstr "Planejamento" | 973 | msgstr "Planejamento" |
880 | 974 | ||
881 | -#: templates/base.html:86 | ||
882 | -msgid "Browse Source" | ||
883 | -msgstr "Ver Código" | 975 | +#: templates/base.html:85 |
976 | +msgid "New Ticket" | ||
977 | +msgstr "Novo Tíquete" | ||
884 | 978 | ||
885 | #: templates/base.html:87 | 979 | #: templates/base.html:87 |
886 | msgid "View Tickets" | 980 | msgid "View Tickets" |
887 | msgstr "Visualizar Tiquetes" | 981 | msgstr "Visualizar Tiquetes" |
888 | 982 | ||
889 | -#: templates/base.html:111 | 983 | +#: templates/base.html:88 |
984 | +msgid "Browse Source" | ||
985 | +msgstr "Ver Códigos Fontes" | ||
986 | + | ||
987 | +#: templates/base.html:99 | ||
988 | +msgid "Login" | ||
989 | +msgstr "Entrar" | ||
990 | + | ||
991 | +#: templates/base.html:113 | ||
890 | msgid "My Profile" | 992 | msgid "My Profile" |
891 | msgstr "Meu Perfil" | 993 | msgstr "Meu Perfil" |
892 | 994 | ||
893 | -#: templates/base.html:123 templates/base.html.py:126 | 995 | +#: templates/base.html:114 |
996 | +msgid "Logout" | ||
997 | +msgstr "Sair" | ||
998 | + | ||
999 | +#: templates/base.html:126 templates/base.html.py:129 | ||
894 | msgid "Search here..." | 1000 | msgid "Search here..." |
895 | msgstr "Pesquise aqui..." | 1001 | msgstr "Pesquise aqui..." |
896 | 1002 | ||
897 | -#: templates/base.html:139 | 1003 | +#: templates/base.html:142 |
898 | msgid "The login has failed. Please, try again." | 1004 | msgid "The login has failed. Please, try again." |
899 | msgstr "O login falhou. Por favor, tente novamente." | 1005 | msgstr "O login falhou. Por favor, tente novamente." |
900 | 1006 | ||
901 | -#: templates/base.html:164 | 1007 | +#: templates/base.html:167 |
902 | msgid "Last email imported at" | 1008 | msgid "Last email imported at" |
903 | msgstr "Último e-mail importado em" | 1009 | msgstr "Último e-mail importado em" |
904 | 1010 | ||
905 | -#: templates/base.html:169 | 1011 | +#: templates/base.html:172 |
906 | msgid "The contents of this site is published under license" | 1012 | msgid "The contents of this site is published under license" |
907 | msgstr "O conteúdo deste site está publicado sob a licença" | 1013 | msgstr "O conteúdo deste site está publicado sob a licença" |
908 | 1014 | ||
909 | -#: templates/base.html:171 | 1015 | +#: templates/base.html:174 |
910 | msgid "Creative Commons - attribution, non-commercial" | 1016 | msgid "Creative Commons - attribution, non-commercial" |
911 | msgstr "Creative Commons - atribuição e não-comercial" | 1017 | msgstr "Creative Commons - atribuição e não-comercial" |
912 | 1018 | ||
@@ -934,10 +1040,6 @@ msgstr "Discussões Mais Relevantes" | @@ -934,10 +1040,6 @@ msgstr "Discussões Mais Relevantes" | ||
934 | msgid "RSS - Most Relevant Threads" | 1040 | msgid "RSS - Most Relevant Threads" |
935 | msgstr "RSS - Discussões Mais Relevantes" | 1041 | msgstr "RSS - Discussões Mais Relevantes" |
936 | 1042 | ||
937 | -#: templates/home.html:57 templates/home.html.py:76 | ||
938 | -msgid "View more discussions..." | ||
939 | -msgstr "Ver mais discussões..." | ||
940 | - | ||
941 | #: templates/home.html:64 | 1043 | #: templates/home.html:64 |
942 | msgid "Latest Threads" | 1044 | msgid "Latest Threads" |
943 | msgstr "Últimas Discussões" | 1045 | msgstr "Últimas Discussões" |
@@ -954,6 +1056,37 @@ msgstr "Vontade de ajudar" | @@ -954,6 +1056,37 @@ msgstr "Vontade de ajudar" | ||
954 | msgid "INTERLEGIS COMMUNITIES" | 1056 | msgid "INTERLEGIS COMMUNITIES" |
955 | msgstr "COMUNIDADES INTERLEGIS" | 1057 | msgstr "COMUNIDADES INTERLEGIS" |
956 | 1058 | ||
1059 | +#~ msgid "Identi.ca account" | ||
1060 | +#~ msgstr "Conta Identi.ca" | ||
1061 | + | ||
1062 | +#~ msgid "Biography" | ||
1063 | +#~ msgstr "Biografia" | ||
1064 | + | ||
1065 | +#~ msgid "Other Collaborations" | ||
1066 | +#~ msgstr "Outras Colaborações" | ||
1067 | + | ||
1068 | +#~ msgid "Community Blogs" | ||
1069 | +#~ msgstr "Blogs da comunidade" | ||
1070 | + | ||
1071 | +#~ msgid "Mailing List Subscriptions" | ||
1072 | +#~ msgstr "Inscrições em listas de e-mails" | ||
1073 | + | ||
1074 | +#~ msgid "Change SVN and XMPP Client password" | ||
1075 | +#~ msgstr "Trocar a senha do SVN e do Mensageiro" | ||
1076 | + | ||
1077 | +#~ msgid "" | ||
1078 | +#~ "You don't need to change this password. Change it only if you really know " | ||
1079 | +#~ "what you are doing." | ||
1080 | +#~ msgstr "" | ||
1081 | +#~ "Você não precisa trocar essa senha. Troque-a somente se tem certeza do " | ||
1082 | +#~ "que está fazendo." | ||
1083 | + | ||
1084 | +#~ msgid "Subscribes: " | ||
1085 | +#~ msgstr "Inscrições: " | ||
1086 | + | ||
1087 | +#~ msgid "Discussions" | ||
1088 | +#~ msgstr "Discussões" | ||
1089 | + | ||
957 | #~ msgid "Community inside participations" | 1090 | #~ msgid "Community inside participations" |
958 | #~ msgstr "Participações internas da comunidade" | 1091 | #~ msgstr "Participações internas da comunidade" |
959 | 1092 |
src/planet/templates/feedzilla/base.html
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | {% load i18n feedzilla_tags %} | 2 | {% load i18n feedzilla_tags %} |
3 | 3 | ||
4 | {% block main-content %} | 4 | {% block main-content %} |
5 | - <h2>{% trans 'Planet' %}</h2> | 5 | + <h2>{% trans 'Planet - Community Blogs' %}</h2> |
6 | <hr/> | 6 | <hr/> |
7 | 7 | ||
8 | <div id="planet" class="row"> | 8 | <div id="planet" class="row"> |
@@ -17,10 +17,12 @@ | @@ -17,10 +17,12 @@ | ||
17 | </div> | 17 | </div> |
18 | <div class="well"> | 18 | <div class="well"> |
19 | <h3>{% trans 'Source Blogs' %}</h3> | 19 | <h3>{% trans 'Source Blogs' %}</h3> |
20 | - {% feedzilla_donor_list %} | ||
21 | - <div class="text-center"> | ||
22 | - <a class="btn btn-primary" href="{% url "feedzilla_submit_blog" %}">{% trans "Submit a blog" %}</a> | ||
23 | - </div> | 20 | + {% feedzilla_donor_list order_by="title" %} |
21 | + {% if user.is_authenticated %} | ||
22 | + <div class="text-center"> | ||
23 | + <a class="btn btn-primary" href="{% url "feedzilla_submit_blog" %}">{% trans "Submit a blog" %}</a> | ||
24 | + </div> | ||
25 | + {% endif %} | ||
24 | </div> | 26 | </div> |
25 | </div> | 27 | </div> |
26 | </div> | 28 | </div> |
@@ -0,0 +1,125 @@ | @@ -0,0 +1,125 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +import datetime | ||
3 | +from django.db import connections | ||
4 | +from south.db import db | ||
5 | +from south.v2 import DataMigration | ||
6 | +from django.db import models | ||
7 | + | ||
8 | +class Migration(DataMigration): | ||
9 | + | ||
10 | + def forwards(self, orm): | ||
11 | + # Selecting trac database | ||
12 | + connection = connections['trac'] | ||
13 | + | ||
14 | + cursor = connection.cursor() | ||
15 | + cursor.execute(''' | ||
16 | + CREATE OR REPLACE VIEW wiki_view AS SELECT | ||
17 | + wiki.name AS name, | ||
18 | + (SELECT wiki2.text FROM wiki AS wiki2 WHERE wiki2.name = wiki.name | ||
19 | + AND wiki2.version = MAX(wiki.version)) AS wiki_text, | ||
20 | + (SELECT wiki3.author FROM wiki AS wiki3 WHERE wiki3.name = wiki.name | ||
21 | + AND wiki3.version = 1) AS author, | ||
22 | + string_agg(DISTINCT wiki.author, ', ') AS collaborators, | ||
23 | + TIMESTAMP WITH TIME ZONE 'epoch' + (MIN(wiki.time)/1000000) * INTERVAL '1s' AS created, | ||
24 | + TIMESTAMP WITH TIME ZONE 'epoch' + (MAX(wiki.time)/1000000) * INTERVAL '1s' AS modified, | ||
25 | + (SELECT wiki4.author FROM wiki AS wiki4 WHERE wiki4.name = wiki.name | ||
26 | + AND wiki4.version = MAX(wiki.version)) AS modified_by | ||
27 | + FROM wiki | ||
28 | + GROUP BY wiki.name; | ||
29 | + | ||
30 | + CREATE OR REPLACE VIEW ticket_view AS SELECT | ||
31 | + ticket.id AS id, | ||
32 | + ticket.summary as summary, | ||
33 | + ticket.description as description, | ||
34 | + ticket.milestone as milestone, | ||
35 | + ticket.priority as priority, | ||
36 | + ticket.component as component, | ||
37 | + ticket.version as version, | ||
38 | + ticket.severity as severity, | ||
39 | + ticket.reporter as reporter, | ||
40 | + ticket.reporter as author, | ||
41 | + ticket.status as status, | ||
42 | + ticket.keywords as keywords, | ||
43 | + (SELECT | ||
44 | + string_agg(DISTINCT ticket_change.author, ', ') | ||
45 | + FROM ticket_change WHERE ticket_change.ticket = ticket.id | ||
46 | + GROUP BY ticket_change.ticket) as collaborators, | ||
47 | + TIMESTAMP WITH TIME ZONE 'epoch' + (time/1000000)* INTERVAL '1s' AS created, | ||
48 | + TIMESTAMP WITH TIME ZONE 'epoch' + (changetime/1000000) * INTERVAL '1s' AS modified, | ||
49 | + (SELECT | ||
50 | + ticket_change.author | ||
51 | + FROM ticket_change | ||
52 | + WHERE ticket_change.ticket = ticket.id | ||
53 | + AND ticket_change.time = ticket.changetime | ||
54 | + LIMIT 1 | ||
55 | + ) AS modified_by | ||
56 | + FROM ticket; | ||
57 | + ''') | ||
58 | + | ||
59 | + | ||
60 | + def backwards(self, orm): | ||
61 | + # Selecting trac database | ||
62 | + connection = connections['trac'] | ||
63 | + | ||
64 | + cursor = connection.cursor() | ||
65 | + cursor.execute(''' | ||
66 | + ALTER VIEW wiki_view ALTER COLUMN modified_by DROP DEFAULT; | ||
67 | + ALTER VIEW ticket_view ALTER COLUMN modified_by DROP DEFAULT; | ||
68 | + ''') | ||
69 | + | ||
70 | + | ||
71 | + models = { | ||
72 | + u'proxy.attachment': { | ||
73 | + 'Meta': {'object_name': 'Attachment', 'db_table': "'attachment_view'", 'managed': 'False'}, | ||
74 | + 'attach_id': ('django.db.models.fields.TextField', [], {}), | ||
75 | + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
76 | + 'created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True'}), | ||
77 | + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
78 | + 'filename': ('django.db.models.fields.TextField', [], {}), | ||
79 | + 'mimetype': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
80 | + 'size': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}), | ||
81 | + 'url': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}), | ||
82 | + 'used_by': ('django.db.models.fields.TextField', [], {}) | ||
83 | + }, | ||
84 | + u'proxy.revision': { | ||
85 | + 'Meta': {'object_name': 'Revision', 'db_table': "'revision_view'", 'managed': 'False'}, | ||
86 | + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
87 | + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||
88 | + 'key': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}), | ||
89 | + 'message': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
90 | + 'repository_name': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
91 | + 'rev': ('django.db.models.fields.TextField', [], {'blank': 'True'}) | ||
92 | + }, | ||
93 | + u'proxy.ticket': { | ||
94 | + 'Meta': {'object_name': 'Ticket', 'db_table': "'ticket_view'", 'managed': 'False'}, | ||
95 | + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
96 | + 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
97 | + 'component': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
98 | + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||
99 | + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
100 | + 'id': ('django.db.models.fields.IntegerField', [], {'primary_key': 'True'}), | ||
101 | + 'keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
102 | + 'milestone': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
103 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||
104 | + 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
105 | + 'priority': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
106 | + 'reporter': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
107 | + 'severity': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
108 | + 'status': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
109 | + 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
110 | + 'version': ('django.db.models.fields.TextField', [], {'blank': 'True'}) | ||
111 | + }, | ||
112 | + u'proxy.wiki': { | ||
113 | + 'Meta': {'object_name': 'Wiki', 'db_table': "'wiki_view'", 'managed': 'False'}, | ||
114 | + 'author': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
115 | + 'collaborators': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
116 | + 'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||
117 | + 'modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||
118 | + 'modified_by': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||
119 | + 'name': ('django.db.models.fields.TextField', [], {'primary_key': 'True'}), | ||
120 | + 'wiki_text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) | ||
121 | + } | ||
122 | + } | ||
123 | + | ||
124 | + complete_apps = ['proxy'] | ||
125 | + symmetrical = True |
@@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
1 | +# -*- coding: utf-8 -*- | ||
2 | +from django.db import connections | ||
3 | +from south.v2 import DataMigration | ||
4 | + | ||
5 | +class Migration(DataMigration): | ||
6 | + | ||
7 | + def forwards(self, orm): | ||
8 | + # Selecting trac database | ||
9 | + connection = connections['trac'] | ||
10 | + | ||
11 | + cursor = connection.cursor() | ||
12 | + cursor.execute(''' | ||
13 | + CREATE OR REPLACE VIEW ticket_collab_count_view AS | ||
14 | + SELECT | ||
15 | + COALESCE (t1.author, t2.author) as author, | ||
16 | + (COALESCE(t1.count, 0) + COALESCE(t2.count, 0)) as count | ||
17 | + FROM | ||
18 | + (SELECT author, count(*) as count | ||
19 | + FROM ticket_change | ||
20 | + GROUP BY author | ||
21 | + ORDER BY author | ||
22 | + ) AS t1 | ||
23 | + FULL OUTER JOIN | ||
24 | + (SELECT reporter as author, count(*) as count | ||
25 | + FROM ticket | ||
26 | + GROUP BY reporter | ||
27 | + ORDER BY reporter | ||
28 | + ) AS t2 | ||
29 | + ON t1.author = t2.author; | ||
30 | + | ||
31 | + CREATE OR REPLACE VIEW wiki_collab_count_view AS | ||
32 | + SELECT author, count(*) from wiki GROUP BY author; | ||
33 | + ''') | ||
34 | + | ||
35 | + def backwards(self, orm): | ||
36 | + # Selecting trac database | ||
37 | + connection = connections['trac'] | ||
38 | + | ||
39 | + cursor = connection.cursor() | ||
40 | + cursor.execute(''' | ||
41 | + DROP VIEW ticket_collab_count_view; | ||
42 | + DROP VIEW wiki_collab_count_view; | ||
43 | + ''') | ||
44 | + | ||
45 | + complete_apps = ['proxy'] | ||
46 | + symmetrical = True |
src/proxy/models.py
@@ -4,7 +4,9 @@ import os | @@ -4,7 +4,9 @@ import os | ||
4 | import urllib2 | 4 | import urllib2 |
5 | 5 | ||
6 | from django.conf import settings | 6 | from django.conf import settings |
7 | -from django.db import models | 7 | +from django.db import models, connections |
8 | +from django.db.models.signals import post_save | ||
9 | +from django.dispatch import receiver | ||
8 | 10 | ||
9 | from accounts.models import User | 11 | from accounts.models import User |
10 | from hitcounter.models import HitCounterModelMixin | 12 | from hitcounter.models import HitCounterModelMixin |
@@ -81,6 +83,7 @@ class Ticket(models.Model, HitCounterModelMixin): | @@ -81,6 +83,7 @@ class Ticket(models.Model, HitCounterModelMixin): | ||
81 | collaborators = models.TextField(blank=True) | 83 | collaborators = models.TextField(blank=True) |
82 | created = models.DateTimeField(blank=True, null=True) | 84 | created = models.DateTimeField(blank=True, null=True) |
83 | modified = models.DateTimeField(blank=True, null=True) | 85 | modified = models.DateTimeField(blank=True, null=True) |
86 | + modified_by = models.TextField(blank=True) | ||
84 | 87 | ||
85 | class Meta: | 88 | class Meta: |
86 | managed = False | 89 | managed = False |
@@ -95,6 +98,12 @@ class Ticket(models.Model, HitCounterModelMixin): | @@ -95,6 +98,12 @@ class Ticket(models.Model, HitCounterModelMixin): | ||
95 | except User.DoesNotExist: | 98 | except User.DoesNotExist: |
96 | return None | 99 | return None |
97 | 100 | ||
101 | + def get_modified_by(self): | ||
102 | + try: | ||
103 | + return User.objects.get(username=self.modified_by) | ||
104 | + except User.DoesNotExist: | ||
105 | + return None | ||
106 | + | ||
98 | 107 | ||
99 | class Wiki(models.Model, HitCounterModelMixin): | 108 | class Wiki(models.Model, HitCounterModelMixin): |
100 | name = models.TextField(primary_key=True) | 109 | name = models.TextField(primary_key=True) |
@@ -103,6 +112,7 @@ class Wiki(models.Model, HitCounterModelMixin): | @@ -103,6 +112,7 @@ class Wiki(models.Model, HitCounterModelMixin): | ||
103 | collaborators = models.TextField(blank=True) | 112 | collaborators = models.TextField(blank=True) |
104 | created = models.DateTimeField(blank=True, null=True) | 113 | created = models.DateTimeField(blank=True, null=True) |
105 | modified = models.DateTimeField(blank=True, null=True) | 114 | modified = models.DateTimeField(blank=True, null=True) |
115 | + modified_by = models.TextField(blank=True) | ||
106 | 116 | ||
107 | class Meta: | 117 | class Meta: |
108 | managed = False | 118 | managed = False |
@@ -116,3 +126,54 @@ class Wiki(models.Model, HitCounterModelMixin): | @@ -116,3 +126,54 @@ class Wiki(models.Model, HitCounterModelMixin): | ||
116 | return User.objects.get(username=self.author) | 126 | return User.objects.get(username=self.author) |
117 | except User.DoesNotExist: | 127 | except User.DoesNotExist: |
118 | return None | 128 | return None |
129 | + | ||
130 | + def get_modified_by(self): | ||
131 | + try: | ||
132 | + return User.objects.get(username=self.modified_by) | ||
133 | + except User.DoesNotExist: | ||
134 | + return None | ||
135 | + | ||
136 | + | ||
137 | +class WikiCollabCount(models.Model): | ||
138 | + author = models.TextField(primary_key=True) | ||
139 | + count = models.IntegerField() | ||
140 | + | ||
141 | + class Meta: | ||
142 | + managed = False | ||
143 | + db_table = 'wiki_collab_count_view' | ||
144 | + | ||
145 | + | ||
146 | +class TicketCollabCount(models.Model): | ||
147 | + author = models.TextField(primary_key=True) | ||
148 | + count = models.IntegerField() | ||
149 | + | ||
150 | + class Meta: | ||
151 | + managed = False | ||
152 | + db_table = 'ticket_collab_count_view' | ||
153 | + | ||
154 | + | ||
155 | +@receiver(post_save, sender=User) | ||
156 | +def change_session_attribute_email(sender, instance, **kwargs): | ||
157 | + cursor = connections['trac'].cursor() | ||
158 | + | ||
159 | + cursor.execute(("UPDATE session_attribute SET value=%s " | ||
160 | + "WHERE name='email' AND sid=%s"), | ||
161 | + [instance.email, instance.username]) | ||
162 | + cursor.execute(("UPDATE session_attribute SET value=%s " | ||
163 | + "WHERE name='name' AND sid=%s"), | ||
164 | + [instance.get_full_name(), instance.username]) | ||
165 | + | ||
166 | + cursor.execute(("INSERT INTO session_attribute " | ||
167 | + "(sid, authenticated, name, value) " | ||
168 | + "SELECT %s, '1', 'email', %s WHERE NOT EXISTS " | ||
169 | + "(SELECT 1 FROM session_attribute WHERE sid=%s " | ||
170 | + "AND name='email')"), | ||
171 | + [instance.username, instance.email, instance.username]) | ||
172 | + | ||
173 | + cursor.execute(("INSERT INTO session_attribute " | ||
174 | + "(sid, authenticated, name, value) " | ||
175 | + "SELECT %s, '1', 'name', %s WHERE NOT EXISTS " | ||
176 | + "(SELECT 1 FROM session_attribute WHERE sid=%s " | ||
177 | + "AND name='name')"), | ||
178 | + [instance.username, instance.get_full_name(), | ||
179 | + instance.username]) |
src/search/base_indexes.py
@@ -19,6 +19,8 @@ class BaseIndex(indexes.SearchIndex): | @@ -19,6 +19,8 @@ class BaseIndex(indexes.SearchIndex): | ||
19 | icon_name = indexes.CharField(indexed=False) | 19 | icon_name = indexes.CharField(indexed=False) |
20 | fullname_and_username = indexes.CharField(null=True, stored=False) | 20 | fullname_and_username = indexes.CharField(null=True, stored=False) |
21 | hits = indexes.IntegerField(model_attr='hits') | 21 | hits = indexes.IntegerField(model_attr='hits') |
22 | + modified_by = indexes.CharField(null=True) | ||
23 | + modified_by_url = indexes.CharField(null=True) | ||
22 | 24 | ||
23 | def get_updated_field(self): | 25 | def get_updated_field(self): |
24 | return 'modified' | 26 | return 'modified' |
@@ -30,33 +32,63 @@ class BaseIndex(indexes.SearchIndex): | @@ -30,33 +32,63 @@ class BaseIndex(indexes.SearchIndex): | ||
30 | return math.log(obj.hits) | 32 | return math.log(obj.hits) |
31 | 33 | ||
32 | def prepare(self, obj): | 34 | def prepare(self, obj): |
35 | + self.author_obj = None | ||
36 | + if hasattr(obj, 'get_author'): | ||
37 | + self.author_obj = obj.get_author() | ||
38 | + | ||
33 | data = super(BaseIndex, self).prepare(obj) | 39 | data = super(BaseIndex, self).prepare(obj) |
34 | data['boost'] = self.get_boost(obj) | 40 | data['boost'] = self.get_boost(obj) |
41 | + | ||
35 | return data | 42 | return data |
36 | 43 | ||
37 | def prepare_author(self, obj): | 44 | def prepare_author(self, obj): |
38 | - author = obj.get_author() | ||
39 | - if author: | ||
40 | - return author.username | 45 | + if self.author_obj: |
46 | + return self.author_obj.username | ||
47 | + return obj.author | ||
48 | + | ||
49 | + def prepare_author_url(self, obj): | ||
50 | + if self.author_obj: | ||
51 | + return self.author_obj.get_absolute_url() | ||
52 | + return None | ||
53 | + | ||
54 | + def prepare_fullname(self, obj): | ||
55 | + if hasattr(obj, 'modified_by'): | ||
56 | + modified_by = obj.get_modified_by() | ||
57 | + if modified_by: | ||
58 | + return modified_by.get_full_name() | ||
59 | + if self.author_obj: | ||
60 | + return self.author_obj.get_full_name() | ||
41 | return obj.author | 61 | return obj.author |
42 | 62 | ||
43 | def prepare_fullname_and_username(self, obj): | 63 | def prepare_fullname_and_username(self, obj): |
44 | - author = obj.get_author() | ||
45 | - if not author: | 64 | + if hasattr(obj, 'modified_by'): |
65 | + modified_by = obj.get_modified_by() | ||
66 | + if modified_by: | ||
67 | + return u'{}\n{}'.format( | ||
68 | + modified_by.get_full_name(), | ||
69 | + modified_by.username, | ||
70 | + ) | ||
71 | + if not self.author_obj: | ||
46 | return obj.author | 72 | return obj.author |
47 | return u'{}\n{}'.format( | 73 | return u'{}\n{}'.format( |
48 | - author.get_full_name(), | ||
49 | - author.username, | 74 | + self.author_obj.get_full_name(), |
75 | + self.author_obj.username, | ||
50 | ) | 76 | ) |
51 | 77 | ||
52 | - def prepare_author_url(self, obj): | ||
53 | - author = obj.get_author() | ||
54 | - if author: | ||
55 | - return author.get_absolute_url() | ||
56 | - return None | ||
57 | - | ||
58 | - def prepare_fullname(self, obj): | ||
59 | - author = obj.get_author() | ||
60 | - if author: | ||
61 | - return author.get_full_name() | 78 | + def prepare_modified_by(self, obj): |
79 | + if hasattr(obj, 'modified_by'): | ||
80 | + modified_by = obj.get_modified_by() | ||
81 | + if modified_by: | ||
82 | + return modified_by.get_full_name() | ||
83 | + if self.author_obj: | ||
84 | + return self.author_obj.get_full_name() | ||
62 | return obj.author | 85 | return obj.author |
86 | + | ||
87 | + def prepare_modified_by_url(self, obj): | ||
88 | + if hasattr(obj, 'modified_by'): | ||
89 | + modified_by = obj.get_modified_by() | ||
90 | + if modified_by: | ||
91 | + return modified_by.get_absolute_url() | ||
92 | + if self.author_obj: | ||
93 | + return self.author_obj.get_absolute_url() | ||
94 | + return None |
src/search/forms.py
@@ -17,6 +17,7 @@ class ColabSearchForm(SearchForm): | @@ -17,6 +17,7 @@ class ColabSearchForm(SearchForm): | ||
17 | order = forms.CharField(widget=forms.HiddenInput(), required=False) | 17 | order = forms.CharField(widget=forms.HiddenInput(), required=False) |
18 | type = forms.CharField(required=False, label=_(u'Type')) | 18 | type = forms.CharField(required=False, label=_(u'Type')) |
19 | author = forms.CharField(required=False, label=_(u'Author')) | 19 | author = forms.CharField(required=False, label=_(u'Author')) |
20 | + modified_by = forms.CharField(required=False, label=_(u'Modified by')) | ||
20 | # ticket status | 21 | # ticket status |
21 | tag = forms.CharField(required=False, label=_(u'Status')) | 22 | tag = forms.CharField(required=False, label=_(u'Status')) |
22 | # mailinglist tag | 23 | # mailinglist tag |
@@ -122,6 +123,11 @@ class ColabSearchForm(SearchForm): | @@ -122,6 +123,11 @@ class ColabSearchForm(SearchForm): | ||
122 | fullname_and_username__contains=self.cleaned_data['author'] | 123 | fullname_and_username__contains=self.cleaned_data['author'] |
123 | ) | 124 | ) |
124 | 125 | ||
126 | + if self.cleaned_data['modified_by']: | ||
127 | + sqs = sqs.filter( | ||
128 | + fullname_and_username__contains=self.cleaned_data['modified_by'] | ||
129 | + ) | ||
130 | + | ||
125 | if self.cleaned_data['milestone']: | 131 | if self.cleaned_data['milestone']: |
126 | sqs = sqs.filter(milestone=self.cleaned_data['milestone']) | 132 | sqs = sqs.filter(milestone=self.cleaned_data['milestone']) |
127 | if self.cleaned_data['priority']: | 133 | if self.cleaned_data['priority']: |
src/static/css/screen.css
@@ -413,3 +413,18 @@ span.highlighted { | @@ -413,3 +413,18 @@ span.highlighted { | ||
413 | .vcard .label { | 413 | .vcard .label { |
414 | line-height: 2; | 414 | line-height: 2; |
415 | } | 415 | } |
416 | + | ||
417 | +/* Message link */ | ||
418 | + | ||
419 | +.div-message-link { | ||
420 | + display: inline !important; | ||
421 | +} | ||
422 | + | ||
423 | +.message-link { | ||
424 | + margin-left: 15px; | ||
425 | +} | ||
426 | + | ||
427 | +.email-message .popover { | ||
428 | + max-width: 350px; | ||
429 | + width: 350px; | ||
430 | +} |
@@ -0,0 +1,285 @@ | @@ -0,0 +1,285 @@ | ||
1 | +/* | ||
2 | + Highcharts JS v3.0.7 (2013-10-24) | ||
3 | + | ||
4 | + (c) 2009-2013 Torstein Hønsi | ||
5 | + | ||
6 | + License: www.highcharts.com/license | ||
7 | +*/ | ||
8 | +(function(){function s(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function x(){var a,b=arguments.length,c={},d=function(a,b){var c,h;typeof a!=="object"&&(a={});for(h in b)b.hasOwnProperty(h)&&(c=b[h],a[h]=c&&typeof c==="object"&&Object.prototype.toString.call(c)!=="[object Array]"&&typeof c.nodeType!=="number"?d(a[h]||{},c):b[h]);return a};for(a=0;a<b;a++)c=d(c,arguments[a]);return c}function y(a,b){return parseInt(a,b||10)}function ea(a){return typeof a==="string"}function T(a){return typeof a=== | ||
9 | +"object"}function Ia(a){return Object.prototype.toString.call(a)==="[object Array]"}function ra(a){return typeof a==="number"}function ma(a){return R.log(a)/R.LN10}function fa(a){return R.pow(10,a)}function ga(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function u(a){return a!==v&&a!==null}function w(a,b,c){var d,e;if(ea(b))u(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(u(b)&&T(b))for(d in b)a.setAttribute(d,b[d]);return e}function ja(a){return Ia(a)? | ||
10 | +a:[a]}function o(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!=="undefined"&&c!==null)return c}function I(a,b){if(sa&&b&&b.opacity!==v)b.filter="alpha(opacity="+b.opacity*100+")";s(a.style,b)}function U(a,b,c,d,e){a=z.createElement(a);b&&s(a,b);e&&I(a,{padding:0,border:S,margin:0});c&&I(a,c);d&&d.appendChild(a);return a}function ha(a,b){var c=function(){};c.prototype=new a;s(c.prototype,b);return c}function Aa(a,b,c,d){var e=L.lang,a=+a||0,f=b===-1?(a.toString().split(".")[1]|| | ||
11 | +"").length:isNaN(b=M(b))?2:b,b=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=a<0?"-":"",c=String(y(a=M(a).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:"")+c.substr(g).replace(/(\d{3})(?=\d)/g,"$1"+d)+(f?b+M(a-c).toFixed(f).slice(2):"")}function Ba(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function mb(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);a.unshift(d);return c.apply(this,a)}}function Ca(a,b){for(var c="{",d=!1, | ||
12 | +e,f,g,h,i,j=[];(c=a.indexOf(c))!==-1;){e=a.slice(0,c);if(d){f=e.split(":");g=f.shift().split(".");i=g.length;e=b;for(h=0;h<i;h++)e=e[g[h]];if(f.length)f=f.join(":"),g=/\.([0-9])/,h=L.lang,i=void 0,/f$/.test(f)?(i=(i=f.match(g))?i[1]:-1,e=Aa(e,i,h.decimalPoint,f.indexOf(",")>-1?h.thousandsSep:"")):e=Ya(f,e)}j.push(e);a=a.slice(c+1);c=(d=!d)?"}":"{"}j.push(a);return j.join("")}function nb(a){return R.pow(10,P(R.log(a)/R.LN10))}function ob(a,b,c,d){var e,c=o(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals=== | ||
13 | +!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function Cb(a,b){var c=b||[[Db,[1,2,5,10,20,25,50,100,200,500]],[pb,[1,2,5,10,15,30]],[Za,[1,2,5,10,15,30]],[Qa,[1,2,3,4,6,8,12]],[ta,[1,2]],[$a,[1,2]],[Ra,[1,2,3,4,6]],[Da,null]],d=c[c.length-1],e=D[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d=c[g],e=D[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+D[c[g+1][0]])/2)break;e===D[Da]&&a<5*e&&(f=[1,2,5]);c=ob(a/e,f,d[0]===Da?r(nb(a/e),1): | ||
14 | +1);return{unitRange:e,count:c,unitName:d[0]}}function Eb(a,b,c,d){var e=[],f={},g=L.global.useUTC,h,i=new Date(b),j=a.unitRange,k=a.count;if(u(b)){j>=D[pb]&&(i.setMilliseconds(0),i.setSeconds(j>=D[Za]?0:k*P(i.getSeconds()/k)));if(j>=D[Za])i[Fb](j>=D[Qa]?0:k*P(i[qb]()/k));if(j>=D[Qa])i[Gb](j>=D[ta]?0:k*P(i[rb]()/k));if(j>=D[ta])i[sb](j>=D[Ra]?1:k*P(i[Sa]()/k));j>=D[Ra]&&(i[Hb](j>=D[Da]?0:k*P(i[ab]()/k)),h=i[bb]());j>=D[Da]&&(h-=h%k,i[Ib](h));if(j===D[$a])i[sb](i[Sa]()-i[tb]()+o(d,1));b=1;h=i[bb](); | ||
15 | +for(var d=i.getTime(),l=i[ab](),m=i[Sa](),p=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;d<c;)e.push(d),j===D[Da]?d=cb(h+b*k,0):j===D[Ra]?d=cb(h,l+b*k):!g&&(j===D[ta]||j===D[$a])?d=cb(h,l,m+b*k*(j===D[ta]?1:7)):d+=j*k,b++;e.push(d);n(ub(e,function(a){return j<=D[Qa]&&a%D[ta]===p}),function(a){f[a]=ta})}e.info=s(a,{higherRanks:f,totalRange:j*k});return e}function Jb(){this.symbol=this.color=0}function Kb(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0? | ||
16 | +a.ss_i-c.ss_i:d});for(e=0;e<c;e++)delete a[e].ss_i}function Ja(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function ua(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Ka(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Ta(a){db||(db=U(Ea));a&&db.appendChild(a);db.innerHTML=""}function ka(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else N.console&&console.log(c)}function ia(a){return parseFloat(a.toPrecision(14))} | ||
17 | +function La(a,b){Fa=o(a,b.animation)}function Lb(){var a=L.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";cb=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,o(c,1),o(g,0),o(h,0),o(i,0))).getTime()};qb=b+"Minutes";rb=b+"Hours";tb=b+"Day";Sa=b+"Date";ab=b+"Month";bb=b+"FullYear";Fb=c+"Minutes";Gb=c+"Hours";sb=c+"Date";Hb=c+"Month";Ib=c+"FullYear"}function va(){}function Ma(a,b,c,d){this.axis=a;this.pos=b;this.type=c||"";this.isNew=!0;!c&&!d&&this.addLabel()}function vb(a,b){this.axis=a;if(b)this.options= | ||
18 | +b,this.id=b.id}function Mb(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.total=null;this.points={};this.stack=e;this.percent=f==="percent";this.alignOptions={align:b.align||(g?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(g?"middle":c?"bottom":"top"),y:o(b.y,g?4:c?14:-6),x:o(b.x,g?c?-6:6:0)};this.textAlign=b.textAlign||(g?c?"right":"left":"center")}function eb(){this.init.apply(this,arguments)}function wb(){this.init.apply(this,arguments)} | ||
19 | +function xb(a,b){this.init(a,b)}function fb(a,b){this.init(a,b)}function yb(){this.init.apply(this,arguments)}var v,z=document,N=window,R=Math,t=R.round,P=R.floor,wa=R.ceil,r=R.max,J=R.min,M=R.abs,V=R.cos,ba=R.sin,xa=R.PI,Ua=xa*2/360,na=navigator.userAgent,Nb=N.opera,sa=/msie/i.test(na)&&!Nb,gb=z.documentMode===8,hb=/AppleWebKit/.test(na),ib=/Firefox/.test(na),Ob=/(Mobile|Android|Windows Phone)/.test(na),ya="http://www.w3.org/2000/svg",W=!!z.createElementNS&&!!z.createElementNS(ya,"svg").createSVGRect, | ||
20 | +Ub=ib&&parseInt(na.split("Firefox/")[1],10)<4,ca=!W&&!sa&&!!z.createElement("canvas").getContext,Va,jb=z.documentElement.ontouchstart!==v,Pb={},zb=0,db,L,Ya,Fa,Ab,D,oa=function(){},Ga=[],Ea="div",S="none",Qb="rgba(192,192,192,"+(W?1.0E-4:0.002)+")",Db="millisecond",pb="second",Za="minute",Qa="hour",ta="day",$a="week",Ra="month",Da="year",Rb="stroke-width",cb,qb,rb,tb,Sa,ab,bb,Fb,Gb,sb,Hb,Ib,X={};N.Highcharts=N.Highcharts?ka(16,!0):{};Ya=function(a,b,c){if(!u(b)||isNaN(b))return"Invalid date";var a= | ||
21 | +o(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[rb](),g=d[tb](),h=d[Sa](),i=d[ab](),j=d[bb](),k=L.lang,l=k.weekdays,d=s({a:l[g].substr(0,3),A:l[g],d:Ba(h),e:h,b:k.shortMonths[i],B:k.months[i],m:Ba(i+1),y:j.toString().substr(2,2),Y:j,H:Ba(f),I:Ba(f%12||12),l:f%12||12,M:Ba(d[qb]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:Ba(d.getSeconds()),L:Ba(t(b%1E3),3)},Highcharts.dateFormats);for(e in d)for(;a.indexOf("%"+e)!==-1;)a=a.replace("%"+e,typeof d[e]==="function"?d[e](b):d[e]);return c?a.substr(0,1).toUpperCase()+ | ||
22 | +a.substr(1):a};Jb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};D=function(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}(Db,1,pb,1E3,Za,6E4,Qa,36E5,ta,864E5,$a,6048E5,Ra,26784E5,Da,31556952E3);Ab={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]==="M"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&& | ||
23 | +(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<=c.length/f&&b.length===c.length)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}}; | ||
24 | +(function(a){N.HighchartsAdapter=N.HighchartsAdapter||a&&{init:function(b){var c=a.fx,d=c.step,e,f=a.Tween,g=f&&f.propHooks;e=a.cssHooks.opacity;a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});a.each(["cur","_default","width","height","opacity"],function(a,b){var e=d,k,l;b==="cur"?e=c.prototype:b==="_default"&&f&&(e=g[b],b="set");(k=e[b])&&(e[b]=function(c){c=a?c:this;if(c.prop!=="align")return l=c.elem,l.attr?l.attr(c.prop,b==="cur"?v:c.now):k.apply(this,arguments)})}); | ||
25 | +mb(e,"get",function(a,b,c){return b.attr?b.opacity||0:a.call(this,b,c)});e=function(a){var c=a.elem,d;if(!a.started)d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0;c.attr("d",b.step(a.start,a.end,a.pos,c.toD))};f?g.d={set:e}:d.d=e;this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c};a.fn.highcharts=function(){var a="Chart",b=arguments,c,d;ea(b[0])&&(a=b[0],b=Array.prototype.slice.call(b, | ||
26 | +1));c=b[0];if(c!==v)c.chart=c.chart||{},c.chart.renderTo=this[0],new Highcharts[a](c,b[1]),d=this;c===v&&(d=Ga[w(this[0],"data-highcharts-chart")]);return d}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;e<f;e++)d[e]=c.call(a[e],a[e],e,a);return d},offset:function(b){return a(b).offset()},addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=z.removeEventListener?"removeEventListener": | ||
27 | +"detachEvent";z[e]&&b&&!b[e]&&(b[e]=function(){});a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var f=a.Event(c),g="detached"+c,h;!sa&&d&&(delete d.layerX,delete d.layerY);s(f,d);b[c]&&(b[g]=b[c],b[c]=null);a.each(["preventDefault","stopPropagation"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){b==="preventDefault"&&(h=!0)}}});a(b).trigger(f);b[g]&&(b[c]=b[g],b[g]=null);e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;if(c.pageX===v)c.pageX= | ||
28 | +a.pageX,c.pageY=a.pageY;return c},animate:function(b,c,d){var e=a(b);if(!b.style)b.style={};if(c.d)b.toD=c.d,c.d=1;e.stop();c.opacity!==v&&b.attr&&(c.opacity+="px");e.animate(c,d)},stop:function(b){a(b).stop()}}})(N.jQuery);var Y=N.HighchartsAdapter,G=Y||{};Y&&Y.init.call(Y,Ab);var kb=G.adapterRun,Vb=G.getScript,pa=G.inArray,n=G.each,ub=G.grep,Wb=G.offset,Na=G.map,K=G.addEvent,$=G.removeEvent,A=G.fireEvent,Xb=G.washMouseEvent,Bb=G.animate,Wa=G.stop,G={enabled:!0,x:0,y:15,style:{color:"#666",cursor:"default", | ||
29 | +fontSize:"11px",lineHeight:"14px"}};L={colors:"#2f7ed8,#0d233a,#8bbc21,#910000,#1aadce,#492970,#f28f43,#77a1e5,#c42525,#a6c96a".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),decimalPoint:".", | ||
30 | +numericSymbols:"k,M,G,T,P,E".split(","),resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/3.0.7/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/3.0.7/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:5,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],style:{fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif', | ||
31 | +fontSize:"12px"},backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",margin:15,style:{color:"#274b6d",fontSize:"16px"}},subtitle:{text:"",align:"center",style:{color:"#4d759e"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0},select:{fillColor:"#FFFFFF", | ||
32 | +lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:x(G,{align:"center",enabled:!1,formatter:function(){return this.y===null?"":Aa(this.y,-1)},verticalAlign:"bottom",y:0}),cropThreshold:300,pointRange:0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:"absolute",color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderWidth:1,borderColor:"#909090",borderRadius:5,navigation:{activeColor:"#274b6d", | ||
33 | +inactiveColor:"#CCC"},shadow:!1,itemStyle:{cursor:"pointer",color:"#274b6d",fontSize:"12px"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:"absolute",width:"13px",height:"13px"},symbolWidth:16,symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold",position:"relative",top:"1em"},style:{position:"absolute",backgroundColor:"white",opacity:0.5,textAlign:"center"}},tooltip:{enabled:!0,animation:W, | ||
34 | +backgroundColor:"rgba(255, 255, 255, .85)",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',shadow:!0,snap:Ob?25:10,style:{color:"#333333",cursor:"default", | ||
35 | +fontSize:"12px",padding:"8px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var Z=L.plotOptions,Y=Z.line;Lb();var Yb=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,Zb=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,$b=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/, | ||
36 | +qa=function(a){var b=[],c,d;(function(a){a&&a.stops?d=Na(a.stops,function(a){return qa(a[1])}):(c=Yb.exec(a))?b=[y(c[1]),y(c[2]),y(c[3]),parseFloat(c[4],10)]:(c=Zb.exec(a))?b=[y(c[1],16),y(c[2],16),y(c[3],16),1]:(c=$b.exec(a))&&(b=[y(c[1]),y(c[2]),y(c[3]),1])})(a);return{get:function(c){var f;d?(f=x(a),f.stops=[].concat(f.stops),n(d,function(a,b){f.stops[b]=[f.stops[b][0],a.get(c)]})):f=b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"?b[3]:"rgba("+b.join(",")+")":a;return f},brighten:function(a){if(d)n(d, | ||
37 | +function(b){b.brighten(a)});else if(ra(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=y(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},rgba:b,setOpacity:function(a){b[3]=a;return this}}};va.prototype={init:function(a,b){this.element=b==="span"?U(b):z.createElementNS(ya,b);this.renderer=a;this.attrSetters={}},opacity:1,animate:function(a,b,c){b=o(b,Fa,!0);Wa(this);if(b){b=x(b);if(c)b.complete=c;Bb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(), | ||
38 | +i=this.renderer,j,k=this.attrSetters,l=this.shadows,m,p,q=this;ea(a)&&u(b)&&(c=a,a={},a[c]=b);if(ea(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),q=w(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&&c!=="fill"&&(q=parseFloat(q));else{for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==v&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&&(d="M 0 0");else if(c==="x"&&h==="text")for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],w(f,"x")=== | ||
39 | +w(g,"x")&&w(f,"x",d);else if(this.rotation&&(c==="x"||c==="y"))p=!0;else if(c==="fill")d=i.color(d,g,c);else if(h==="circle"&&(c==="x"||c==="y"))c={x:"cx",y:"cy"}[c]||c;else if(h==="rect"&&c==="r")w(g,{rx:d,ry:d}),j=!0;else if(c==="translateX"||c==="translateY"||c==="rotation"||c==="verticalAlign"||c==="scaleX"||c==="scaleY")j=p=!0;else if(c==="stroke")d=i.color(d,g,c);else if(c==="dashstyle")if(c="stroke-dasharray",d=d&&d.toLowerCase(),d==="solid")d=S;else{if(d){d=d.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot", | ||
40 | +"3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(",");for(e=d.length;e--;)d[e]=y(d[e])*o(a["stroke-width"],this["stroke-width"]);d=d.join(",")}}else if(c==="width")d=y(d);else if(c==="align")c="text-anchor",d={left:"start",center:"middle",right:"end"}[d];else if(c==="title")e=g.getElementsByTagName("title")[0],e||(e=z.createElementNS(ya,"title"),g.appendChild(e)),e.textContent=d;c==="strokeWidth"&& | ||
41 | +(c="stroke-width");if(c==="stroke-width"||c==="stroke"){this[c]=d;if(this.stroke&&this["stroke-width"])w(g,"stroke",this.stroke),w(g,"stroke-width",this["stroke-width"]),this.hasStroke=!0;else if(c==="stroke-width"&&d===0&&this.hasStroke)g.removeAttribute("stroke"),this.hasStroke=!1;j=!0}this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(m||(this.symbolAttr(a),m=!0),j=!0);if(l&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(c))for(e=l.length;e--;)w(l[e], | ||
42 | +c,c==="height"?r(d-(l[e].cutHeight||0),0):d);if((c==="width"||c==="height")&&h==="rect"&&d<0)d=0;this[c]=d;c==="text"?(d!==this.textStr&&delete this.bBox,this.textStr=d,this.added&&i.buildText(this)):j||w(g,c,d)}p&&this.updateTransform()}return q},addClass:function(a){var b=this.element,c=w(b,"class")||"";c.indexOf(a)===-1&&w(b,"class",c+" "+a);return this},symbolAttr:function(a){var b=this;n("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=o(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x, | ||
43 | +b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path",a?"url("+this.renderer.url+"#"+a.id+")":S)},crisp:function(a,b,c,d,e){var f,g={},h={},i,a=a||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;i=t(a)%2/2;h.x=P(b||this.x||0)+i;h.y=P(c||this.y||0)+i;h.width=P((d||this.width||0)-2*i);h.height=P((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},css:function(a){var b=this.element,c=this.textWidth=a&&a.width&&b.nodeName.toLowerCase()=== | ||
44 | +"text"&&y(a.width),d,e="",f=function(a,b){return"-"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=s(this.styles,a);c&&delete a.width;if(sa&&!W)I(this.element,a);else{for(d in a)e+=d.replace(/([A-Z])/g,f)+":"+a[d]+";";w(b,"style",e)}c&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){var c=this,d=c.element;jb&&a==="click"?(d.ontouchstart=function(a){c.touchEventFired=Date.now();a.preventDefault();b.call(d,a)},d.onclick=function(a){(na.indexOf("Android")===-1||Date.now()- | ||
45 | +(c.touchEventFired||0)>1100)&&b.call(d,a)}):d["on"+a]=b;return this},setRadialReference:function(a){this.element.radialReference=a;return this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},htmlCss:function(a){var b=this.element;if(b=a&&b.tagName==="SPAN"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=s(this.styles,a);I(this.element,a);return this},htmlGetBBox:function(){var a= | ||
46 | +this.element,b=this.bBox;if(!b){if(a.nodeName==="text")a.style.position="absolute";b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}}return b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:0.5,right:1}[g],i=g&&g!=="left",j=this.shadows;I(b,{marginLeft:c,marginTop:d});j&&n(j,function(a){I(a,{marginLeft:c+1,marginTop:d+1})}); | ||
47 | +this.inverted&&n(b.childNodes,function(c){a.invertChild(c,b)});if(b.tagName==="SPAN"){var k,l,j=this.rotation,m;k=0;var p=1,q=0,aa;m=y(this.textWidth);var B=this.xCorr||0,O=this.yCorr||0,Sb=[j,g,b.innerHTML,this.textWidth].join(",");if(Sb!==this.cTT){u(j)&&(k=j*Ua,p=V(k),q=ba(k),this.setSpanRotation(j,q,p));k=o(this.elemWidth,b.offsetWidth);l=o(this.elemHeight,b.offsetHeight);if(k>m&&/[ \-]/.test(b.textContent||b.innerText))I(b,{width:m+"px",display:"block",whiteSpace:"normal"}),k=m;m=a.fontMetrics(b.style.fontSize).b; | ||
48 | +B=p<0&&-k;O=q<0&&-l;aa=p*q<0;B+=q*m*(aa?1-h:h);O-=p*m*(j?aa?h:1-h:1);i&&(B-=k*h*(p<0?-1:1),j&&(O-=l*h*(q<0?-1:1)),I(b,{textAlign:g}));this.xCorr=B;this.yCorr=O}I(b,{left:e+B+"px",top:f+O+"px"});if(hb)l=b.offsetHeight;this.cTT=Sb}}else this.alignOnAdd=!0},setSpanRotation:function(a){var b={};b[sa?"-ms-transform":hb?"-webkit-transform":ib?"MozTransform":Nb?"-o-transform":""]=b.transform="rotate("+a+"deg)";I(this.element,b)},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c= | ||
49 | +this.scaleX,d=this.scaleY,e=this.inverted,f=this.rotation;e&&(a+=this.attr("width"),b+=this.attr("height"));a=["translate("+a+","+b+")"];e?a.push("rotate(90) scale(-1,1)"):f&&a.push("rotate("+f+" "+(this.x||0)+" "+(this.y||0)+")");(u(c)||u(d))&&a.push("scale("+o(c,1)+" "+o(d,1)+")");a.length&&w(this.element,"transform",a.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){var d,e,f,g,h={};e=this.renderer;f=e.alignedObjects;if(a){if(this.alignOptions= | ||
50 | +a,this.alignByTranslate=b,!c||ea(c))this.alignTo=d=c||"renderer",ga(f,this),f.push(this),c=null}else a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo;c=o(c,e[d],e);d=a.align;e=a.verticalAlign;f=(c.x||0)+(a.x||0);g=(c.y||0)+(a.y||0);if(d==="right"||d==="center")f+=(c.width-(a.width||0))/{right:1,center:2}[d];h[b?"translateX":"x"]=t(f);if(e==="bottom"||e==="middle")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?"translateY":"y"]=t(g);this[this.placed?"animate":"attr"](h);this.placed= | ||
51 | +!0;this.alignAttr=h;return this},getBBox:function(){var a=this.bBox,b=this.renderer,c,d=this.rotation;c=this.element;var e=this.styles,f=d*Ua;if(!a){if(c.namespaceURI===ya||b.forExport){try{a=c.getBBox?s({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(g){}if(!a||a.width<0)a={width:0,height:0}}else a=this.htmlGetBBox();if(b.isSVG){b=a.width;c=a.height;if(sa&&e&&e.fontSize==="11px"&&c.toPrecision(3)==="22.7")a.height=c=14;if(d)a.width=M(c*ba(f))+M(b*V(f)),a.height=M(c*V(f))+M(b*ba(f))}this.bBox= | ||
52 | +a}return a},show:function(){return this.attr({visibility:"visible"})},hide:function(){return this.attr({visibility:"hidden"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.hide()}})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=w(f,"zIndex"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=!0,g=y(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a= | ||
53 | +e[c],b=w(a,"zIndex"),a!==f&&(y(b)>g||!u(g)&&u(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;A(this,"add");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d=a.renderer.isSVG&&b.nodeName==="SPAN"&&a.parentGroup,e,f;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null;Wa(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy(); | ||
54 | +a.stops=null}a.safeRemoveChild(b);for(c&&n(c,function(b){a.safeRemoveChild(b)});d&&d.div.childNodes.length===0;)b=d.parentGroup,a.safeRemoveChild(d.div),delete d.div,d=b;a.alignTo&&ga(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},shadow:function(a,b,c){var d=[],e,f,g=this.element,h,i,j,k;if(a){i=o(a.width,3);j=(a.opacity||0.15)/i;k=this.parentInverted?"(-1,-1)":"("+o(a.offsetX,1)+", "+o(a.offsetY,1)+")";for(e=1;e<=i;e++){f=g.cloneNode(0);h=i*2+1-2*e;w(f,{isShadow:"true",stroke:a.color|| | ||
55 | +"black","stroke-opacity":j*e,"stroke-width":h,transform:"translate"+k,fill:S});if(c)w(f,"height",r(w(f,"height")-h,0)),f.cutHeight=h;b?b.element.appendChild(f):g.parentNode.insertBefore(f,g);d.push(f)}this.shadows=d}return this}};var za=function(){this.init.apply(this,arguments)};za.prototype={Element:va,init:function(a,b,c,d){var e=location,f,g;f=this.createElement("svg").attr({version:"1.1"});g=f.element;a.appendChild(g);a.innerHTML.indexOf("xmlns")===-1&&w(g,"xmlns",ya);this.isSVG=!0;this.box= | ||
56 | +g;this.boxWrapper=f;this.alignedObjects=[];this.url=(ib||hb)&&z.getElementsByTagName("base").length?e.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"";this.createElement("desc").add().element.appendChild(z.createTextNode("Created with Highcharts 3.0.7"));this.defs=this.createElement("defs").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1);var h;if(ib&&a.getBoundingClientRect)this.subPixelFix=b=function(){I(a,{left:0,top:0});h=a.getBoundingClientRect();I(a, | ||
57 | +{left:wa(h.left)-h.left+"px",top:wa(h.top)-h.top+"px"})},b(),K(N,"resize",b)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Ka(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();this.subPixelFix&&$(N,"resize",this.subPixelFix);return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a);return b},draw:function(){},buildText:function(a){for(var b= | ||
58 | +a.element,c=this,d=c.forExport,e=o(a.textStr,"").toString().replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g),f=b.childNodes,g=/style="([^"]+)"/,h=/href="(http[^"]+)"/,i=w(b,"x"),j=a.styles,k=a.textWidth,l=j&&j.lineHeight,m=f.length;m--;)b.removeChild(f[m]);k&&!a.added&&this.box.appendChild(b);e[e.length-1]===""&&e.pop();n(e,function(e,f){var m,o=0, | ||
59 | +e=e.replace(/<span/g,"|||<span").replace(/<\/span>/g,"</span>|||");m=e.split("|||");n(m,function(e){if(e!==""||m.length===1){var p={},n=z.createElementNS(ya,"tspan"),r;g.test(e)&&(r=e.match(g)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),w(n,"style",r));h.test(e)&&!d&&(w(n,"onclick",'location.href="'+e.match(h)[1]+'"'),I(n,{cursor:"pointer"}));e=(e.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">");if(e!==" "&&(n.appendChild(z.createTextNode(e)),o?p.dx=0:p.x=i,w(n,p),!o&&f&& | ||
60 | +(!W&&d&&I(n,{display:"block"}),w(n,"dy",l||c.fontMetrics(/px$/.test(n.style.fontSize)?n.style.fontSize:j.fontSize).h,hb&&n.offsetHeight)),b.appendChild(n),o++,k))for(var e=e.replace(/([^\^])-/g,"$1- ").split(" "),u,t,p=a._clipHeight,E=[],v=y(l||16),s=1;e.length||E.length;)delete a.bBox,u=a.getBBox(),t=u.width,!W&&c.forExport&&(t=c.measureSpanWidth(n.firstChild.data,a.styles)),u=t>k,!u||e.length===1?(e=E,E=[],e.length&&(s++,p&&s*v>p?(e=["..."],a.attr("title",a.textStr)):(n=z.createElementNS(ya,"tspan"), | ||
61 | +w(n,{dy:v,x:i}),r&&w(n,"style",r),b.appendChild(n),t>k&&(k=t)))):(n.removeChild(n.firstChild),E.unshift(e.pop())),e.length&&n.appendChild(z.createTextNode(e.join(" ").replace(/- /g,"-")))}})})},button:function(a,b,c,d,e,f,g,h,i){var j=this.label(a,b,c,i,null,null,null,null,"button"),k=0,l,m,p,q,n,o,a={x1:0,y1:0,x2:0,y2:1},e=x({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:a,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},e);p=e.style;delete e.style;f=x(e,{stroke:"#68A", | ||
62 | +fill:{linearGradient:a,stops:[[0,"#FFF"],[1,"#ACF"]]}},f);q=f.style;delete f.style;g=x(e,{stroke:"#68A",fill:{linearGradient:a,stops:[[0,"#9BD"],[1,"#CDF"]]}},g);n=g.style;delete g.style;h=x(e,{style:{color:"#CCC"}},h);o=h.style;delete h.style;K(j.element,sa?"mouseover":"mouseenter",function(){k!==3&&j.attr(f).css(q)});K(j.element,sa?"mouseout":"mouseleave",function(){k!==3&&(l=[e,f,g][k],m=[p,q,n][k],j.attr(l).css(m))});j.setState=function(a){(j.state=k=a)?a===2?j.attr(g).css(n):a===3&&j.attr(h).css(o): | ||
63 | +j.attr(e).css(p)};return j.on("click",function(){k!==3&&d.call(j)}).attr(e).css(s({cursor:"default"},p))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=t(a[1])-b%2/2);a[2]===a[5]&&(a[2]=a[5]=t(a[2])+b%2/2);return a},path:function(a){var b={fill:S};Ia(a)?b.d=a:T(a)&&s(b,a);return this.createElement("path").attr(b)},circle:function(a,b,c){a=T(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(T(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;a=this.symbol("arc", | ||
64 | +a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0});a.r=c;return a},rect:function(a,b,c,d,e,f){e=T(a)?a.r:e;e=this.createElement("rect").attr({rx:e,ry:e,fill:S});return e.attr(T(a)?a:e.crisp(f,a,b,r(c,0),r(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[o(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return u(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b, | ||
65 | +c,d,e){var f={preserveAspectRatio:S};arguments.length>1&&s(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(t(b),t(c),d,e,f),i=/^url\((.*?)\)$/,j,k;if(h)g=this.path(h),s(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&s(g,f);else if(i.test(a))k=function(a,b){a.element&&(a.attr({width:b[0], | ||
66 | +height:b[1]}),a.alignByTranslate||a.translate(t((d-b[0])/2),t((e-b[1])/2)))},j=a.match(i)[1],a=Pb[j],g=this.image(j).attr({x:b,y:c}),g.isImg=!0,a?k(g,a):(g.attr({width:0,height:0}),U("img",{onload:function(){k(g,Pb[j]=[this.width,this.height])},src:j}));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M", | ||
67 | +a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-0.001,d=e.innerR,h=e.open,i=V(f),j=ba(f),k=V(g),g=ba(g),e=e.end-f<xa?0:1;return["M",a+c*i,b+c*j,"A",c,c,0,e,1,a+c*k,b+c*g,h?"M":"L",a+d*k,b+d*g,"A",d,d,0,e,0,a+d*i,b+d*j,h?"":"Z"]}},clipRect:function(a,b,c,d){var e="highcharts-"+zb++,f=this.createElement("clipPath").attr({id:e}).add(this.defs), | ||
68 | +a=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d=this,e,f=/^rgba/,g,h,i,j,k,l,m,p=[];a&&a.linearGradient?g="linearGradient":a&&a.radialGradient&&(g="radialGradient");if(g){c=a[g];h=d.gradients;j=a.stops;b=b.radialReference;Ia(c)&&(a[g]=c={x1:c[0],y1:c[1],x2:c[2],y2:c[3],gradientUnits:"userSpaceOnUse"});g==="radialGradient"&&b&&!u(c.gradientUnits)&&(c=x(c,{cx:b[0]-b[2]/2+c.cx*b[2],cy:b[1]-b[2]/2+c.cy*b[2],r:c.r*b[2],gradientUnits:"userSpaceOnUse"}));for(m in c)m!== | ||
69 | +"id"&&p.push(m,c[m]);for(m in j)p.push(j[m]);p=p.join(",");h[p]?a=h[p].id:(c.id=a="highcharts-"+zb++,h[p]=i=d.createElement(g).attr(c).add(d.defs),i.stops=[],n(j,function(a){f.test(a[1])?(e=qa(a[1]),k=e.get("rgb"),l=e.get("a")):(k=a[1],l=1);a=d.createElement("stop").attr({offset:a[0],"stop-color":k,"stop-opacity":l}).add(i);i.stops.push(a)}));return"url("+d.url+"#"+a+")"}else return f.test(a)?(e=qa(a),w(b,c+"-opacity",e.get("a")),e.get("rgb")):(b.removeAttribute(c+"-opacity"),a)},text:function(a, | ||
70 | +b,c,d){var e=L.chart.style,f=ca||!W&&this.forExport;if(d&&!this.forExport)return this.html(a,b,c);b=t(o(b,0));c=t(o(c,0));a=this.createElement("text").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,fontSize:e.fontSize});f&&a.css({position:"absolute"});a.x=b;a.y=c;return a},html:function(a,b,c){var d=L.chart.style,e=this.createElement("span"),f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){a!==g.innerHTML&&delete this.bBox;g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b=== | ||
71 | +"align"&&(b="textAlign");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:t(b),y:t(c)}).css({position:"absolute",whiteSpace:"nowrap",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;if(h.isSVG)e.add=function(a){var b,c=h.box.parentNode,d=[];if(this.parentGroup=a){if(b=a.div,!b){for(;a;)d.push(a),a=a.parentGroup;n(d.reverse(),function(a){var d;b=a.div=a.div||U(Ea,{className:w(a.element,"class")},{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px"},b||c); | ||
72 | +d=b.style;s(a.attrSetters,{translateX:function(a){d.left=a+"px"},translateY:function(a){d.top=a+"px"},visibility:function(a,b){d[b]=a}})})}}else b=c;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};return e},fontMetrics:function(a){var a=y(a||11),a=a<24?a+4:t(a*1.2),b=t(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a,b;a=o.element.style;O=(Oa===void 0||Ha===void 0||q.styles.textAlign)&&o.getBBox();q.width=(Oa||O.width||0)+2*da+lb;q.height=(Ha|| | ||
73 | +O.height||0)+2*da;w=da+p.fontMetrics(a&&a.fontSize).b;if(y){if(!B)a=t(-r*da),b=h?-w:0,q.box=B=d?p.symbol(d,a,b,q.width,q.height,Xa):p.rect(a,b,q.width,q.height,0,Xa[Rb]),B.add(q);B.isImg||B.attr(x({width:q.width,height:q.height},Xa));Xa=null}}function k(){var a=q.styles,a=a&&a.textAlign,b=lb+da*(1-r),c;c=h?0:w;if(u(Oa)&&(a==="center"||a==="right"))b+={center:0.5,right:1}[a]*(Oa-O.width);(b!==o.x||c!==o.y)&&o.attr({x:b,y:c});o.x=b;o.y=c}function l(a,b){B?B.attr(a,b):Xa[a]=b}function m(){o.add(q);q.attr({text:a, | ||
74 | +x:b,y:c});B&&u(e)&&q.attr({anchorX:e,anchorY:f})}var p=this,q=p.g(i),o=p.text("",0,0,g).attr({zIndex:1}),B,O,r=0,da=3,lb=0,Oa,Ha,E,H,C=0,Xa={},w,g=q.attrSetters,y;K(q,"add",m);g.width=function(a){Oa=a;return!1};g.height=function(a){Ha=a;return!1};g.padding=function(a){u(a)&&a!==da&&(da=a,k());return!1};g.paddingLeft=function(a){u(a)&&a!==lb&&(lb=a,k());return!1};g.align=function(a){r={left:0,center:0.5,right:1}[a];return!1};g.text=function(a,b){o.attr(b,a);j();k();return!1};g[Rb]=function(a,b){y= | ||
75 | +!0;C=a%2/2;l(b,a);return!1};g.stroke=g.fill=g.r=function(a,b){b==="fill"&&(y=!0);l(b,a);return!1};g.anchorX=function(a,b){e=a;l(b,a+C-E);return!1};g.anchorY=function(a,b){f=a;l(b,a-H);return!1};g.x=function(a){q.x=a;a-=r*((Oa||O.width)+da);E=t(a);q.attr("translateX",E);return!1};g.y=function(a){H=q.y=t(a);q.attr("translateY",H);return!1};var z=q.css;return s(q,{css:function(a){if(a){var b={},a=x(a);n("fontSize,fontWeight,fontFamily,color,lineHeight,width,textDecoration,textShadow".split(","),function(c){a[c]!== | ||
76 | +v&&(b[c]=a[c],delete a[c])});o.css(b)}return z.call(q,a)},getBBox:function(){return{width:O.width+2*da,height:O.height+2*da,x:O.x-da,y:O.y-da}},shadow:function(a){B&&B.shadow(a);return q},destroy:function(){$(q,"add",m);$(q.element,"mouseenter");$(q.element,"mouseleave");o&&(o=o.destroy());B&&(B=B.destroy());va.prototype.destroy.call(q);q=p=j=k=l=m=null}})}};Va=za;var F;if(!W&&!ca){Highcharts.VMLElement=F={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ","absolute",";"], | ||
77 | +e=b===Ea;(b==="shape"||e)&&d.push("left:0;top:0;width:1px;height:1px;");d.push("visibility: ",e?"hidden":"visible");c.push(' style="',d.join(""),'"/>');if(b)c=e||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=U(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();A(this,"add");return this}, | ||
78 | +updateTransform:va.prototype.htmlUpdateTransform,setSpanRotation:function(a,b,c){I(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11=",c,", M12=",-b,", M21=",b,", M22=",c,", sizingMethod='auto expand')"].join(""):S})},pathToVML:function(a){for(var b=a.length,c=[],d;b--;)if(ra(a[b]))c[b]=t(a[b]*10)-5;else if(a[b]==="Z")c[b]="x";else if(c[b]=a[b],a.isArc&&(a[b]==="wa"||a[b]==="at"))d=a[b]==="wa"?1:-1,c[b+5]===c[b+7]&&(c[b+7]-=d),c[b+6]===c[b+8]&&(c[b+8]-=d);return c.join(" ")||"x"}, | ||
79 | +attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,l=this.shadows,m,p=this.attrSetters,q=this;ea(a)&&u(b)&&(c=a,a={},a[c]=b);if(ea(a))c=a,q=c==="strokeWidth"||c==="stroke-width"?this.strokeweight:this[c];else for(c in a)if(d=a[c],m=!1,e=p[c]&&p[c].call(this,d,c),e!==!1&&d!==null){e!==v&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a),k=!0),m=!0;else if(c==="d"){d=d||[];this.d=d.join(" ");f.path= | ||
80 | +d=this.pathToVML(d);if(l)for(e=l.length;e--;)l[e].path=l[e].cutOff?this.cutOffPath(d,l[e].cutOff):d;m=!0}else if(c==="visibility"){if(l)for(e=l.length;e--;)l[e].style[c]=d;h==="DIV"&&(d=d==="hidden"?"-999em":0,gb||(g[c]=d?"visible":"hidden"),c="top");g[c]=d;m=!0}else if(c==="zIndex")d&&(g[c]=d),m=!0;else if(pa(c,["x","y","width","height"])!==-1)this[c]=d,c==="x"||c==="y"?c={x:"left",y:"top"}[c]:d=r(0,d),this.updateClipping?(this[c]=d,this.updateClipping()):g[c]=d,m=!0;else if(c==="class"&&h==="DIV")f.className= | ||
81 | +d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,ra(d)&&(d+="px");else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||U(i.prepVML(["<stroke/>"]),null,null,f))[c]=d||"solid",this.dashstyle=d,m=!0;else if(c==="fill")if(h==="SPAN")g.color=d;else{if(h!=="IMG")f.filled=d!==S?!0:!1,d=i.color(d,f,c,this),c="fillcolor"}else if(c==="opacity")m=!0;else if(h==="shape"&&c==="rotation")this[c]=f.style[c]= | ||
82 | +d,f.style.left=-t(ba(d*Ua)+1)+"px",f.style.top=t(V(d*Ua))+"px";else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),m=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,m=!0;m||(gb?f[c]=d:w(f,c,d))}return q},clip:function(a){var b=this,c;a?(c=a.members,ga(c,b),c.push(b),b.destroyClip=function(){ga(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:gb?"inherit":"rect(auto)"});return b.css(a)},css:va.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&& | ||
83 | +Ta(a)},destroy:function(){this.destroyClip&&this.destroyClip();return va.prototype.destroy.apply(this)},on:function(a,b){this.element["on"+a]=function(){var a=N.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,b){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=y(a[c-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,l,m,p,q;k&&typeof k.value!=="string"&&(k="x");m=k;if(a){p=o(a.width,3);q=(a.opacity|| | ||
84 | +0.15)/p;for(e=1;e<=3;e++){l=p*2+1-2*e;c&&(m=this.cutOffPath(k.value,l+0.5));j=['<shape isShadow="true" strokeweight="',l,'" filled="false" path="',m,'" coordsize="10 10" style="',f.style.cssText,'" />'];h=U(g.prepVML(j),null,{left:y(i.left)+o(a.offsetX,1),top:y(i.top)+o(a.offsetY,1)});if(c)h.cutOff=l+1;j=['<stroke color="',a.color||"black",'" opacity="',q*e,'"/>'];U(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};F=ha(va,F); | ||
85 | +var la={Element:F,isIE8:na.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(Ea);e=d.element;e.style.position="relative";a.appendChild(d.element);this.isVML=!0;this.box=e;this.boxWrapper=d;this.setSize(b,c,!1);if(!z.namespaces.hcv){z.namespaces.add("hcv","urn:schemas-microsoft-com:vml");try{z.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}catch(f){z.styleSheets[0].cssText+= | ||
86 | +"hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "}}},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=T(a);return s(e,{members:[],left:(f?a.x:a)+1,top:(f?a.y:b)+1,width:(f?a.width:c)-1,height:(f?a.height:d)-1,getCSS:function(a){var b=a.element,c=b.nodeName,a=a.inverted,d=this.top-(c==="shape"?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:"rect("+t(a?e:d)+"px,"+t(a?f: | ||
87 | +b)+"px,"+t(a?b:f)+"px,"+t(a?d:e)+"px)"};!a&&gb&&c==="DIV"&&s(d,{width:b+"px",height:f+"px"});return d},updateClipping:function(){n(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=S;a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern");if(i){var k,l,m=a.linearGradient||a.radialGradient,p,q,o,B,O,r="",a=a.stops,u,t=[],v=function(){h=['<fill colors="'+t.join(",")+'" opacity="',o,'" o:opacity2="',q,'" type="',i,'" ',r,'focus="100%" method="any" />']; | ||
88 | +U(e.prepVML(h),null,null,b)};p=a[0];u=a[a.length-1];p[0]>0&&a.unshift([0,p[1]]);u[0]<1&&a.push([1,u[1]]);n(a,function(a,b){g.test(a[1])?(f=qa(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1);t.push(a[0]*100+"% "+k);b?(o=l,B=k):(q=l,O=k)});if(c==="fill")if(i==="gradient")c=m.x1||m[0]||0,a=m.y1||m[1]||0,p=m.x2||m[2]||0,m=m.y2||m[3]||0,r='angle="'+(90-R.atan((m-a)/(p-c))*180/xa)+'"',v();else{var j=m.r,s=j*2,E=j*2,H=m.cx,C=m.cy,x=b.radialReference,w,j=function(){x&&(w=d.getBBox(),H+=(x[0]-w.x)/w.width- | ||
89 | +0.5,C+=(x[1]-w.y)/w.height-0.5,s*=x[2]/w.width,E*=x[2]/w.height);r='src="'+L.global.VMLRadialGradientURL+'" size="'+s+","+E+'" origin="0.5,0.5" position="'+H+","+C+'" color2="'+O+'" ';v()};d.added?j():K(d,"add",j);j=B}else j=k}else if(g.test(a)&&b.tagName!=="IMG")f=qa(a),h=["<",c,' opacity="',f.get("a"),'"/>'],U(this.prepVML(h),null,null,b),j=f.get("rgb");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1,j[0].type="solid";j=a}return j},prepVML:function(a){var b=this.isIE8,a=a.join("");b? | ||
90 | +(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===-1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:");return a},text:za.prototype.html,path:function(a){var b={coordsize:"10 10"};Ia(a)?b.d=a:T(a)&&s(b,a);return this.createElement("shape").attr(b)},circle:function(a,b,c){var d=this.symbol("circle");if(T(a))c=a.r,b=a.y,a=a.x;d.isCircle= | ||
91 | +!0;d.r=c;return d.attr({x:a,y:b})},g:function(a){var b;a&&(b={className:"highcharts-"+a,"class":"highcharts-"+a});return this.createElement(Ea).attr(b)},image:function(a,b,c,d,e){var f=this.createElement("img").attr({src:a});arguments.length>1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){var g=this.symbol("rect");g.r=T(a)?a.r:e;return g.attr(T(a)?a:g.crisp(f,a,b,r(c,0),r(d,0)))},invertChild:function(a,b){var c=b.style;I(a,{flip:"x",left:y(c.width)-1,top:y(c.height)-1,rotation:-90})}, | ||
92 | +symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=V(f),i=ba(f),j=V(g),k=ba(g);if(g-f===0)return["x"];f=["wa",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*j,b+h*k];e.open&&!c&&f.push("e","M",a,b);f.push("at",a-c,b-c,a+c,b+c,a+c*j,b+c*k,a+c*d,b+c*i,"x","e");f.isArc=!0;return f},circle:function(a,b,c,d,e){e&&(c=d=2*e.r);e&&e.isCircle&&(a-=c/2,b-=d/2);return["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){var f=a+c,g=b+d,h;!u(e)||!e.r?f=za.prototype.symbols.square.apply(0, | ||
93 | +arguments):(h=J(e.r,c,d),f=["M",a+h,b,"L",f-h,b,"wa",f-2*h,b,f,b+2*h,f-h,b,f,b+h,"L",f,g-h,"wa",f-2*h,g-2*h,f,g,f,g-h,f-h,g,"L",a+h,g,"wa",a,g-2*h,a+2*h,g,a+h,g,a,g-h,"L",a,b+h,"wa",a,b,a+2*h,b+2*h,a,b+h,a+h,b,"x","e"]);return f}}};Highcharts.VMLRenderer=F=function(){this.init.apply(this,arguments)};F.prototype=x(za.prototype,la);Va=F}za.prototype.measureSpanWidth=function(a,b){var c=z.createElement("span"),d=z.createTextNode(a);c.appendChild(d);I(c,b);this.box.appendChild(c);return c.offsetWidth}; | ||
94 | +var Tb;if(ca)Highcharts.CanVGRenderer=F=function(){ya="http://www.w3.org/1999/xhtml"},F.prototype.symbols={},Tb=function(){function a(){var a=b.length,d;for(d=0;d<a;d++)b[d]();b=[]}var b=[];return{push:function(c,d){b.length===0&&Vb(d,a);b.push(c)}}}(),Va=F;Ma.prototype={addLabel:function(){var a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=a.names,g=this.pos,h=b.labels,i=a.tickPositions,d=d&&e&&!h.step&&!h.staggerLines&&!h.rotation&&c.plotWidth/i.length||!d&&(c.margin[3]||c.chartWidth* | ||
95 | +0.33),j=g===i[0],k=g===i[i.length-1],l,f=e?o(e[g],f[g],g):g,e=this.label,m=i.info;a.isDatetimeAxis&&m&&(l=b.dateTimeLabelFormats[m.higherRanks[g]||m.unitName]);this.isFirst=j;this.isLast=k;b=a.labelFormatter.call({axis:a,chart:c,isFirst:j,isLast:k,dateTimeLabelFormat:l,value:a.isLog?ia(fa(f)):f});g=d&&{width:r(1,t(d-2*(h.padding||10)))+"px"};g=s(g,h.style);if(u(e))e&&e.attr({text:b}).css(g);else{l={align:a.labelAlign};if(ra(h.rotation))l.rotation=h.rotation;if(d&&h.ellipsis)l._clipHeight=a.len/i.length; | ||
96 | +this.label=u(b)&&h.enabled?c.renderer.text(b,0,0,h.useHTML).attr(l).css(g).add(a.labelGroup):null}},getLabelSize:function(){var a=this.label,b=this.axis;return a?(this.labelBBox=a.getBBox())[b.horiz?"height":"width"]:0},getLabelSides:function(){var a=this.axis,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.labelAlign]-a.options.labels.x;return[-a,b-a]},handleOverflow:function(a,b){var c=!0,d=this.axis,e=d.chart,f=this.isFirst,g=this.isLast,h=b.x,i=d.reversed,j=d.tickPositions;if(f||g){var k= | ||
97 | +this.getLabelSides(),l=k[0],k=k[1],e=e.plotLeft,m=e+d.len,j=(d=d.ticks[j[a+(f?1:-1)]])&&d.label.xy&&d.label.xy.x+d.getLabelSides()[f?0:1];f&&!i||g&&i?h+l<e&&(h=e-l,d&&h+k>j&&(c=!1)):h+k>m&&(h=m-k,d&&h+l<j&&(c=!1));b.x=h}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0): | ||
98 | +g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,l=i.staggerLines,m=i.chart.renderer.fontMetrics(e.style.fontSize).b,p=e.rotation,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):0);p&&i.side===2&&(b-=m-m*V(p*Ua));!u(e.y)&&!p&&(b+=m-c.getBBox().height/2);l&&(b+=g/(h||1)%l*(i.labelOffset/l));return{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine(["M",a,b,"L",a+(e?0:-c),b+(e?c:0)],d)},render:function(a, | ||
99 | +b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,j=this.pos,k=e.labels,l=this.gridLine,m=h?h+"Grid":"grid",p=h?h+"Tick":"tick",q=e[m+"LineWidth"],n=e[m+"LineColor"],B=e[m+"LineDashStyle"],r=e[p+"Length"],m=e[p+"Width"]||0,u=e[p+"Color"],t=e[p+"Position"],p=this.mark,s=k.step,w=!0,x=d.tickmarkOffset,E=this.getPosition(g,j,x,b),H=E.x,E=E.y,C=g&&H===d.pos+d.len||!g&&E===d.pos?-1:1,y=d.staggerLines;this.isActive=!0;if(q){j=d.getPlotLinePath(j+x,q*C,b,!0);if(l===v){l= | ||
100 | +{stroke:n,"stroke-width":q};if(B)l.dashstyle=B;if(!h)l.zIndex=1;if(b)l.opacity=0;this.gridLine=l=q?f.path(j).attr(l).add(d.gridGroup):null}if(!b&&l&&j)l[this.isNew?"attr":"animate"]({d:j,opacity:c})}if(m&&r)t==="inside"&&(r=-r),d.opposite&&(r=-r),b=this.getMarkPath(H,E,r,m*C,g,f),p?p.animate({d:b,opacity:c}):this.mark=f.path(b).attr({stroke:u,"stroke-width":m,opacity:c}).add(d.axisGroup);if(i&&!isNaN(H))i.xy=E=this.getLabelPosition(H,E,i,g,k,x,a,s),this.isFirst&&!this.isLast&&!o(e.showFirstLabel, | ||
101 | +1)||this.isLast&&!this.isFirst&&!o(e.showLastLabel,1)?w=!1:!y&&g&&k.overflow==="justify"&&!this.handleOverflow(a,E)&&(w=!1),s&&a%s&&(w=!1),w&&!isNaN(E.y)?(E.opacity=c,i[this.isNew?"attr":"animate"](E),this.isNew=!1):i.attr("y",-9999)},destroy:function(){Ka(this,this.axis)}};vb.prototype={render:function(){var a=this,b=a.axis,c=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=u(j)&&u(i),l=e.value,m=e.dashStyle,p=a.svgElem,q=[],n,B=e.color,O=e.zIndex,t=e.events, | ||
102 | +v=b.chart.renderer;b.isLog&&(j=ma(j),i=ma(i),l=ma(l));if(h){if(q=b.getPlotLinePath(l,h),d={stroke:B,"stroke-width":h},m)d.dashstyle=m}else if(k){if(j=r(j,b.min-d),i=J(i,b.max+d),q=b.getPlotBandPath(j,i,e),d={fill:B},e.borderWidth)d.stroke=e.borderColor,d["stroke-width"]=e.borderWidth}else return;if(u(O))d.zIndex=O;if(p)if(q)p.animate({d:q},null,p.onGetPath);else{if(p.hide(),p.onGetPath=function(){p.show()},g)a.label=g=g.destroy()}else if(q&&q.length&&(a.svgElem=p=v.path(q).attr(d).add(),t))for(n in e= | ||
103 | +function(b){p.on(b,function(c){t[b].apply(a,[c])})},t)e(n);if(f&&u(f.text)&&q&&q.length&&b.width>0&&b.height>0){f=x({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=v.text(f.text,0,0,f.useHTML).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:O}).css(f.style).add();b=[q[1],q[4],o(q[6],q[1])];q=[q[2],q[5],o(q[7],q[2])];c=Ja(b);k=Ja(q);g.align(f,!1,{x:c,y:k,width:ua(b)-c,height:ua(q)-k});g.show()}else g&&g.hide();return a}, | ||
104 | +destroy:function(){ga(this.axis.plotLinesAndBands,this);delete this.axis;Ka(this)}};Mb.prototype={destroy:function(){Ka(this,this.axis)},render:function(a){var b=this.options,c=b.format,c=c?Ca(c,this):b.formatter.call(this);this.label?this.label.attr({text:c,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(c,0,0,b.useHTML).css(b.style).attr({align:this.textAlign,rotation:b.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative, | ||
105 | +g=c.translate(this.percent?100:this.total,0,0,0,1),c=c.translate(0),c=M(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?W?"inherit":"visible":"hidden"})}};eb.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b", | ||
106 | +month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#C0C0C0",labels:G,lineColor:"#C0D0E0",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#4d759e",fontWeight:"bold"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0, | ||
107 | +gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return Aa(this.total,-1)},style:G.style}},defaultLeftAxisOptions:{labels:{x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:8,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{x:0,y:-5}, | ||
108 | +title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c;this.xOrY=(this.isXAxis=c)?"x":"y";this.opposite=b.opposite;this.side=this.horiz?this.opposite?0:2:this.opposite?1:3;this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.userOptions=b;this.minPixelPadding=0;this.chart=a;this.reversed=d.reversed;this.zoomEnabled=d.zoomEnabled!==!1;this.categories=d.categories||e==="category";this.names=[];this.isLog=e==="logarithmic"; | ||
109 | +this.isDatetimeAxis=e==="datetime";this.isLinked=u(d.linkedTo);this.tickmarkOffset=this.categories&&d.tickmarkPlacement==="between"?0.5:0;this.ticks={};this.minorTicks={};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;this.stacks={};this.oldStacks={};this.stackExtremes={};this.min=this.max=null;var f,d=this.options.events;pa(this,a.axes)===-1&&(a.axes.push(this),a[c?"xAxis":"yAxis"].push(this)); | ||
110 | +this.series=this.series||[];if(a.inverted&&c&&this.reversed===v)this.reversed=!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)K(this,f,d[f]);if(this.isLog)this.val2lin=ma,this.lin2val=fa},setOptions:function(a){this.options=x(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],x(L[this.isXAxis?"xAxis":"yAxis"],a))},update:function(a, | ||
111 | +b){var c=this.chart,a=c.options[this.xOrY+"Axis"][this.options.index]=x(this.userOptions,a);this.destroy(!0);this._addedPlotLB=this.userMin=this.userMax=v;this.init(c,s(a,{events:v}));c.isDirtyBox=!0;o(b,!0)&&c.redraw()},remove:function(a){var b=this.chart,c=this.xOrY+"Axis";n(this.series,function(a){a.remove(!1)});ga(b.axes,this);ga(b[c],this);b.options[c].splice(this.options.index,1);n(b[c],function(a,b){a.options.index=b});this.destroy();b.isDirtyBox=!0;o(a,!0)&&b.redraw()},defaultLabelFormatter:function(){var a= | ||
112 | +this.axis,b=this.value,c=a.categories,d=this.dateTimeLabelFormat,e=L.lang.numericSymbols,f=e&&e.length,g,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ca(h,this);else if(c)g=b;else if(d)g=Ya(d,b);else if(f&&a>=1E3)for(;f--&&g===v;)c=Math.pow(1E3,f+1),a>=c&&e[f]!==null&&(g=Aa(b/c,-1)+e[f]);g===v&&(g=b>=1E3?Aa(b,0):Aa(b,-1));return g},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;a.stackExtremes={};a.buildStacks();n(a.series,function(c){if(c.visible|| | ||
113 | +!b.options.chart.ignoreHiddenSeries){var d;d=c.options.threshold;var e;a.hasVisibleSeries=!0;a.isLog&&d<=0&&(d=null);if(a.isXAxis){if(d=c.xData,d.length)a.dataMin=J(o(a.dataMin,d[0]),Ja(d)),a.dataMax=r(o(a.dataMax,d[0]),ua(d))}else{c.getExtremes();e=c.dataMax;c=c.dataMin;if(u(c)&&u(e))a.dataMin=J(o(a.dataMin,c),c),a.dataMax=r(o(a.dataMax,e),e);if(u(d))if(a.dataMin>=d)a.dataMin=d,a.ignoreMinPadding=!0;else if(a.dataMax<d)a.dataMax=d,a.ignoreMaxPadding=!0}}})},translate:function(a,b,c,d,e,f){var g= | ||
114 | +this.len,h=1,i=0,j=d?this.oldTransA:this.transA,d=d?this.oldMin:this.min,k=this.minPixelPadding,e=(this.options.ordinal||this.isLog&&e)&&this.lin2val;if(!j)j=this.transA;c&&(h*=-1,i=g);this.reversed&&(h*=-1,i-=h*g);b?(a=a*h+i,a-=k,a=a/j+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),f==="between"&&(f=0.5),a=h*(a-d)*j+i+h*k+(ra(f)?j*f*this.pointRange:0));return a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a- | ||
115 | +(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,b,c,d){var e=this.chart,f=this.left,g=this.top,h,i,j,a=this.translate(a,null,null,c),k=c&&e.oldChartHeight||e.chartHeight,l=c&&e.oldChartWidth||e.chartWidth,m;h=this.transB;c=i=t(a+h);h=j=t(k-a-h);if(isNaN(a))m=!0;else if(this.horiz){if(h=g,j=k-this.bottom,c<f||c>f+this.width)m=!0}else if(c=f,i=l-this.right,h<g||h>g+this.height)m=!0;return m&&!d?null:e.renderer.crispLine(["M",c,h,"L",i,j],b||0)},getPlotBandPath:function(a,b){var c= | ||
116 | +this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],c[5],c[1],c[2]):d=null;return d},getLinearTickPositions:function(a,b,c){for(var d,b=ia(P(b/a)*a),c=ia(wa(c/a)*a),e=[];b<=c;){e.push(b);b=ia(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=t(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=P(b),h,i,j,k,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];f< | ||
117 | +c+1&&!l;f++){i=e.length;for(h=0;h<i&&!l;h++)j=ma(fa(f)*e[h]),j>b&&(!d||k<=c)&&g.push(k),k>c&&(l=!0),k=j}else if(b=fa(b),c=fa(c),a=e[d?"minorTickInterval":"tickInterval"],a=o(a==="auto"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=ob(a,null,nb(a)),g=Na(this.getLinearTickPositions(a,b,c),ma),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval, | ||
118 | +d=[],e;if(this.isLog){e=b.length;for(a=1;a<e;a++)d=d.concat(this.getLogTickPositions(c,b[a-1],b[a],!0))}else if(this.isDatetimeAxis&&a.minorTickInterval==="auto")d=d.concat(Eb(Cb(c),this.min,this.max,a.startOfWeek)),d[0]<this.min&&d.shift();else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var a=this.options,b=this.min,c=this.max,d,e=this.dataMax-this.dataMin>=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===v&&!this.isLog)u(a.min)||u(a.max)? | ||
119 | +this.minRange=null:(n(this.series,function(a){i=a.xData;for(g=j=a.xIncrement?1:i.length-1;g>0;g--)if(h=i[g]-i[g-1],f===v||h<f)f=h}),this.minRange=J(f*5,this.dataMax-this.dataMin));if(c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2;d=[b-d,o(a.min,b-d)];if(e)d[2]=this.dataMin;b=ua(d);c=[b+k,o(a.max,b+k)];if(e)c[2]=this.dataMax;c=Ja(c);c-b<k&&(d[0]=c-k,d[1]=o(a.min,c-k),b=ua(d))}this.min=b;this.max=c},setAxisTranslation:function(a){var b=this.max-this.min,c=0,d,e=0,f=0,g=this.linkedParent,h=this.transA; | ||
120 | +if(this.isXAxis)g?(e=g.minPointOffset,f=g.pointRangePadding):n(this.series,function(a){var g=a.pointRange,h=a.options.pointPlacement,l=a.closestPointRange;g>b&&(g=0);c=r(c,g);e=r(e,ea(h)?0:g/2);f=r(f,h==="on"?0:g);!a.noSharedTooltip&&u(l)&&(d=u(d)?J(d,l):l)}),g=this.ordinalSlope&&d?this.ordinalSlope/d:1,this.minPointOffset=e*=g,this.pointRangePadding=f*=g,this.pointRange=J(c,b),this.closestPointRange=d;if(a)this.oldTransA=h;this.translationSlope=this.transA=h=this.len/(b+f||1);this.transB=this.horiz? | ||
121 | +this.left:this.bottom;this.minPixelPadding=h*e},setTickPositions:function(a){var b=this,c=b.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,l=d.tickInterval,m=d.minTickInterval,p=d.tickPixelInterval,q,aa=b.categories;h?(b.linkedParent=c[g?"xAxis":"yAxis"][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=o(c.min,c.dataMin),b.max=o(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&ka(11,1)):(b.min=o(b.userMin,d.min, | ||
122 | +b.dataMin),b.max=o(b.userMax,d.max,b.dataMax));if(e)!a&&J(b.min,o(b.dataMin,b.min))<=0&&ka(10,1),b.min=ia(ma(b.min)),b.max=ia(ma(b.max));if(b.range&&(b.userMin=b.min=r(b.min,b.max-b.range),b.userMax=b.max,a))b.range=null;b.beforePadding&&b.beforePadding();b.adjustForMinRange();if(!aa&&!b.usePercentage&&!h&&u(b.min)&&u(b.max)&&(c=b.max-b.min)){if(!u(d.min)&&!u(b.userMin)&&k&&(b.dataMin<0||!b.ignoreMinPadding))b.min-=c*k;if(!u(d.max)&&!u(b.userMax)&&j&&(b.dataMax>0||!b.ignoreMaxPadding))b.max+=c*j}b.min=== | ||
123 | +b.max||b.min===void 0||b.max===void 0?b.tickInterval=1:h&&!l&&p===b.linkedParent.options.tickPixelInterval?b.tickInterval=b.linkedParent.tickInterval:(b.tickInterval=o(l,aa?1:(b.max-b.min)*p/r(b.len,p)),!u(l)&&b.len<p&&!this.isRadial&&(q=!0,b.tickInterval/=4));g&&!a&&n(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(!0);b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval); | ||
124 | +if(b.pointRange)b.tickInterval=r(b.pointRange,b.tickInterval);if(!l&&b.tickInterval<m)b.tickInterval=m;if(!f&&!e&&!l)b.tickInterval=ob(b.tickInterval,null,nb(b.tickInterval),d);b.minorTickInterval=d.minorTickInterval==="auto"&&b.tickInterval?b.tickInterval/5:d.minorTickInterval;b.tickPositions=a=d.tickPositions?[].concat(d.tickPositions):i&&i.apply(b,[b.min,b.max]);if(!a)!b.ordinalPositions&&(b.max-b.min)/b.tickInterval>r(2*b.len,200)&&ka(19,!0),a=f?(b.getNonLinearTimeTicks||Eb)(Cb(b.tickInterval, | ||
125 | +d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,b.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),q&&a.splice(1,a.length-2),b.tickPositions=a;if(!h)e=a[0],f=a[a.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&a.shift(),d.endOnTick?b.max=f:b.max+h<f&&a.pop(),a.length===1&&(b.min-=0.001,b.max+=0.001)},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey= | ||
126 | +[this.xOrY,this.pos,this.len].join("-");if(!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this._maxTicksKey,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(e<a){for(;b.length<a;)b.push(ia(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a- | ||
127 | +1);this.max=b[b.length-1]}if(u(d)&&a!==d)this.isDirty=!0}},setScale:function(){var a=this.stacks,b,c,d,e;this.oldMin=this.min;this.oldMax=this.max;this.oldAxisLength=this.len;this.setAxisSize();e=this.len!==this.oldAxisLength;n(this.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)d=!0});if(e||d||this.isLinked||this.forceRedraw||this.userMin!==this.oldUserMin||this.userMax!==this.oldUserMax){if(!this.isXAxis)for(b in a)for(c in a[b])a[b][c].total=null,a[b][c].cum=0;this.forceRedraw= | ||
128 | +!1;this.getSeriesExtremes();this.setTickPositions();this.oldUserMin=this.userMin;this.oldUserMax=this.userMax;if(!this.isDirty)this.isDirty=e||this.min!==this.oldMin||this.max!==this.oldMax}else if(!this.isXAxis){if(this.oldStacks)a=this.stacks=this.oldStacks;for(b in a)for(c in a[b])a[b][c].cum=a[b][c].total}this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=o(c,!0),e=s(e,{min:a,max:b});A(f,"setExtremes",e,function(){f.userMin=a;f.userMax=b;f.eventArgs=e;f.isDirtyExtremes= | ||
129 | +!0;c&&g.redraw(d)})},zoom:function(a,b){this.allowZoomOutside||(u(this.dataMin)&&a<=this.dataMin&&(a=v),u(this.dataMax)&&b>=this.dataMax&&(b=v));this.displayBtn=a!==v||b!==v;this.setExtremes(a,b,!1,v,{trigger:"zoom"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=b.offsetRight||0,e=this.horiz,f,g;this.left=g=o(b.left,a.plotLeft+c);this.top=f=o(b.top,a.plotTop);this.width=c=o(b.width,a.plotWidth-c+d);this.height=b=o(b.height,a.plotHeight);this.bottom=a.chartHeight- | ||
130 | +b-f;this.right=a.chartWidth-c-g;this.len=r(e?c:b,0);this.pos=e?g:f},getExtremes:function(){var a=this.isLog;return{min:a?ia(fa(this.min)):this.min,max:a?ia(fa(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?fa(this.min):this.min,b=b?fa(this.max):this.max;c>a||a===null?a=c:b<a&&(a=b);return this.translate(a,0,1,0,1)},addPlotBand:function(a){this.addPlotBandOrLine(a,"plotBands")},addPlotLine:function(a){this.addPlotBandOrLine(a, | ||
131 | +"plotLines")},addPlotBandOrLine:function(a,b){var c=(new vb(this,a)).render(),d=this.userOptions;c&&(b&&(d[b]=d[b]||[],d[b].push(a)),this.plotLinesAndBands.push(c));return c},autoLabelAlign:function(a){a=(o(a,0)-this.side*90+720)%360;return a>15&&a<165?"right":a>195&&a<345?"left":"center"},getOffset:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,j,k=0,l,m=0,p=d.title,q=d.labels,aa=0,B=b.axisOffset,t=b.clipOffset, | ||
132 | +s=[-1,1,1,-1][h],w,x=1,y=o(q.maxStaggerLines,5),Ha,E,H,C;a.hasData=j=a.hasVisibleSeries||u(a.min)&&u(a.max)&&!!e;a.showAxis=b=j||o(d.showEmpty,!0);a.staggerLines=a.horiz&&q.staggerLines;if(!a.axisGroup)a.gridGroup=c.g("grid").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g("axis").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g("axis-labels").attr({zIndex:q.zIndex||7}).add();if(j||a.isLinked){a.labelAlign=o(q.align||a.autoLabelAlign(q.rotation));n(e,function(b){f[b]?f[b].addLabel():f[b]=new Ma(a, | ||
133 | +b)});if(a.horiz&&!a.staggerLines&&y&&!q.rotation){for(w=a.reversed?[].concat(e).reverse():e;x<y;){j=[];Ha=!1;for(q=0;q<w.length;q++)E=w[q],H=(H=f[E].label&&f[E].label.getBBox())?H.width:0,C=q%x,H&&(E=a.translate(E),j[C]!==v&&E<j[C]&&(Ha=!0),j[C]=E+H);if(Ha)x++;else break}if(x>1)a.staggerLines=x}n(e,function(b){if(h===0||h===2||{1:"left",3:"right"}[h]===a.labelAlign)aa=r(f[b].getLabelSize(),aa)});if(a.staggerLines)aa*=a.staggerLines,a.labelOffset=aa}else for(w in f)f[w].destroy(),delete f[w];if(p&& | ||
134 | +p.text&&p.enabled!==!1){if(!a.axisTitle)a.axisTitle=c.text(p.text,0,0,p.useHTML).attr({zIndex:7,rotation:p.rotation||0,align:p.textAlign||{low:"left",middle:"center",high:"right"}[p.align]}).css(p.style).add(a.axisGroup),a.axisTitle.isNew=!0;if(b)k=a.axisTitle.getBBox()[g?"height":"width"],m=o(p.margin,g?5:10),l=p.offset;a.axisTitle[b?"show":"hide"]()}a.offset=s*o(d.offset,B[h]);a.axisTitleMargin=o(l,aa+m+(h!==2&&aa&&s*d.labels[g?"y":"x"]));B[h]=r(B[h],a.axisTitleMargin+k+s*a.offset);t[i]=r(t[i], | ||
135 | +P(d.lineWidth/2)*2)},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d,d=b.chartHeight-this.bottom-(c?this.height:0)+d;c&&(a*=-1);return b.renderer.crispLine(["M",e?this.left:f,e?d:this.top,"L",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=y(e.style.fontSize||12),d={low:f+(a?0:d), | ||
136 | +middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(this.side===2?i:0);return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.isLog,f=a.isLinked,g=a.tickPositions,h=a.axisTitle,i=a.stacks,j=a.ticks,k=a.minorTicks,l=a.alternateBands,m=d.stackLabels,p=d.alternateGridColor,q=a.tickmarkOffset,o=d.lineWidth,B,r=b.hasRendered&&u(a.oldMin)&&!isNaN(a.oldMin);B=a.hasData; | ||
137 | +var t=a.showAxis,s,w;n([j,k,l],function(a){for(var b in a)a[b].isActive=!1});if(B||f)if(a.minorTickInterval&&!a.categories&&n(a.getMinorTickPositions(),function(b){k[b]||(k[b]=new Ma(a,b,"minor"));r&&k[b].isNew&&k[b].render(null,!0);k[b].render(null,!1,1)}),g.length&&(n(g.slice(1).concat([g[0]]),function(b,c){c=c===g.length-1?0:c+1;if(!f||b>=a.min&&b<=a.max)j[b]||(j[b]=new Ma(a,b)),r&&j[b].isNew&&j[b].render(c,!0),j[b].render(c,!1,1)}),q&&a.min===0&&(j[-1]||(j[-1]=new Ma(a,-1,null,!0)),j[-1].render(-1))), | ||
138 | +p&&n(g,function(b,c){if(c%2===0&&b<a.max)l[b]||(l[b]=new vb(a)),s=b+q,w=g[c+1]!==v?g[c+1]+q:a.max,l[b].options={from:e?fa(s):s,to:e?fa(w):w,color:p},l[b].render(),l[b].isActive=!0}),!a._addedPlotLB)n((d.plotLines||[]).concat(d.plotBands||[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0;n([j,k,l],function(a){var c,d,e=[],f=Fa?Fa.duration||500:0,g=function(){for(d=e.length;d--;)a[e[d]]&&!a[e[d]].isActive&&(a[e[d]].destroy(),delete a[e[d]])};for(c in a)if(!a[c].isActive)a[c].render(c,!1,0), | ||
139 | +a[c].isActive=!1,e.push(c);a===l||!b.hasRendered||!f?g():f&&setTimeout(g,f)});if(o)B=a.getLinePath(o),a.axisLine?a.axisLine.animate({d:B}):a.axisLine=c.path(B).attr({stroke:d.lineColor,"stroke-width":o,zIndex:7}).add(a.axisGroup),a.axisLine[t?"show":"hide"]();if(h&&t)h[h.isNew?"attr":"animate"](a.getTitlePosition()),h.isNew=!1;if(m&&m.enabled){var x,y,d=a.stackTotalGroup;if(!d)a.stackTotalGroup=d=c.g("stack-labels").attr({visibility:"visible",zIndex:6}).add();d.translate(b.plotLeft,b.plotTop);for(x in i)for(y in c= | ||
140 | +i[x],c)c[y].render(d)}a.isDirty=!1},removePlotBandOrLine:function(a){for(var b=this.plotLinesAndBands,c=this.options,d=this.userOptions,e=b.length;e--;)b[e].id===a&&b[e].destroy();n([c.plotLines||[],d.plotLines||[],c.plotBands||[],d.plotBands||[]],function(b){for(e=b.length;e--;)b[e].id===a&&ga(b,b[e])})},setTitle:function(a,b){this.update({title:a},b)},redraw:function(){var a=this.chart.pointer;a.reset&&a.reset(!0);this.render();n(this.plotLinesAndBands,function(a){a.render()});n(this.series,function(a){a.isDirty= | ||
141 | +!0})},buildStacks:function(){var a=this.series,b=a.length;if(!this.isXAxis){for(;b--;)a[b].setStackedPoints();if(this.usePercentage)for(b=0;b<a.length;b++)a[b].setPercentStacks()}},setCategories:function(a,b){this.update({categories:a},b)},destroy:function(a){var b=this,c=b.stacks,d,e=b.plotLinesAndBands;a||$(b);for(d in c)Ka(c[d]),c[d]=null;n([b.ticks,b.minorTicks,b.alternateBands],function(a){Ka(a)});for(a=e.length;a--;)e[a].destroy();n("stackTotalGroup,axisLine,axisGroup,gridGroup,labelGroup,axisTitle".split(","), | ||
142 | +function(a){b[a]&&(b[a]=b[a].destroy())})}};wb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=y(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=a.renderer.label("",0,0,b.shape,null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).add().attr({y:-999});ca||this.label.shadow(b.shadow);this.shared=b.shared},destroy:function(){n(this.crosshairs, | ||
143 | +function(a){a&&a.destroy()});if(this.label)this.label=this.label.destroy();clearTimeout(this.hideTimer);clearTimeout(this.tooltipTimeout)},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden;s(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:g?(2*f.anchorX+c)/3:c,anchorY:g?(f.anchorY+d)/2:d});e.label.attr(f);if(g&&(M(a-f.x)>1||M(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){var a=this,b;clearTimeout(this.hideTimer); | ||
144 | +if(!this.isHidden)b=this.chart.hoverPoints,this.hideTimer=setTimeout(function(){a.label.fadeOut();a.isHidden=!0},o(this.options.hideDelay,500)),b&&n(b,function(a){a.setState()}),this.chart.hoverPoints=null},hideCrosshairs:function(){n(this.crosshairs,function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f=d.plotTop,g=0,h=0,i,a=ja(a);c=a[0].tooltipPos;this.followPointer&&b&&(b.chartX===v&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]);c||(n(a,function(a){i= | ||
145 | +a.series.yAxis;g+=a.plotX;h+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&i?i.top-f:0)}),g/=a.length,h/=a.length,c=[e?d.plotWidth-h:g,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-g:h]);return Na(c,t)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=o(this.options.distance,12),j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,l;d<7&&(d=e+r(j,0)+i);d+a>e+g&&(d-=d+a-(e+g),k=c-b+f-i,l=!0);k<f+5&&(k=f+5,l&&c>=k&&c<=k+b&&(k=c+ | ||
146 | +f+i));k+b>f+h&&(k=r(f,f+h-b-i));return{x:d,y:k}},defaultFormatter:function(a){var b=this.points||ja(this),c=b[0].series,d;d=[c.tooltipHeaderFormatter(b[0])];n(b,function(a){c=a.series;d.push(c.tooltipFormatter&&c.tooltipFormatter(a)||a.point.tooltipFormatter(c.tooltipOptions.pointFormat))});d.push(a.options.footerFormat||"");return d.join("")},refresh:function(a,b){var c=this.chart,d=this.label,e=this.options,f,g,h={},i,j=[];i=e.formatter||this.defaultFormatter;var h=c.hoverPoints,k,l=e.crosshairs, | ||
147 | +m=this.shared;clearTimeout(this.hideTimer);this.followPointer=ja(a)[0].series.tooltipOptions.followPointer;g=this.getAnchor(a,b);f=g[0];g=g[1];m&&(!a.series||!a.series.noSharedTooltip)?(c.hoverPoints=a,h&&n(h,function(a){a.setState()}),n(a,function(a){a.setState("hover");j.push(a.getLabelConfig())}),h={x:a[0].category,y:a[0].y},h.points=j,a=a[0]):h=a.getLabelConfig();i=i.call(h,this);h=a.series;i===!1?this.hide():(this.isHidden&&(Wa(d),d.attr("opacity",1).show()),d.attr({text:i}),k=e.borderColor|| | ||
148 | +a.color||h.color||"#606060",d.attr({stroke:k}),this.updatePosition({plotX:f,plotY:g}),this.isHidden=!1);if(l){l=ja(l);for(d=l.length;d--;)if(m=a.series,e=m[d?"yAxis":"xAxis"],l[d]&&e)if(h=d?o(a.stackY,a.y):a.x,e.isLog&&(h=ma(h)),d===1&&m.modifyValue&&(h=m.modifyValue(h)),e=e.getPlotLinePath(h,1),this.crosshairs[d])this.crosshairs[d].attr({d:e,visibility:"visible"});else{h={"stroke-width":l[d].width||1,stroke:l[d].color||"#C0C0C0",zIndex:l[d].zIndex||2};if(l[d].dashStyle)h.dashstyle=l[d].dashStyle; | ||
149 | +this.crosshairs[d]=c.renderer.path(e).attr(h).add()}}A(c,"tooltipRefresh",{text:i,x:f+c.plotLeft,y:g+c.plotTop,borderColor:k})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||this.getPosition).call(this,c.width,c.height,a);this.move(t(c.x),t(c.y),a.plotX+b.plotLeft,a.plotY+b.plotTop)}};xb.prototype={init:function(a,b){var c=b.chart,d=c.events,e=ca?"":c.zoomType,c=a.inverted,f;this.options=b;this.chart=a;this.zoomX=f=/x/.test(e);this.zoomY=e=/y/.test(e);this.zoomHor= | ||
150 | +f&&!c||e&&c;this.zoomVert=e&&!c||f&&c;this.runChartClick=d&&!!d.click;this.pinchDown=[];this.lastValidTouch={};if(b.tooltip.enabled)a.tooltip=new wb(a,b.tooltip);this.setDOMEvents()},normalize:function(a,b){var c,d,a=a||N.event;if(!a.target)a.target=a.srcElement;a=Xb(a);d=a.touches?a.touches.item(0):a;if(!b)this.chartPosition=b=Wb(this.chart.container);d.pageX===v?(c=r(a.x,a.clientX-b.left),d=a.y):(c=d.pageX-b.left,d=d.pageY-b.top);return s(a,{chartX:t(c),chartY:t(d)})},getCoordinates:function(a){var b= | ||
151 | +{xAxis:[],yAxis:[]};n(this.chart.axes,function(c){b[c.isXAxis?"xAxis":"yAxis"].push({axis:c,value:c.toValue(a[c.horiz?"chartX":"chartY"])})});return b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},runPointActions:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g||!g.noSharedTooltip)){e=[];h=c.length;for(i=0;i<h;i++)if(c[i].visible&& | ||
152 | +c[i].options.enableMouseTracking!==!1&&!c[i].noSharedTooltip&&c[i].tooltipPoints.length&&(b=c[i].tooltipPoints[k])&&b.series)b._dist=M(k-b.clientX),j=J(j,b._dist),e.push(b);for(h=e.length;h--;)e[h]._dist>j&&e.splice(h,1);if(e.length&&e[0].clientX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].clientX}if(g&&g.tracker){if((b=g.tooltipPoints[k])&&b!==f)b.onMouseOver(a)}else d&&d.followPointer&&!d.isHidden&&(a=d.getAnchor([{}],a),d.updatePosition({plotX:a[0],plotY:a[1]}))},reset:function(a){var b=this.chart, | ||
153 | +c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&&ja(b)[0].plotX===v&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());this.hoverX=null}},scaleGroups:function(a,b){var c=this.chart,d;n(c.series,function(e){d=a||e.getPlotBox();e.xAxis&&e.xAxis.zoomEnabled&&(e.group.attr(d),e.markerGroup&&(e.markerGroup.attr(d),e.markerGroup.clip(b?c.clipRect:null)),e.dataLabelsGroup&&e.dataLabelsGroup.attr(d))});c.clipRect.attr(b|| | ||
154 | +c.clipBox)},pinchTranslate:function(a,b,c,d,e,f,g,h){a&&this.pinchTranslateDirection(!0,c,d,e,f,g,h);b&&this.pinchTranslateDirection(!1,c,d,e,f,g,h)},pinchTranslateDirection:function(a,b,c,d,e,f,g,h){var i=this.chart,j=a?"x":"y",k=a?"X":"Y",l="chart"+k,m=a?"width":"height",p=i["plot"+(a?"Left":"Top")],q,o,n=h||1,r=i.inverted,t=i.bounds[a?"h":"v"],u=b.length===1,s=b[0][l],v=c[0][l],w=!u&&b[1][l],x=!u&&c[1][l],y,c=function(){!u&&M(s-w)>20&&(n=h||M(v-x)/M(s-w));o=(p-v)/n+s;q=i["plot"+(a?"Width":"Height")]/ | ||
155 | +n};c();b=o;b<t.min?(b=t.min,y=!0):b+q>t.max&&(b=t.max-q,y=!0);y?(v-=0.8*(v-g[j][0]),u||(x-=0.8*(x-g[j][1])),c()):g[j]=[v,x];r||(f[j]=o-p,f[m]=q);f=r?1/n:n;e[m]=q;e[j]=b;d[r?a?"scaleY":"scaleX":"scale"+k]=n;d["translate"+k]=f*p+(v-f*s)},pinch:function(a){var b=this,c=b.chart,d=b.pinchDown,e=c.tooltip&&c.tooltip.options.followTouchMove,f=a.touches,g=f.length,h=b.lastValidTouch,i=b.zoomHor||b.pinchHor,j=b.zoomVert||b.pinchVert,k=i||j,l=b.selectionMarker,m={},p=g===1&&(b.inClass(a.target,"highcharts-tracker")&& | ||
156 | +c.runTrackerClick||c.runChartClick),q={};(k||e)&&!p&&a.preventDefault();Na(f,function(a){return b.normalize(a)});if(a.type==="touchstart")n(f,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),h.x=[d[0].chartX,d[1]&&d[1].chartX],h.y=[d[0].chartY,d[1]&&d[1].chartY],n(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?"h":"v"],d=a.minPixelPadding,e=a.toPixels(a.dataMin),f=a.toPixels(a.dataMax),g=J(e,f),e=r(e,f);b.min=J(a.pos,g-d);b.max=r(a.pos+a.len,e+d)}});else if(d.length){if(!l)b.selectionMarker= | ||
157 | +l=s({destroy:oa},c.plotBox);b.pinchTranslate(i,j,d,f,m,l,q,h);b.hasPinched=k;b.scaleGroups(m,q);!k&&e&&g===1&&this.runPointActions(b.normalize(a))}},dragStart:function(a){var b=this.chart;b.mouseIsDown=a.type;b.cancelClick=!1;b.mouseDownX=this.mouseDownX=a.chartX;b.mouseDownY=this.mouseDownY=a.chartY},drag:function(a){var b=this.chart,c=b.options.chart,d=a.chartX,e=a.chartY,f=this.zoomHor,g=this.zoomVert,h=b.plotLeft,i=b.plotTop,j=b.plotWidth,k=b.plotHeight,l,m=this.mouseDownX,p=this.mouseDownY;d< | ||
158 | +h?d=h:d>h+j&&(d=h+j);e<i?e=i:e>i+k&&(e=i+k);this.hasDragged=Math.sqrt(Math.pow(m-d,2)+Math.pow(p-e,2));if(this.hasDragged>10){l=b.isInsidePlot(m-h,p-i);if(b.hasCartesianSeries&&(this.zoomX||this.zoomY)&&l&&!this.selectionMarker)this.selectionMarker=b.renderer.rect(h,i,f?1:j,g?1:k,0).attr({fill:c.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add();this.selectionMarker&&f&&(d-=m,this.selectionMarker.attr({width:M(d),x:(d>0?0:d)+m}));this.selectionMarker&&g&&(d=e-p,this.selectionMarker.attr({height:M(d), | ||
159 | +y:(d>0?0:d)+p}));l&&!this.selectionMarker&&c.panning&&b.pan(a,c.panning)}},drop:function(a){var b=this.chart,c=this.hasPinched;if(this.selectionMarker){var d={xAxis:[],yAxis:[],originalEvent:a.originalEvent||a},e=this.selectionMarker,f=e.x,g=e.y,h;if(this.hasDragged||c)n(b.axes,function(a){if(a.zoomEnabled){var b=a.horiz,c=a.toValue(b?f:g),b=a.toValue(b?f+e.width:g+e.height);!isNaN(c)&&!isNaN(b)&&(d[a.xOrY+"Axis"].push({axis:a,min:J(c,b),max:r(c,b)}),h=!0)}}),h&&A(b,"selection",d,function(a){b.zoom(s(a, | ||
160 | +c?{animation:!1}:null))});this.selectionMarker=this.selectionMarker.destroy();c&&this.scaleGroups()}if(b)I(b.container,{cursor:b._cursor}),b.cancelClick=this.hasDragged>10,b.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[]},onContainerMouseDown:function(a){a=this.normalize(a);a.preventDefault&&a.preventDefault();this.dragStart(a)},onDocumentMouseUp:function(a){this.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,d=b.hoverSeries,a=this.normalize(a,c); | ||
161 | +c&&d&&!this.inClass(a.target,"highcharts-tracker")&&!b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.reset()},onContainerMouseLeave:function(){this.reset();this.chartPosition=null},onContainerMouseMove:function(a){var b=this.chart,a=this.normalize(a);a.returnValue=!1;b.mouseIsDown==="mousedown"&&this.drag(a);(this.inClass(a.target,"highcharts-tracker")||b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop))&&!b.openMenu&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c= | ||
162 | +w(a,"class"))if(c.indexOf(b)!==-1)return!0;else if(c.indexOf("highcharts-container")!==-1)return!1;a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries;if(b&&!b.options.stickyTracking&&!this.inClass(a.toElement||a.relatedTarget,"highcharts-tooltip"))b.onMouseOut()},onContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,f=b.inverted,g,h,i,a=this.normalize(a);a.cancelBubble=!0;if(!b.cancelClick)c&&this.inClass(a.target,"highcharts-tracker")?(g=this.chartPosition, | ||
163 | +h=c.plotX,i=c.plotY,s(c,{pageX:g.left+d+(f?b.plotWidth-i:h),pageY:g.top+e+(f?b.plotHeight-h:i)}),A(c.series,"click",s(a,{point:c})),b.hoverPoint&&c.firePointEvent("click",a)):(s(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-e)&&A(b,"click",a))},onContainerTouchStart:function(a){var b=this.chart;a.touches.length===1?(a=this.normalize(a),b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)?(this.runPointActions(a),this.pinch(a)):this.reset()):a.touches.length===2&&this.pinch(a)},onContainerTouchMove:function(a){(a.touches.length=== | ||
164 | +1||a.touches.length===2)&&this.pinch(a)},onDocumentTouchEnd:function(a){this.drop(a)},setDOMEvents:function(){var a=this,b=a.chart.container,c;this._events=c=[[b,"onmousedown","onContainerMouseDown"],[b,"onmousemove","onContainerMouseMove"],[b,"onclick","onContainerClick"],[b,"mouseleave","onContainerMouseLeave"],[z,"mousemove","onDocumentMouseMove"],[z,"mouseup","onDocumentMouseUp"]];jb&&c.push([b,"ontouchstart","onContainerTouchStart"],[b,"ontouchmove","onContainerTouchMove"],[z,"touchend","onDocumentTouchEnd"]); | ||
165 | +n(c,function(b){a["_"+b[2]]=function(c){a[b[2]](c)};b[1].indexOf("on")===0?b[0][b[1]]=a["_"+b[2]]:K(b[0],b[1],a["_"+b[2]])})},destroy:function(){var a=this;n(a._events,function(b){b[1].indexOf("on")===0?b[0][b[1]]=null:$(b[0],b[1],a["_"+b[2]])});delete a._events;clearInterval(a.tooltipTimeout)}};fb.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=o(b.padding,8),f=b.itemMarginTop||0;this.options=b;if(b.enabled)c.baseline=y(d.fontSize)+3+f,c.itemStyle=d,c.itemHiddenStyle=x(d,b.itemHiddenStyle), | ||
166 | +c.itemMarginTop=f,c.padding=e,c.initialItemX=e,c.initialItemY=e-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.lastLineHeight=0,c.render(),K(c.chart,"endResize",function(){c.positionCheckboxes()})},colorizeItem:function(a,b){var c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c,color:c});e&&e.attr({stroke:h});if(f){if(g&&f.isMarker)for(j in g=a.convertAttribs(g), | ||
167 | +g)d=g[j],d!==v&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=e,f.y=d},destroyItem:function(a){var b=a.checkbox;n(["legendItem","legendLine","legendSymbol","legendGroup"],function(b){a[b]&&(a[b]=a[b].destroy())});b&&Ta(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()}, | ||
168 | +positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight;if(b)c=b.translateY,n(this.allItems,function(e){var f=e.checkbox,g;f&&(g=c+f.y+(a||0)+3,I(f,{left:b.translateX+e.legendItemWidth+f.x-20+"px",top:g+"px",display:g>c-6&&g<c+d-6?"":S}))})},renderTitle:function(){var a=this.padding,b=this.options.title,c=0;if(b.text){if(!this.title)this.title=this.chart.renderer.label(b.text,a-3,a-4,null,null,null,null,null,"legend-title").attr({zIndex:1}).css(b.style).add(this.group); | ||
169 | +a=this.title.getBBox();c=a.height;this.offsetWidth=a.width;this.contentGroup.attr({translateY:c})}this.titleHeight=c},renderItem:function(a){var C;var b=this,c=b.chart,d=c.renderer,e=b.options,f=e.layout==="horizontal",g=e.symbolWidth,h=e.symbolPadding,i=b.itemStyle,j=b.itemHiddenStyle,k=b.padding,l=f?o(e.itemDistance,8):0,m=!e.rtl,p=e.width,q=e.itemMarginBottom||0,n=b.itemMarginTop,B=b.initialItemX,t=a.legendItem,u=a.series||a,s=u.options,v=s.showCheckbox,w=e.useHTML;if(!t&&(a.legendGroup=d.g("legend-item").attr({zIndex:1}).add(b.scrollGroup), | ||
170 | +u.drawLegendSymbol(b,a),a.legendItem=t=d.text(e.labelFormat?Ca(e.labelFormat,a):e.labelFormatter.call(a),m?g+h:-h,b.baseline,w).css(x(a.visible?i:j)).attr({align:m?"left":"right",zIndex:2}).add(a.legendGroup),(w?t:a.legendGroup).on("mouseover",function(){a.setState("hover");t.css(b.options.itemHoverStyle)}).on("mouseout",function(){t.css(a.visible?i:j);a.setState()}).on("click",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent("legendItemClick",b,c): | ||
171 | +A(a,"legendItemClick",b,c)}),b.colorizeItem(a,a.visible),s&&v))a.checkbox=U("input",{type:"checkbox",checked:a.selected,defaultChecked:a.selected},e.itemCheckboxStyle,c.container),K(a.checkbox,"click",function(b){A(a,"checkboxClick",{checked:b.target.checked},function(){a.select()})});d=t.getBBox();C=a.legendItemWidth=e.itemWidth||g+h+d.width+l+(v?20:0),e=C;b.itemHeight=g=d.height;if(f&&b.itemX-B+e>(p||c.chartWidth-2*k-B))b.itemX=B,b.itemY+=n+b.lastLineHeight+q,b.lastLineHeight=0;b.maxItemWidth=r(b.maxItemWidth, | ||
172 | +e);b.lastItemY=n+b.itemY+q;b.lastLineHeight=r(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=n+g+q,b.lastLineHeight=g);b.offsetWidth=p||r((f?b.itemX-B-l:e)+k,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,m=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d), | ||
173 | +a.scrollGroup=c.g().add(a.contentGroup);a.renderTitle();e=[];n(b.series,function(a){var b=a.options;if(o(b.showInLegend,b.linkedTo===v?v:!1,!0))e=e.concat(a.legendItems||(b.legendType==="point"?a.data:a))});Kb(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;n(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight+a.titleHeight;h=a.handleOverflow(h);if(l|| | ||
174 | +m){g+=k;h+=k;if(i){if(g>0&&h>0)i[i.isNew?"attr":"animate"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius,l||0).attr({stroke:j.borderColor,"stroke-width":l||0,fill:m||S}).add(d).shadow(j.shadow),i.isNew=!0;i[f?"show":"hide"]()}a.legendWidth=g;a.legendHeight=h;n(e,function(b){a.positionItem(b)});f&&d.align(s({width:g,height:h},j),!0,"spacingBox");b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options, | ||
175 | +f=e.y,f=c.spacingBox.height+(e.verticalAlign==="top"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=o(i.animation,!0),k=i.arrowSize||12,l=this.nav;e.layout==="horizontal"&&(f/=2);g&&(f=J(f,g));if(a>f&&!e.useHTML){this.clipHeight=c=f-20-this.titleHeight;this.pageCount=wa(a/c);this.currentPage=o(this.currentPage,1);this.fullHeight=a;if(!h)h=b.clipRect=d.clipRect(0,0,9999,0),b.contentGroup.clip(h);h.attr({height:c});if(!l)this.nav=l=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle", | ||
176 | +0,0,k,k).on("click",function(){b.scroll(-1,j)}).add(l),this.pager=d.text("",15,10).css(i.style).add(l),this.down=d.symbol("triangle-down",0,0,k,k).on("click",function(){b.scroll(1,j)}).add(l);b.scroll(0);a=f}else if(l)h.attr({height:c.chartHeight}),l.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,h=f.inactiveColor,f=this.pager,i=this.padding;d>c&&(d= | ||
177 | +c);if(d>0)b!==v&&La(b,this.chart),this.nav.attr({translateX:i,translateY:e+7+this.titleHeight,visibility:"visible"}),this.up.attr({fill:d===1?h:g}).css({cursor:d===1?"default":"pointer"}),f.attr({text:d+"/"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width,fill:d===c?h:g}).css({cursor:d===c?"default":"pointer"}),e=-J(e*(d-1),this.fullHeight-e+i)+1,this.scrollGroup.animate({translateY:e}),f.attr({text:d+"/"+c}),this.currentPage=d,this.positionCheckboxes(e)}};/Trident\/7\.0/.test(na)&& | ||
178 | +mb(fb.prototype,"positionItem",function(a,b){var c=this,d=function(){a.call(c,b)};c.chart.renderer.forExport?d():setTimeout(d)});yb.prototype={init:function(a,b){var c,d=a.series;a.series=null;c=x(L,a);c.series=a.series=d;d=c.chart;this.margin=this.splashArray("margin",d);this.spacing=this.splashArray("spacing",d);var e=d.events;this.bounds={h:{},v:{}};this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f=this,g;f.index=Ga.length;Ga.push(f); | ||
179 | +d.reflow!==!1&&K(f,"load",function(){f.initReflow()});if(e)for(g in e)K(f,g,e[g]);f.xAxis=[];f.yAxis=[];f.animation=ca?!1:o(d.animation,!0);f.pointCount=0;f.counters=new Jb;f.firstRender()},initSeries:function(a){var b=this.options.chart;(b=X[a.type||b.type||b.defaultSeriesType])||ka(17,!0);b=new b;b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(b=o(b,!0),A(e,"addSeries",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;e.linkSeries();b&&e.redraw(c)}));return d},addAxis:function(a, | ||
180 | +b,c,d){var e=b?"xAxis":"yAxis",f=this.options;new eb(this,x(a,{index:this[e].length,isX:b}));f[e]=ja(f[e]||{});f[e].push(a);o(c,!0)&&this.redraw(d)},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&n(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,g,h,i=this.isDirtyBox, | ||
181 | +j=c.length,k=j,l=this.renderer,m=l.isHidden(),p=[];La(a,this);m&&this.cloneRenderTo();for(this.layOutTitles();k--;)if(a=c[k],a.options.stacking&&(g=!0,a.isDirty)){h=!0;break}if(h)for(k=j;k--;)if(a=c[k],a.options.stacking)a.isDirty=!0;n(c,function(a){a.isDirty&&a.options.legendType==="point"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;g&&this.getStacks();if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,n(b,function(a){a.setScale()});this.adjustTickAmounts(); | ||
182 | +this.getMargins();n(b,function(a){a.isDirty&&(i=!0)});n(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,p.push(function(){A(a,"afterSetExtremes",s(a.eventArgs,a.getExtremes()));delete a.eventArgs});(i||g)&&a.redraw()})}i&&this.drawChartBox();n(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.reset&&d.reset(!0);l.draw();A(this,"redraw");m&&this.cloneRenderTo(!0);n(p,function(a){a.call()})},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading; | ||
183 | +if(!c)this.loadingDiv=c=U(Ea,{className:"highcharts-loading"},s(d.style,{zIndex:10,display:S}),this.container),this.loadingSpan=U("span",null,d.labelStyle,c);this.loadingSpan.innerHTML=a||b.lang.loading;if(!this.loadingShown)I(c,{opacity:0,display:"",left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+"px",height:this.plotHeight+"px"}),Bb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&Bb(b, | ||
184 | +{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){I(b,{display:S})}});this.loadingShown=!1},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;d<b.length;d++)if(b[d].options.id===a)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++){e=c[d].points||[];for(b=0;b<e.length;b++)if(e[b].id===a)return e[b]}return null},getAxes:function(){var a=this,b=this.options,c=b.xAxis=ja(b.xAxis||{}),b=b.yAxis=ja(b.yAxis||{});n(c,function(a,b){a.index= | ||
185 | +b;a.isX=!0});n(b,function(a,b){a.index=b});c=c.concat(b);n(c,function(b){new eb(a,b)});a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];n(this.series,function(b){a=a.concat(ub(b.points||[],function(a){return a.selected}))});return a},getSelectedSeries:function(){return ub(this.series,function(a){return a.selected})},getStacks:function(){var a=this;n(a.yAxis,function(a){if(a.stacks&&a.hasVisibleSeries)a.oldStacks=a.stacks});n(a.series,function(b){if(b.options.stacking&&(b.visible===!0|| | ||
186 | +a.options.chart.ignoreHiddenSeries===!1))b.stackKey=b.type+o(b.options.stack,"")})},showResetZoom:function(){var a=this,b=L.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,f=c.relativeTo==="chart"?null:"plotBox";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,title:b.resetZoomTitle}).add().align(c.position,!1,f)},zoomOut:function(){var a=this;A(a,"selection",{resetSelection:!0},function(){a.zoom()})},zoom:function(a){var b, | ||
187 | +c=this.pointer,d=!1,e;!a||a.resetSelection?n(this.axes,function(a){b=a.zoom()}):n(a.xAxis.concat(a.yAxis),function(a){var e=a.axis,h=e.isXAxis;if(c[h?"zoomX":"zoomY"]||c[h?"pinchX":"pinchY"])b=e.zoom(a.min,a.max),e.displayBtn&&(d=!0)});e=this.resetZoomButton;if(d&&!e)this.showResetZoom();else if(!d&&T(e))this.resetZoomButton=e.destroy();b&&this.redraw(o(this.options.chart.animation,a&&a.animation,this.pointCount<100))},pan:function(a,b){var c=this,d=c.hoverPoints,e;d&&n(d,function(a){a.setState()}); | ||
188 | +n(b==="xy"?[1,0]:[1],function(b){var d=a[b?"chartX":"chartY"],h=c[b?"xAxis":"yAxis"][0],i=c[b?"mouseDownX":"mouseDownY"],j=(h.pointRange||0)/2,k=h.getExtremes(),l=h.toValue(i-d,!0)+j,i=h.toValue(i+c[b?"plotWidth":"plotHeight"]-d,!0)-j;h.series.length&&l>J(k.dataMin,k.min)&&i<r(k.dataMax,k.max)&&(h.setExtremes(l,i,!1,!1,{trigger:"pan"}),e=!0);c[b?"mouseDownX":"mouseDownY"]=d});e&&c.redraw(!1);I(c.container,{cursor:"move"})},setTitle:function(a,b){var f;var c=this,d=c.options,e;e=d.title=x(d.title, | ||
189 | +a);f=d.subtitle=x(d.subtitle,b),d=f;n([["title",a,e],["subtitle",b,d]],function(a){var b=a[0],d=c[b],e=a[1],a=a[2];d&&e&&(c[b]=d=d.destroy());a&&a.text&&!d&&(c[b]=c.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,"class":"highcharts-"+b,zIndex:a.zIndex||4}).css(a.style).add())});c.layOutTitles()},layOutTitles:function(){var a=0,b=this.title,c=this.subtitle,d=this.options,e=d.title,d=d.subtitle,f=this.spacingBox.width-44;if(b&&(b.css({width:(e.width||f)+"px"}).align(s({y:15},e),!1,"spacingBox"), | ||
190 | +!e.floating&&!e.verticalAlign))a=b.getBBox().height,a>=18&&a<=25&&(a=15);c&&(c.css({width:(d.width||f)+"px"}).align(s({y:a+e.margin},d),!1,"spacingBox"),!d.floating&&!d.verticalAlign&&(a=wa(a+c.getBBox().height)));this.titleOffset=a},getChartSize:function(){var a=this.options.chart,b=this.renderToClone||this.renderTo;this.containerWidth=kb(b,"width");this.containerHeight=kb(b,"height");this.chartWidth=r(0,a.width||this.containerWidth||600);this.chartHeight=r(0,o(a.height,this.containerHeight>19?this.containerHeight: | ||
191 | +400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Ta(b),delete this.renderToClone):(c&&c.parentNode===this.renderTo&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),I(b,{position:"absolute",top:"-9999px",display:"block"}),z.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e="highcharts-"+zb++;if(ea(a))this.renderTo=a=z.getElementById(a); | ||
192 | +a||ka(13,!0);c=y(w(a,"data-highcharts-chart"));!isNaN(c)&&Ga[c]&&Ga[c].destroy();w(a,"data-highcharts-chart",this.index);a.innerHTML="";a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;this.container=a=U(Ea,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},s({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0,"-webkit-tap-highlight-color":"rgba(0,0,0,0)"},b.style),this.renderToClone|| | ||
193 | +a);this._cursor=a.style.cursor;this.renderer=b.forExport?new za(a,c,d,!0):new Va(a,c,d);ca&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.spacing,b,c=this.legend,d=this.margin,e=this.options.legend,f=o(e.margin,10),g=e.x,h=e.y,i=e.align,j=e.verticalAlign,k=this.titleOffset;this.resetMargins();b=this.axisOffset;if(k&&!u(d[0]))this.plotTop=r(this.plotTop,k+this.options.title.margin+a[0]);if(c.display&&!e.floating)if(i==="right"){if(!u(d[1]))this.marginRight=r(this.marginRight,c.legendWidth- | ||
194 | +g+f+a[1])}else if(i==="left"){if(!u(d[3]))this.plotLeft=r(this.plotLeft,c.legendWidth+g+f+a[3])}else if(j==="top"){if(!u(d[0]))this.plotTop=r(this.plotTop,c.legendHeight+h+f+a[0])}else if(j==="bottom"&&!u(d[2]))this.marginBottom=r(this.marginBottom,c.legendHeight-h+f+a[2]);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);this.hasCartesianSeries&&n(this.axes,function(a){a.getOffset()});u(d[3])||(this.plotLeft+=b[3]);u(d[0])|| | ||
195 | +(this.plotTop+=b[0]);u(d[2])||(this.marginBottom+=b[2]);u(d[1])||(this.marginRight+=b[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||kb(d,"width"),h=c.height||kb(d,"height"),a=a?a.target:N;if(!b.hasUserSize&&g&&h&&(a===N||a===z)){if(g!==b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){if(b.container)b.setSize(g,h,!1),b.hasUserSize=null},100);b.containerWidth=g;b.containerHeight=h}}var b=this,c=b.options.chart,d=b.renderTo, | ||
196 | +e;b.reflow=a;K(N,"resize",a);K(b,"destroy",function(){$(N,"resize",a)})},setSize:function(a,b,c){var d=this,e,f,g;d.isResizing+=1;g=function(){d&&A(d,"endResize",null,function(){d.isResizing-=1})};La(c,d);d.oldChartHeight=d.chartHeight;d.oldChartWidth=d.chartWidth;if(u(a))d.chartWidth=e=r(0,t(a)),d.hasUserSize=!!e;if(u(b))d.chartHeight=f=r(0,t(b));I(d.container,{width:e+"px",height:f+"px"});d.setChartSize(!0);d.renderer.setSize(e,f,c);d.maxTicks=null;n(d.axes,function(a){a.isDirty=!0;a.setScale()}); | ||
197 | +n(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();d.redraw(c);d.oldChartHeight=null;A(d,"resize");Fa===!1?g():setTimeout(g,Fa&&Fa.duration||500)},setChartSize:function(a){var b=this.inverted,c=this.renderer,d=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=this.spacing,h=this.clipOffset,i,j,k,l;this.plotLeft=i=t(this.plotLeft);this.plotTop=j=t(this.plotTop);this.plotWidth=k=r(0,t(d-i-this.marginRight));this.plotHeight=l=r(0,t(e-j-this.marginBottom)); | ||
198 | +this.plotSizeX=b?l:k;this.plotSizeY=b?k:l;this.plotBorderWidth=f.plotBorderWidth||0;this.spacingBox=c.spacingBox={x:g[3],y:g[0],width:d-g[3]-g[1],height:e-g[0]-g[2]};this.plotBox=c.plotBox={x:i,y:j,width:k,height:l};d=2*P(this.plotBorderWidth/2);b=wa(r(d,h[3])/2);c=wa(r(d,h[0])/2);this.clipBox={x:b,y:c,width:P(this.plotSizeX-r(d,h[1])/2-b),height:P(this.plotSizeY-r(d,h[2])/2-c)};a||n(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this.spacing,b=this.margin; | ||
199 | +this.plotTop=o(b[0],a[0]);this.marginRight=o(b[1],a[1]);this.marginBottom=o(b[2],a[2]);this.plotLeft=o(b[3],a[3]);this.axisOffset=[0,0,0,0];this.clipOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,p,q=this.plotLeft,o=this.plotTop,n=this.plotWidth, | ||
200 | +r=this.plotHeight,t=this.plotBox,u=this.clipRect,s=this.clipBox;p=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null,null,null,c-p,d-p));else{e={fill:j||S};if(i)e.stroke=a.borderColor,e["stroke-width"]=i;this.chartBackground=b.rect(p/2,p/2,c-p,d-p,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(t):this.plotBackground=b.rect(q,o,n,r,0).attr({fill:k}).add().shadow(a.plotShadow);if(l)h?h.animate(t):this.plotBGImage=b.image(l,q,o,n,r).add();u?u.animate({width:s.width,height:s.height}): | ||
201 | +this.clipRect=b.clipRect(s);if(m)g?g.animate(g.crisp(null,q,o,n,r)):this.plotBorder=b.rect(q,o,n,r,0,-m).attr({stroke:a.plotBorderColor,"stroke-width":m,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,c,d=a.options.series,e,f;n(["inverted","angular","polar"],function(g){c=X[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=X[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},linkSeries:function(){var a=this,b=a.series; | ||
202 | +n(b,function(a){a.linkedSeries.length=0});n(b,function(b){var d=b.options.linkedTo;if(ea(d)&&(d=d===":previous"?a.series[b.index-1]:a.get(d)))d.linkedSeries.push(b),b.linkedParent=d})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,f=d.credits,g;a.setTitle();a.legend=new fb(a,d.legend);a.getStacks();n(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null;n(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox(); | ||
203 | +a.hasCartesianSeries&&n(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g("series-group").attr({zIndex:3}).add();n(a.series,function(a){a.translate();a.setTooltipPoints();a.render()});e.items&&n(e.items,function(b){var d=s(e.style,b.style),f=y(d.left)+a.plotLeft,g=y(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,g).attr({zIndex:2}).css(d).add()});if(f.enabled&&!a.credits)g=f.href,a.credits=c.text(f.text,0,0).on("click",function(){if(g)location.href=g}).attr({align:f.position.align, | ||
204 | +zIndex:8}).css(f.style).add().align(f.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;A(a,"destroy");Ga[a.index]=v;a.renderTo.removeAttribute("data-highcharts-chart");$(a);for(e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();n("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),function(b){var c= | ||
205 | +a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML="",$(d),f&&Ta(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!W&&N==N.top&&z.readyState!=="complete"||ca&&!N.canvg?(ca?Tb.push(function(){a.firstRender()},a.options.global.canvasToolsURL):z.attachEvent("onreadystatechange",function(){z.detachEvent("onreadystatechange",a.firstRender);z.readyState==="complete"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;if(a.isReadyToRender())a.getContainer(), | ||
206 | +A(a,"init"),a.resetMargins(),a.setChartSize(),a.propFromSeries(),a.getAxes(),n(b.series||[],function(b){a.initSeries(b)}),a.linkSeries(),A(a,"beforeRender"),a.pointer=new xb(a,b),a.render(),a.renderer.draw(),c&&c.apply(a,[a]),n(a.callbacks,function(b){b.apply(a,[a])}),a.cloneRenderTo(!0),A(a,"load")},splashArray:function(a,b){var c=b[a],c=T(c)?c:[c,c,c,c];return[o(b[a+"Top"],c[0]),o(b[a+"Right"],c[1]),o(b[a+"Bottom"],c[2]),o(b[a+"Left"],c[3])]}};yb.prototype.callbacks=[];var Pa=function(){};Pa.prototype= | ||
207 | +{init:function(a,b,c){this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors,this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length))a.colorCounter=0;a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=c.pointValKey,a=Pa.prototype.optionsToObject.call(this,a);s(this,a);this.options=this.options?s(this.options,a):a;if(d)this.y=this[d];if(this.x===v&&c)this.x=b===v?c.autoIncrement():b;return this}, | ||
208 | +optionsToObject:function(a){var b={},c=this.series,d=c.pointArrayMap||["y"],e=d.length,f=0,g=0;if(typeof a==="number"||a===null)b[d[0]]=a;else if(Ia(a)){if(a.length>e){c=typeof a[0];if(c==="string")b.name=a[0];else if(c==="number")b.x=a[0];f++}for(;g<e;)b[d[g++]]=a[f++]}else if(typeof a==="object"){b=a;if(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}return b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),ga(b,this),!b.length))a.hoverPoints= | ||
209 | +null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)$(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a="graphic,dataLabel,dataLabelUpper,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total|| | ||
210 | +this.stackTotal}},select:function(a,b){var c=this,d=c.series,e=d.chart,a=o(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=c.options.selected=a;d.options.data[pa(c,d.data)]=c.options;c.setState(a&&"select");b||n(e.getSelectedPoints(),function(a){if(a.selected&&a!==c)a.selected=a.options.selected=!1,d.options.data[pa(a,d.data)]=a.options,a.setState(""),a.firePointEvent("unselect")})})},onMouseOver:function(a){var b=this.series,c=b.chart,d=c.tooltip,e=c.hoverPoint; | ||
211 | +if(e&&e!==this)e.onMouseOut();this.firePointEvent("mouseOver");d&&(!d.shared||b.noSharedTooltip)&&d.refresh(this,a);this.setState("hover");c.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;if(!b||pa(this,b)===-1)this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=o(c.valueDecimals,""),e=c.valuePrefix||"",f=c.valueSuffix||"";n(b.pointArrayMap||["y"],function(b){b="{point."+b;if(e||f)a= | ||
212 | +a.replace(b+"}",e+b+"}"+f);a=a.replace(b+"}",b+":,."+d+"f}")});return Ca(a,{point:this,series:this.series})},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=e.chart,j=e.options,b=o(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a);if(T(a)&&(e.getAttribs(),f))a&&a.marker&&a.marker.symbol?d.graphic=f.destroy():f.attr(d.pointAttr[d.state||""]);g=pa(d,h);e.xData[g]=d.x;e.yData[g]=e.toYData?e.toYData(d):d.y;e.zData[g]=d.z;j.data[g]=d.options;e.isDirty=e.isDirtyData= | ||
213 | +!0;if(!e.fixedBox&&e.hasCartesianSeries)i.isDirtyBox=!0;j.legendType==="point"&&i.legend.destroyItem(d);b&&i.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.points,f=d.chart,g,h=d.data;La(b,f);a=o(a,!0);c.firePointEvent("remove",null,function(){g=pa(c,h);h.length===e.length&&e.splice(g,1);h.splice(g,1);d.options.data.splice(g,1);d.xData.splice(g,1);d.yData.splice(g,1);d.zData.splice(g,1);c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&f.redraw()})},firePointEvent:function(a,b,c){var d=this, | ||
214 | +e=this.series.options;(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a==="click"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});A(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=x(this.series.options.point,this.options).events,b;this.events=a;for(b in a)K(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=Z[d.type].marker&& | ||
215 | +d.options.marker,g=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,j=d.stateMarkerGraphic,k=this.marker||{},l=d.chart,m=this.pointAttr,a=a||"";if(!(a===this.state||this.selected&&a!=="select"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled)||a&&k.states&&k.states[a]&&k.states[a].enabled===!1)){if(this.graphic)e=f&&this.graphic.symbolName&&m[a].r,this.graphic.attr(x(m[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a&&h)e=h.radius,k=k.symbol||d.symbol,j&&j.currentSymbol!==k&&(j=j.destroy()), | ||
216 | +j?j.attr({x:b-e,y:c-e}):(d.stateMarkerGraphic=j=l.renderer.symbol(k,b-e,c-e,2*e,2*e).attr(m[a]).add(d.markerGroup),j.currentSymbol=k);if(j)j[a&&l.isInsidePlot(b,c)?"show":"hide"]()}this.state=a}}};var Q=function(){};Q.prototype={isCartesian:!0,type:"line",pointClass:Pa,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},colorCounter:0,init:function(a,b){var c,d,e=a.series;this.chart=a;this.options=b=this.setOptions(b);this.linkedSeries= | ||
217 | +[];this.bindAxes();s(this,{name:b.name,state:"",pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0});if(ca)b.animation=!1;d=b.events;for(c in d)K(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1);if(this.isCartesian)a.hasCartesianSeries=!0;e.push(this);this._i=e.length-1;Kb(e,function(a,b){return o(a.options.index,a._i)-o(b.options.index,a._i)});n(e,function(a,b){a.index= | ||
218 | +b;a.name=a.name||"Series "+(b+1)})},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&n(["xAxis","yAxis"],function(e){n(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]!==v&&b[e]===d.id||b[e]===v&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0});a[e]||ka(18,!0)})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=o(b,a.pointStart,0);this.pointInterval=o(this.pointInterval,a.pointInterval,1);this.xIncrement=b+this.pointInterval;return b},getSegments:function(){var a= | ||
219 | +-1,b=[],c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else n(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type];this.userOptions=a;a=x(d,c.series,a);this.tooltipOptions=x(b.tooltip,a.tooltip);d.marker===null&&delete a.marker;return a},getColor:function(){var a=this.options,b=this.userOptions, | ||
220 | +c=this.chart.options.colors,d=this.chart.counters,e;e=a.color||Z[this.type].color;if(!e&&!a.colorByPoint)u(b._colorIndex)?a=b._colorIndex:(b._colorIndex=d.color,a=d.color++),e=c[a];this.color=e;d.wrapColor(c.length)},getSymbol:function(){var a=this.userOptions,b=this.options.marker,c=this.chart,d=c.options.symbols,c=c.counters;this.symbol=b.symbol;if(!this.symbol)u(a._symbolIndex)?a=a._symbolIndex:(a._symbolIndex=c.symbol,a=c.symbol++),this.symbol=d[a];if(/^url/.test(this.symbol))b.radius=0;c.wrapSymbol(d.length)}, | ||
221 | +drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options,e;e=d.symbolWidth;var f=this.chart.renderer,g=this.legendGroup,a=a.baseline-t(f.fontMetrics(d.itemStyle.fontSize).b*0.3);if(b.lineWidth){d={"stroke-width":b.lineWidth};if(b.dashStyle)d.dashstyle=b.dashStyle;this.legendLine=f.path(["M",0,a,"L",e,a]).attr(d).add(g)}if(c&&c.enabled)b=c.radius,this.legendSymbol=e=f.symbol(this.symbol,e/2-b,a-b,2*b,2*b).add(g),e.isMarker=!0},addPoint:function(a,b,c,d){var e=this.options,f=this.data, | ||
222 | +g=this.graph,h=this.area,i=this.chart,j=this.xData,k=this.yData,l=this.zData,m=this.xAxis&&this.xAxis.names,p=g&&g.shift||0,q=e.data,r;La(d,i);c&&n([g,h,this.graphNeg,this.areaNeg],function(a){if(a)a.shift=p+1});if(h)h.isArea=!0;b=o(b,!0);d={series:this};this.pointClass.prototype.applyOptions.apply(d,[a]);g=d.x;h=j.length;if(this.requireSorting&&g<j[h-1])for(r=!0;h&&j[h-1]>g;)h--;j.splice(h,0,g);k.splice(h,0,this.toYData?this.toYData(d):d.y);l.splice(h,0,d.z);if(m)m[g]=d.name;q.splice(h,0,a);r&&(this.data.splice(h, | ||
223 | +0,null),this.processData());e.legendType==="point"&&this.generatePoints();c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),j.shift(),k.shift(),l.shift(),q.shift()));this.isDirtyData=this.isDirty=!0;b&&(this.getAttribs(),i.redraw())},setData:function(a,b){var c=this.points,d=this.options,e=this.chart,f=null,g=this.xAxis,h=g&&g.names,i;this.xIncrement=null;this.pointRange=g&&g.categories?1:d.pointRange;this.colorCounter=0;var j=[],k=[],l=[],m=a?a.length:[];i=o(d.turboThreshold,1E3);var p=this.pointArrayMap, | ||
224 | +p=p&&p.length,q=!!this.toYData;if(i&&m>i){for(i=0;f===null&&i<m;)f=a[i],i++;if(ra(f)){h=o(d.pointStart,0);d=o(d.pointInterval,1);for(i=0;i<m;i++)j[i]=h,k[i]=a[i],h+=d;this.xIncrement=h}else if(Ia(f))if(p)for(i=0;i<m;i++)d=a[i],j[i]=d[0],k[i]=d.slice(1,p+1);else for(i=0;i<m;i++)d=a[i],j[i]=d[0],k[i]=d[1];else ka(12)}else for(i=0;i<m;i++)if(a[i]!==v&&(d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a[i]]),j[i]=d.x,k[i]=q?this.toYData(d):d.y,l[i]=d.z,h&&d.name))h[d.x]=d.name;ea(k[0])&& | ||
225 | +ka(14,!0);this.data=[];this.options.data=a;this.xData=j;this.yData=k;this.zData=l;for(i=c&&c.length||0;i--;)c[i]&&c[i].destroy&&c[i].destroy();if(g)g.minRange=g.userMinRange;this.isDirty=this.isDirtyData=e.isDirtyBox=!0;o(b,!0)&&e.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=o(a,!0);if(!c.isRemoving)c.isRemoving=!0,A(c,"remove",null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;d.linkSeries();a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData, | ||
226 | +d=b.length,e;e=0;var f,g,h=this.xAxis,i=this.options,j=i.cropThreshold,k=this.isCartesian;if(k&&!this.isDirty&&!h.isDirty&&!this.yAxis.isDirty&&!a)return!1;if(k&&this.sorted&&(!j||d>j||this.forceCrop))if(a=h.min,h=h.max,b[d-1]<a||b[0]>h)b=[],c=[];else if(b[0]<a||b[d-1]>h)e=this.cropData(this.xData,this.yData,a,h),b=e.xData,c=e.yData,e=e.start,f=!0;for(h=b.length-1;h>=0;h--)d=b[h]-b[h-1],d>0&&(g===v||d<g)?g=d:d<0&&this.requireSorting&&ka(15);this.cropped=f;this.cropStart=e;this.processedXData=b;this.processedYData= | ||
227 | +c;if(i.pointRange===null)this.pointRange=g||1;this.closestPointRange=g},cropData:function(a,b,c,d){var e=a.length,f=0,g=e,h=o(this.cropShoulder,1),i;for(i=0;i<e;i++)if(a[i]>=c){f=r(0,i-h);break}for(;i<e;i++)if(a[i]>d){g=i+h;break}return{xData:a.slice(f,g),yData:b.slice(f,g),start:f,end:g}},generatePoints:function(){var a=this.options.data,b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,j=this.hasGroupedData,k,l=[],m;if(!b&&!j)b=[],b.length= | ||
228 | +a.length,b=this.data=b;for(m=0;m<g;m++)i=h+m,j?l[m]=(new f).init(this,[d[m]].concat(ja(e[m]))):(b[i]?k=b[i]:a[i]!==v&&(b[i]=k=(new f).init(this,a[i],d[m])),l[m]=k);if(b&&(g!==(c=b.length)||j))for(m=0;m<c;m++)if(m===h&&!j&&(m+=g),b[m])b[m].destroyElements(),b[m].plotX=v;this.data=b;this.points=l},setStackedPoints:function(){if(this.options.stacking&&!(this.visible!==!0&&this.chart.options.chart.ignoreHiddenSeries!==!1)){var a=this.processedXData,b=this.processedYData,c=[],d=b.length,e=this.options, | ||
229 | +f=e.threshold,g=e.stack,e=e.stacking,h=this.stackKey,i="-"+h,j=this.negStacks,k=this.yAxis,l=k.stacks,m=k.oldStacks,p,q,o,n,t;for(o=0;o<d;o++){n=a[o];t=b[o];q=(p=j&&t<f)?i:h;l[q]||(l[q]={});if(!l[q][n])m[q]&&m[q][n]?(l[q][n]=m[q][n],l[q][n].total=null):l[q][n]=new Mb(k,k.options.stackLabels,p,n,g,e);q=l[q][n];q.points[this.index]=[q.cum||0];e==="percent"?(p=p?h:i,j&&l[p]&&l[p][n]?(p=l[p][n],q.total=p.total=r(p.total,q.total)+M(t)||0):q.total+=M(t)||0):q.total+=t||0;q.cum=(q.cum||0)+(t||0);q.points[this.index].push(q.cum); | ||
230 | +c[o]=q.cum}if(e==="percent")k.usePercentage=!0;this.stackedYData=c;k.oldStacks={}}},setPercentStacks:function(){var a=this,b=a.stackKey,c=a.yAxis.stacks;n([b,"-"+b],function(b){var d;for(var e=a.xData.length,f,g;e--;)if(f=a.xData[e],d=(g=c[b]&&c[b][f])&&g.points[a.index],f=d)g=g.total?100/g.total:0,f[0]=ia(f[0]*g),f[1]=ia(f[1]*g),a.stackedYData[e]=f[1]})},getExtremes:function(){var a=this.yAxis,b=this.processedXData,c=this.stackedYData||this.processedYData,d=c.length,e=[],f=0,g=this.xAxis.getExtremes(), | ||
231 | +h=g.min,g=g.max,i,j,k,l;for(l=0;l<d;l++)if(j=b[l],k=c[l],i=k!==null&&k!==v&&(!a.isLog||k.length||k>0),j=this.getExtremesFromAll||this.cropped||(b[l+1]||j)>=h&&(b[l-1]||j)<=g,i&&j)if(i=k.length)for(;i--;)k[i]!==null&&(e[f++]=k[i]);else e[f++]=k;this.dataMin=o(void 0,Ja(e));this.dataMax=o(void 0,ua(e))},translate:function(){this.processedXData||this.processData();this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue, | ||
232 | +i=a.pointPlacement,j=i==="between"||ra(i),k=a.threshold,a=0;a<g;a++){var l=f[a],m=l.x,p=l.y,q=l.low,n=e.stacks[(this.negStacks&&p<k?"-":"")+this.stackKey];if(e.isLog&&p<=0)l.y=p=null;l.plotX=c.translate(m,0,0,0,1,i,this.type==="flags");if(b&&this.visible&&n&&n[m])n=n[m],p=n.points[this.index],q=p[0],p=p[1],q===0&&(q=o(k,e.min)),e.isLog&&q<=0&&(q=null),l.total=l.stackTotal=n.total,l.percentage=b==="percent"&&l.y/n.total*100,l.stackY=p,n.setOffset(this.pointXOffset||0,this.barW||0);l.yBottom=u(q)?e.translate(q, | ||
233 | +0,1,0,1):null;h&&(p=this.modifyValue(p,l));l.plotY=typeof p==="number"&&p!==Infinity?e.translate(p,0,1,0,1):v;l.clientX=j?c.translate(m,0,0,0,1):l.plotX;l.negative=l.y<(k||0);l.category=d&&d[l.x]!==v?d[l.x]:l.x}this.getSegments()},setTooltipPoints:function(a){var b=[],c,d,e=this.xAxis,f=e&&e.getExtremes(),g=e?e.tooltipLen||e.len:this.chart.plotSizeX,h,i,j=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints=null;n(this.segments||this.points,function(a){b=b.concat(a)});e&&e.reversed&& | ||
234 | +(b=b.reverse());this.orderTooltipPoints&&this.orderTooltipPoints(b);a=b.length;for(i=0;i<a;i++)if(e=b[i],c=e.x,c>=f.min&&c<=f.max){h=b[i+1];c=d===v?0:d+1;for(d=b[i+1]?J(r(0,P((e.clientX+(h?h.wrappedClientX||h.clientX:g))/2)),g):g;c>=0&&c<=d;)j[c++]=e}this.tooltipPoints=j}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,d=b.dateTimeLabelFormats,e=this.xAxis,f=e&&e.options.type==="datetime",b=b.headerFormat,e=e&&e.closestPointRange,g;if(f&&!c)if(e)for(g in D){if(D[g]>= | ||
235 | +e){c=d[g];break}}else c=d.day;f&&c&&ra(a.key)&&(b=b.replace("{point.key}","{point.key:"+c+"}"));return Ca(b,{point:a,series:this})},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&A(this,"mouseOver");this.setState("hover");a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&A(this,"mouseOut");c&&!a.stickyTracking&&(!c.shared||this.noSharedTooltip)&& | ||
236 | +c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!T(e))e=Z[b.type].animation;h="_sharedClip"+e.duration+e.easing;if(a)a=c[h],e=c[h+"m"],a||(c[h]=a=d.clipRect(s(f,{width:0})),c[h+"m"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?c.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey=h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+"m"].animate({width:c.plotSizeX+ | ||
237 | +99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()},e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group;c&&this.options.clip!==!1&&(c.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+"m"]=a[b+"m"].destroy())},100)},drawPoints:function(){var a,b=this.points,c=this.chart,d,e,f,g,h,i,j,k,l=this.options.marker,m,n=this.markerGroup;if(l.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g= | ||
238 | +b[f],d=P(g.plotX),e=g.plotY,k=g.graphic,i=g.marker||{},a=l.enabled&&i.enabled===v||i.enabled,m=c.isInsidePlot(t(d),e,c.inverted),a&&e!==v&&!isNaN(e)&&g.y!==null)if(a=g.pointAttr[g.selected?"select":""],h=a.r,i=o(i.symbol,this.symbol),j=i.indexOf("url")===0,k)k.attr({visibility:m?W?"inherit":"visible":"hidden"}).animate(s({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{}));else{if(m&&(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(n)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a, | ||
239 | +b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=o(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=a.options,c=Z[a.type].marker?b.marker:b,d=c.states,e=d.hover,f,g=a.color,h={stroke:g,fill:g},i=a.points||[],j=[],k,l=a.pointAttrToOptions,m=b.negativeColor,p=c.lineColor,q;b.marker?(e.radius=e.radius||c.radius+2,e.lineWidth=e.lineWidth||c.lineWidth+1):e.color=e.color||qa(e.color||g).brighten(e.brightness).get();j[""]=a.convertAttribs(c, | ||
240 | +h);n(["hover","select"],function(b){j[b]=a.convertAttribs(d[b],j[""])});a.pointAttr=j;for(g=i.length;g--;){h=i[g];if((c=h.options&&h.options.marker||h.options)&&c.enabled===!1)c.radius=0;if(h.negative&&m)h.color=h.fillColor=m;f=b.colorByPoint||h.color;if(h.options)for(q in l)u(c[l[q]])&&(f=!0);if(f){c=c||{};k=[];d=c.states||{};f=d.hover=d.hover||{};if(!b.marker)f.color=qa(f.color||h.color).brighten(f.brightness||e.brightness).get();k[""]=a.convertAttribs(s({color:h.color,fillColor:h.color,lineColor:p=== | ||
241 | +null?h.color:v},c),j[""]);k.hover=a.convertAttribs(d.hover,j.hover,k[""]);k.select=a.convertAttribs(d.select,j.select,k[""])}else k=j;h.pointAttr=k}},update:function(a,b){var c=this.chart,d=this.type,e=X[d].prototype,f,a=x(this.userOptions,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},a);this.remove(!1);for(f in e)e.hasOwnProperty(f)&&(this[f]=v);s(this,X[a.type||d].prototype);this.init(c,a);o(b,!0)&&c.redraw(!1)},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\/533/.test(na), | ||
242 | +d,e,f=a.data||[],g,h,i;A(a,"destroy");$(a);n(["xAxis","yAxis"],function(b){if(i=a[b])ga(i.series,a),i.isDirty=i.forceRedraw=!0,i.stacks={}});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout);n("area,graph,dataLabelsGroup,group,markerGroup,tracker,graphNeg,areaNeg,posClip,negClip".split(","),function(b){a[b]&&(d=c&&b==="group"?"hide":"destroy",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;ga(b.series, | ||
243 | +a);for(h in a)delete a[h]},drawDataLabels:function(){var a=this,b=a.options,c=b.cursor,d=b.dataLabels,b=a.points,e,f,g,h;if(d.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(d),h=a.plotGroup("dataLabelsGroup","data-labels",a.visible?"visible":"hidden",d.zIndex||6),f=d,n(b,function(b){var j,k=b.dataLabel,l,m,n=b.connector,q=!0;e=b.options&&b.options.dataLabels;j=o(e&&e.enabled,f.enabled);if(k&&!j)b.dataLabel=k.destroy();else if(j){d=x(f,e);j=d.rotation;l=b.getLabelConfig();g=d.format? | ||
244 | +Ca(d.format,l):d.formatter.call(l,d);d.style.color=o(d.color,d.style.color,a.color,"black");if(k)if(u(g))k.attr({text:g}),q=!1;else{if(b.dataLabel=k=k.destroy(),n)b.connector=n.destroy()}else if(u(g)){k={fill:d.backgroundColor,stroke:d.borderColor,"stroke-width":d.borderWidth,r:d.borderRadius||0,rotation:j,padding:d.padding,zIndex:1};for(m in k)k[m]===v&&delete k[m];k=b.dataLabel=a.chart.renderer[j?"text":"label"](g,0,-999,null,null,null,d.useHTML).attr(k).css(s(d.style,c&&{cursor:c})).add(h).shadow(d.shadow)}k&& | ||
245 | +a.alignDataLabel(b,k,d,null,q)}})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=o(a.plotX,-999),i=o(a.plotY,-999),j=b.getBBox();if(a=this.visible&&f.isInsidePlot(a.plotX,a.plotY,g))d=s({x:g?f.plotWidth-i:h,y:t(g?f.plotHeight-h:i),width:0,height:0},d),s(c,{width:j.width,height:j.height}),c.rotation?(g={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](g)):(b.align(c,null,d),g=b.alignAttr,o(c.overflow,"justify")==="justify"?this.justifyDataLabel(b,c, | ||
246 | +g,j,d,e):o(c.crop,!0)&&(a=f.isInsidePlot(g.x,g.y)&&f.isInsidePlot(g.x+j.width,g.y+j.height)));a||b.attr({y:-999})},justifyDataLabel:function(a,b,c,d,e,f){var g=this.chart,h=b.align,i=b.verticalAlign,j,k;j=c.x;if(j<0)h==="right"?b.align="left":b.x=-j,k=!0;j=c.x+d.width;if(j>g.plotWidth)h==="left"?b.align="right":b.x=g.plotWidth-j,k=!0;j=c.y;if(j<0)i==="bottom"?b.verticalAlign="top":b.y=-j,k=!0;j=c.y+d.height;if(j>g.plotHeight)i==="top"?b.verticalAlign="bottom":b.y=g.plotHeight-j,k=!0;if(k)a.placed= | ||
247 | +!f,a.align(b,null,e)},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;n(a,function(e,f){var g=e.plotX,h=e.plotY,i;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?"L":"M"),d&&f&&(i=a[f-1],d==="right"?c.push(i.plotX,h):d==="center"?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];n(a.segments,function(e){c=a.getSegmentPath(e);e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints= | ||
248 | +d;return a.graphPath=b},drawGraph:function(){var a=this,b=this.options,c=[["graph",b.lineColor||this.color]],d=b.lineWidth,e=b.dashStyle,f=b.linecap!=="square",g=this.getGraphPath(),h=b.negativeColor;h&&c.push(["graphNeg",h]);n(c,function(c,h){var k=c[0],l=a[k];if(l)Wa(l),l.animate({d:g});else if(d&&g.length)l={stroke:c[1],"stroke-width":d,zIndex:1},e?l.dashstyle=e:f&&(l["stroke-linecap"]=l["stroke-linejoin"]="round"),a[k]=a.chart.renderer.path(g).attr(l).add(a.group).shadow(!h&&b.shadow)})},clipNeg:function(){var a= | ||
249 | +this.options,b=this.chart,c=b.renderer,d=a.negativeColor||a.negativeFillColor,e,f=this.graph,g=this.area,h=this.posClip,i=this.negClip;e=b.chartWidth;var j=b.chartHeight,k=r(e,j),l=this.yAxis;if(d&&(f||g)){d=t(l.toPixels(a.threshold||0,!0));a={x:0,y:0,width:k,height:d};k={x:0,y:d,width:k,height:k};if(b.inverted)a.height=k.y=b.plotWidth-d,c.isVML&&(a={x:b.plotWidth-d-b.plotLeft,y:0,width:e,height:j},k={x:d+b.plotLeft-e,y:0,width:b.plotLeft+d,height:e});l.reversed?(b=k,e=a):(b=a,e=k);h?(h.animate(b), | ||
250 | +i.animate(e)):(this.posClip=h=c.clipRect(b),this.negClip=i=c.clipRect(e),f&&this.graphNeg&&(f.clip(h),this.graphNeg.clip(i)),g&&(g.clip(h),this.areaNeg.clip(i)))}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};n(["group","markerGroup"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;if(b.xAxis)K(c,"resize",a),K(b,"destroy",function(){$(c,"resize",a)}),a(),b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],g=!f;g&&(this[a]=f=this.chart.renderer.g(b).attr({visibility:c, | ||
251 | +zIndex:d||0.1}).add(e));f[g?"attr":"animate"](this.getPlotBox());return f},getPlotBox:function(){return{translateX:this.xAxis?this.xAxis.left:this.chart.plotLeft,translateY:this.yAxis?this.yAxis.top:this.chart.plotTop,scaleX:1,scaleY:1}},render:function(){var a=this.chart,b,c=this.options,d=c.animation&&!!this.animate&&a.renderer.isSVG,e=this.visible?"visible":"hidden",f=c.zIndex,g=this.hasRendered,h=a.seriesGroup;b=this.plotGroup("group","series",e,f,h);this.markerGroup=this.plotGroup("markerGroup", | ||
252 | +"markers",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=this.isCartesian?a.inverted:!1;this.drawGraph&&(this.drawGraph(),this.clipNeg());this.drawDataLabels();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&&b.clip(a.clipRect);d?this.animate():g||this.afterAnimate();this.isDirty=this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group,d=this.xAxis, | ||
253 | +e=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:o(d&&d.left,a.plotLeft),translateY:o(e&&e.top,a.plotTop)}));this.translate();this.setTooltipPoints(!0);this.render();b&&A(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph,d=this.graphNeg,e=b.states,b=b.lineWidth,a=a||"";if(this.state!==a)this.state=a,e[a]&&e[a].enabled===!1||(a&&(b=e[a].lineWidth||b+1),c&&!c.dashstyle&&(a={"stroke-width":b},c.attr(a),d&&d.attr(a)))},setVisible:function(a, | ||
254 | +b){var c=this,d=c.chart,e=c.legendItem,f,g=d.options.chart.ignoreHiddenSeries,h=c.visible;f=(c.visible=a=c.userOptions.visible=a===v?!h:a)?"show":"hide";n(["group","dataLabelsGroup","markerGroup","tracker"],function(a){if(c[a])c[a][f]()});if(d.hoverSeries===c)c.onMouseOut();e&&d.legend.colorizeItem(c,a);c.isDirty=!0;c.options.stacking&&n(d.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});n(c.linkedSeries,function(b){b.setVisible(a,!1)});if(g)d.isDirtyBox=!0;b!==!1&&d.redraw();A(c, | ||
255 | +f)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===v?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;A(this,a?"select":"unselect")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.pointer,h=f.renderer,i=f.options.tooltip.snap,j=a.tracker,k=b.cursor,l=k&&{cursor:k},k=a.singlePoints,m,p=function(){if(f.hoverSeries!==a)a.onMouseOver()};if(e&&!c)for(m= | ||
256 | +e+1;m--;)d[m]==="M"&&d.splice(m+1,0,d[m+1]-i,d[m+2],"L"),(m&&d[m]==="M"||m===e)&&d.splice(m,0,"L",d[m-2]+i,d[m-1]);for(m=0;m<k.length;m++)e=k[m],d.push("M",e.plotX-i,e.plotY,"L",e.plotX+i,e.plotY);j?j.attr({d:d}):(a.tracker=h.path(d).attr({"stroke-linejoin":"round",visibility:a.visible?"visible":"hidden",stroke:Qb,fill:c?Qb:S,"stroke-width":b.lineWidth+(c?0:2*i),zIndex:2}).add(a.group),n([a.tracker,a.markerGroup],function(a){a.addClass("highcharts-tracker").on("mouseover",p).on("mouseout",function(a){g.onTrackerMouseOut(a)}).css(l); | ||
257 | +if(jb)a.on("touchstart",p)}))}};G=ha(Q);X.line=G;Z.area=x(Y,{threshold:0});G=ha(Q,{type:"area",getSegments:function(){var a=[],b=[],c=[],d=this.xAxis,e=this.yAxis,f=e.stacks[this.stackKey],g={},h,i,j=this.points,k=this.options.connectNulls,l,m,p;if(this.options.stacking&&!this.cropped){for(m=0;m<j.length;m++)g[j[m].x]=j[m];for(p in f)f[p].total!==null&&c.push(+p);c.sort(function(a,b){return a-b});n(c,function(a){if(!k||g[a]&&g[a].y!==null)g[a]?b.push(g[a]):(h=d.translate(a),l=f[a].percent?f[a].total? | ||
258 | +f[a].cum*100/f[a].total:0:f[a].cum,i=e.toPixels(l,!0),b.push({y:null,plotX:h,clientX:h,plotY:i,yBottom:i,onMouseOver:oa}))});b.length&&a.push(b)}else Q.prototype.getSegments.call(this),a=this.segments;this.segments=a},getSegmentPath:function(a){var b=Q.prototype.getSegmentPath.call(this,a),c=[].concat(b),d,e=this.options;d=b.length;var f=this.yAxis.getThreshold(e.threshold),g;d===3&&c.push("L",b[1],b[2]);if(e.stacking&&!this.closedStacks)for(d=a.length-1;d>=0;d--)g=o(a[d].yBottom,f),d<a.length-1&& | ||
259 | +e.step&&c.push(a[d+1].plotX,g),c.push(a[d].plotX,g);else this.closeSegment(c,a,f);this.areaPath=this.areaPath.concat(c);return b},closeSegment:function(a,b,c){a.push("L",b[b.length-1].plotX,c,"L",b[0].plotX,c)},drawGraph:function(){this.areaPath=[];Q.prototype.drawGraph.apply(this);var a=this,b=this.areaPath,c=this.options,d=c.negativeColor,e=c.negativeFillColor,f=[["area",this.color,c.fillColor]];(d||e)&&f.push(["areaNeg",d,e]);n(f,function(d){var e=d[0],f=a[e];f?f.animate({d:b}):a[e]=a.chart.renderer.path(b).attr({fill:o(d[2], | ||
260 | +qa(d[1]).setOpacity(o(c.fillOpacity,0.75)).get()),zIndex:0}).add(a.group)})},drawLegendSymbol:function(a,b){b.legendSymbol=this.chart.renderer.rect(0,a.baseline-11,a.options.symbolWidth,12,2).attr({zIndex:3}).add(b.legendGroup)}});X.area=G;Z.spline=x(Y);F=ha(Q,{type:"spline",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,j,k;if(f&&g){a=f.plotY;j=g.plotX;var g=g.plotY,l;h=(1.5*d+f.plotX)/2.5;i=(1.5*e+a)/2.5;j=(1.5*d+j)/2.5;k=(1.5*e+g)/2.5;l=(k-i)*(j-d)/(j-h)+e-k;i+=l; | ||
261 | +k+=l;i>a&&i>e?(i=r(a,e),k=2*e-i):i<a&&i<e&&(i=J(a,e),k=2*e-i);k>g&&k>e?(k=r(g,e),i=2*e-k):k<g&&k<e&&(k=J(g,e),i=2*e-k);b.rightContX=j;b.rightContY=k}c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=["M",d,e];return b}});X.spline=F;Z.areaspline=x(Z.area);la=G.prototype;F=ha(F,{type:"areaspline",closedStacks:!0,getSegmentPath:la.getSegmentPath,closeSegment:la.closeSegment,drawGraph:la.drawGraph,drawLegendSymbol:la.drawLegendSymbol});X.areaspline= | ||
262 | +F;Z.column=x(Y,{borderColor:"#FFFFFF",borderWidth:1,borderRadius:0,groupPadding:0.2,marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},stickyTracking:!1,threshold:0});F=ha(Q,{type:"column",pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",r:"borderRadius"},cropShoulder:0,trackerGroups:["group", | ||
263 | +"dataLabelsGroup"],negStacks:!0,init:function(){Q.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0})},getColumnMetrics:function(){var a=this,b=a.options,c=a.xAxis,d=a.yAxis,e=c.reversed,f,g={},h,i=0;b.grouping===!1?i=1:n(a.chart.series,function(b){var c=b.options,e=b.yAxis;if(b.type===a.type&&b.visible&&d.len===e.len&&d.pos===e.pos)c.stacking?(f=b.stackKey,g[f]===v&&(g[f]=i++),h=g[f]):c.grouping!==!1&&(h=i++),b.columnIndex= | ||
264 | +h});var c=J(M(c.transA)*(c.ordinalSlope||b.pointRange||c.closestPointRange||1),c.len),j=c*b.groupPadding,k=(c-2*j)/i,l=b.pointWidth,b=u(l)?(k-l)/2:k*b.pointPadding,l=o(l,k-2*b);return a.columnMetrics={width:l,offset:b+(j+((e?i-(a.columnIndex||0):a.columnIndex)||0)*k-c/2)*(e?-1:1)}},translate:function(){var a=this.chart,b=this.options,c=b.borderWidth,d=this.yAxis,e=this.translatedThreshold=d.getThreshold(b.threshold),f=o(b.minPointLength,5),b=this.getColumnMetrics(),g=b.width,h=this.barW=wa(r(g,1+ | ||
265 | +2*c)),i=this.pointXOffset=b.offset,j=-(c%2?0.5:0),k=c%2?0.5:1;a.renderer.isVML&&a.inverted&&(k+=1);Q.prototype.translate.apply(this);n(this.points,function(a){var b=o(a.yBottom,e),c=J(r(-999-b,a.plotY),d.len+999+b),n=a.plotX+i,u=h,s=J(c,b),v,c=r(c,b)-s;M(c)<f&&f&&(c=f,s=t(M(s-e)>f?b-f:e-(d.translate(a.y,0,1,0,1)<=e?f:0)));a.barX=n;a.pointWidth=g;b=M(n)<0.5;u=t(n+u)+j;n=t(n)+j;u-=n;v=M(s)<0.5;c=t(s+c)+k;s=t(s)+k;c-=s;b&&(n+=1,u-=1);v&&(s-=1,c+=1);a.shapeType="rect";a.shapeArgs={x:n,y:s,width:u,height:c}})}, | ||
266 | +getSymbol:oa,drawLegendSymbol:G.prototype.drawLegendSymbol,drawGraph:oa,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;n(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==v&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(Wa(g),g.animate(x(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected?"select":""]).add(a.group).shadow(b.shadow,null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){var a=this,b=a.chart,c=b.pointer,d=a.options.cursor, | ||
267 | +e=d&&{cursor:d},f=function(c){var d=c.target,e;if(b.hoverSeries!==a)a.onMouseOver();for(;d&&!e;)e=d.point,d=d.parentNode;if(e!==v&&e!==b.hoverPoint)e.onMouseOver(c)};n(a.points,function(a){if(a.graphic)a.graphic.element.point=a;if(a.dataLabel)a.dataLabel.element.point=a});if(!a._hasTracking)n(a.trackerGroups,function(b){if(a[b]&&(a[b].addClass("highcharts-tracker").on("mouseover",f).on("mouseout",function(a){c.onTrackerMouseOut(a)}).css(e),jb))a[b].on("touchstart",f)}),a._hasTracking=!0},alignDataLabel:function(a, | ||
268 | +b,c,d,e){var f=this.chart,g=f.inverted,h=a.dlBox||a.shapeArgs,i=a.below||a.plotY>o(this.translatedThreshold,f.plotSizeY),j=o(c.inside,!!this.options.stacking);if(h&&(d=x(h),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!j))g?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0);c.align=o(c.align,!g||j?"center":i?"right":"left");c.verticalAlign=o(c.verticalAlign,g||j?"middle":i?"top":"bottom");Q.prototype.alignDataLabel.call(this,a,b,c,d,e)},animate:function(a){var b= | ||
269 | +this.yAxis,c=this.options,d=this.chart.inverted,e={};if(W)a?(e.scaleY=0.001,a=J(b.pos+b.len,r(b.pos,b.toPixels(c.threshold))),d?e.translateX=a-b.len:e.translateY=a,this.group.attr(e)):(e.scaleY=1,e[d?"translateX":"translateY"]=b.pos,this.group.animate(e,this.options.animation),this.animate=null)},remove:function(){var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0});Q.prototype.remove.apply(a,arguments)}});X.column=F;Z.bar=x(Z.column);la=ha(F,{type:"bar",inverted:!0}); | ||
270 | +X.bar=la;Z.scatter=x(Y,{lineWidth:0,tooltip:{headerFormat:'<span style="font-size: 10px; color:{series.color}">{series.name}</span><br/>',pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>",followPointer:!0},stickyTracking:!1});la=ha(Q,{type:"scatter",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:["markerGroup"],takeOrdinalPosition:!1,drawTracker:F.prototype.drawTracker,setTooltipPoints:oa});X.scatter=la;Z.pie=x(Y,{borderColor:"#FFFFFF",borderWidth:1,center:[null,null],clip:!1, | ||
271 | +colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}});Y={type:"pie",isCartesian:!1,pointClass:ha(Pa,{init:function(){Pa.prototype.init.apply(this,arguments);var a=this,b;if(a.y<0)a.y=null;s(a,{visible:a.visible!==!1,name:o(a.name,"Slice")});b=function(b){a.slice(b.type==="select")}; | ||
272 | +K(a,"select",b);K(a,"unselect",b);return a},setVisible:function(a){var b=this,c=b.series,d=c.chart,e;b.visible=b.options.visible=a=a===v?!b.visible:a;c.options.data[pa(b,c.data)]=b.options;e=a?"show":"hide";n(["graphic","dataLabel","connector","shadowGroup"],function(a){if(b[a])b[a][e]()});b.legendItem&&d.legend.colorizeItem(b,a);if(!c.isDirty&&c.options.ignoreHiddenPoint)c.isDirty=!0,d.redraw()},slice:function(a,b,c){var d=this.series;La(c,d.chart);o(b,!0);this.sliced=this.options.sliced=a=u(a)? | ||
273 | +a:!this.sliced;d.options.data[pa(this,d.data)]=this.options;a=a?this.slicedTranslation:{translateX:0,translateY:0};this.graphic.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),requireSorting:!1,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:oa,animate:function(a){var b=this,c=b.points,d=b.startAngleRad;if(!a)n(c,function(a){var c=a.graphic,a=a.shapeArgs;c&&(c.attr({r:b.center[3]/ | ||
274 | +2,start:d,end:d}),c.animate({r:a.r,start:a.start,end:a.end},b.options.animation))}),b.animate=null},setData:function(a,b){Q.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();o(b,!0)&&this.chart.redraw()},generatePoints:function(){var a,b=0,c,d,e,f=this.options.ignoreHiddenPoint;Q.prototype.generatePoints.call(this);c=this.points;d=c.length;for(a=0;a<d;a++)e=c[a],b+=f&&!e.visible?0:e.y;this.total=b;for(a=0;a<d;a++)e=c[a],e.percentage=b>0?e.y/b*100:0,e.total=b},getCenter:function(){var a= | ||
275 | +this.options,b=this.chart,c=2*(a.slicedOffset||0),d,e=b.plotWidth-2*c,f=b.plotHeight-2*c,b=a.center,a=[o(b[0],"50%"),o(b[1],"50%"),a.size||"100%",a.innerSize||0],g=J(e,f),h;return Na(a,function(a,b){h=/%$/.test(a);d=b<2||b===2&&h;return(h?[e,f,g,g][b]*y(a)/100:a)+(d?c:0)})},translate:function(a){this.generatePoints();var b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g,h,i=c.startAngle||0,j=this.startAngleRad=xa/180*(i-90),i=(this.endAngleRad=xa/180*((c.endAngle||i+360)-90))-j,k=this.points, | ||
276 | +l=c.dataLabels.distance,c=c.ignoreHiddenPoint,m,n=k.length,o;if(!a)this.center=a=this.getCenter();this.getX=function(b,c){h=R.asin((b-a[1])/(a[2]/2+l));return a[0]+(c?-1:1)*V(h)*(a[2]/2+l)};for(m=0;m<n;m++){o=k[m];f=j+b*i;if(!c||o.visible)b+=o.percentage/100;g=j+b*i;o.shapeType="arc";o.shapeArgs={x:a[0],y:a[1],r:a[2]/2,innerR:a[3]/2,start:t(f*1E3)/1E3,end:t(g*1E3)/1E3};h=(g+f)/2;h>0.75*i&&(h-=2*xa);o.slicedTranslation={translateX:t(V(h)*d),translateY:t(ba(h)*d)};f=V(h)*a[2]/2;g=ba(h)*a[2]/2;o.tooltipPos= | ||
277 | +[a[0]+f*0.7,a[1]+g*0.7];o.half=h<-xa/2||h>xa/2?1:0;o.angle=h;e=J(e,l/2);o.labelPos=[a[0]+f+V(h)*l,a[1]+g+ba(h)*l,a[0]+f+V(h)*e,a[1]+g+ba(h)*e,a[0]+f,a[1]+g,l<0?"center":o.half?"right":"left",h]}},setTooltipPoints:oa,drawGraph:null,drawPoints:function(){var a=this,b=a.chart.renderer,c,d,e=a.options.shadow,f,g;if(e&&!a.shadowGroup)a.shadowGroup=b.g("shadow").add(a.group);n(a.points,function(h){d=h.graphic;g=h.shapeArgs;f=h.shadowGroup;if(e&&!f)f=h.shadowGroup=b.g("shadow").add(a.shadowGroup);c=h.sliced? | ||
278 | +h.slicedTranslation:{translateX:0,translateY:0};f&&f.attr(c);d?d.animate(s(g,c)):h.graphic=d=b.arc(g).setRadialReference(a.center).attr(h.pointAttr[h.selected?"select":""]).attr({"stroke-linejoin":"round"}).attr(c).add(a.group).shadow(e,f);h.visible===!1&&h.setVisible(!1)})},sortByAngle:function(a,b){a.sort(function(a,d){return a.angle!==void 0&&(d.angle-a.angle)*b})},drawDataLabels:function(){var a=this,b=a.data,c,d=a.chart,e=a.options.dataLabels,f=o(e.connectorPadding,10),g=o(e.connectorWidth,1), | ||
279 | +h=d.plotWidth,d=d.plotHeight,i,j,k=o(e.softConnector,!0),l=e.distance,m=a.center,p=m[2]/2,q=m[1],u=l>0,s,v,w,x,y=[[],[]],z,A,E,H,C,D=[0,0,0,0],J=function(a,b){return b.y-a.y};if(a.visible&&(e.enabled||a._hasPointLabels)){Q.prototype.drawDataLabels.apply(a);n(b,function(a){a.dataLabel&&y[a.half].push(a)});for(H=0;!x&&b[H];)x=b[H]&&b[H].dataLabel&&(b[H].dataLabel.getBBox().height||21),H++;for(H=2;H--;){var b=[],I=[],G=y[H],K=G.length,F;a.sortByAngle(G,H-0.5);if(l>0){for(C=q-p-l;C<=q+p+l;C+=x)b.push(C); | ||
280 | +v=b.length;if(K>v){c=[].concat(G);c.sort(J);for(C=K;C--;)c[C].rank=C;for(C=K;C--;)G[C].rank>=v&&G.splice(C,1);K=G.length}for(C=0;C<K;C++){c=G[C];w=c.labelPos;c=9999;var N,L;for(L=0;L<v;L++)N=M(b[L]-w[1]),N<c&&(c=N,F=L);if(F<C&&b[C]!==null)F=C;else for(v<K-C+F&&b[C]!==null&&(F=v-K+C);b[F]===null;)F++;I.push({i:F,y:b[F]});b[F]=null}I.sort(J)}for(C=0;C<K;C++){c=G[C];w=c.labelPos;s=c.dataLabel;E=c.visible===!1?"hidden":"visible";c=w[1];if(l>0){if(v=I.pop(),F=v.i,A=v.y,c>A&&b[F+1]!==null||c<A&&b[F-1]!== | ||
281 | +null)A=c}else A=c;z=e.justify?m[0]+(H?-1:1)*(p+l):a.getX(F===0||F===b.length-1?c:A,H);s._attr={visibility:E,align:w[6]};s._pos={x:z+e.x+({left:f,right:-f}[w[6]]||0),y:A+e.y-10};s.connX=z;s.connY=A;if(this.options.size===null)v=s.width,z-v<f?D[3]=r(t(v-z+f),D[3]):z+v>h-f&&(D[1]=r(t(z+v-h+f),D[1])),A-x/2<0?D[0]=r(t(-A+x/2),D[0]):A+x/2>d&&(D[2]=r(t(A+x/2-d),D[2]))}}if(ua(D)===0||this.verifyDataLabelOverflow(D))this.placeDataLabels(),u&&g&&n(this.points,function(b){i=b.connector;w=b.labelPos;if((s=b.dataLabel)&& | ||
282 | +s._pos)E=s._attr.visibility,z=s.connX,A=s.connY,j=k?["M",z+(w[6]==="left"?5:-5),A,"C",z,A,2*w[2]-w[4],2*w[3]-w[5],w[2],w[3],"L",w[4],w[5]]:["M",z+(w[6]==="left"?5:-5),A,"L",w[2],w[3],"L",w[4],w[5]],i?(i.animate({d:j}),i.attr("visibility",E)):b.connector=i=a.chart.renderer.path(j).attr({"stroke-width":g,stroke:e.connectorColor||b.color||"#606060",visibility:E}).add(a.group);else if(i)b.connector=i.destroy()})}},verifyDataLabelOverflow:function(a){var b=this.center,c=this.options,d=c.center,e=c=c.minSize|| | ||
283 | +80,f;d[0]!==null?e=r(b[2]-r(a[1],a[3]),c):(e=r(b[2]-a[1]-a[3],c),b[0]+=(a[3]-a[1])/2);d[1]!==null?e=r(J(e,b[2]-r(a[0],a[2])),c):(e=r(J(e,b[2]-a[0]-a[2]),c),b[1]+=(a[0]-a[2])/2);e<b[2]?(b[2]=e,this.translate(b),n(this.points,function(a){if(a.dataLabel)a.dataLabel._pos=null}),this.drawDataLabels()):f=!0;return f},placeDataLabels:function(){n(this.points,function(a){var a=a.dataLabel,b;if(a)(b=a._pos)?(a.attr(a._attr),a[a.moved?"animate":"attr"](b),a.moved=!0):a&&a.attr({y:-999})})},alignDataLabel:oa, | ||
284 | +drawTracker:F.prototype.drawTracker,drawLegendSymbol:G.prototype.drawLegendSymbol,getSymbol:oa};Y=ha(Q,Y);X.pie=Y;s(Highcharts,{Axis:eb,Chart:yb,Color:qa,Legend:fb,Pointer:xb,Point:Pa,Tick:Ma,Tooltip:wb,Renderer:Va,Series:Q,SVGElement:va,SVGRenderer:za,arrayMin:Ja,arrayMax:ua,charts:Ga,dateFormat:Ya,format:Ca,pathAnim:Ab,getOptions:function(){return L},hasBidiBug:Ub,isTouchDevice:Ob,numberFormat:Aa,seriesTypes:X,setOptions:function(a){L=x(L,a);Lb();return L},addEvent:K,removeEvent:$,createElement:U, | ||
285 | +discardElement:Ta,css:I,each:n,extend:s,map:Na,merge:x,pick:o,splat:ja,extendClass:ha,pInt:y,wrap:mb,svg:W,canvas:ca,vml:!W&&!ca,product:"Highcharts",version:"3.0.7"})})(); |
src/super_archives/management/commands/import_emails.py
@@ -11,7 +11,10 @@ from optparse import make_option | @@ -11,7 +11,10 @@ from optparse import make_option | ||
11 | 11 | ||
12 | from django.db import transaction | 12 | from django.db import transaction |
13 | from django.template.defaultfilters import slugify | 13 | from django.template.defaultfilters import slugify |
14 | +from super_archives.utils.email import colab_send_email | ||
14 | from django.core.management.base import BaseCommand, CommandError | 15 | from django.core.management.base import BaseCommand, CommandError |
16 | +from django.template.loader import render_to_string | ||
17 | +from django.utils.translation import ugettext as _ | ||
15 | 18 | ||
16 | from super_archives.models import MailingList, Message, \ | 19 | from super_archives.models import MailingList, Message, \ |
17 | Thread, EmailAddress | 20 | Thread, EmailAddress |
@@ -196,6 +199,21 @@ class Command(BaseCommand, object): | @@ -196,6 +199,21 @@ class Command(BaseCommand, object): | ||
196 | email_addr.save() | 199 | email_addr.save() |
197 | 200 | ||
198 | subject = email_msg.get_subject() | 201 | subject = email_msg.get_subject() |
202 | + if not subject: | ||
203 | + colab_send_email( | ||
204 | + subject=_( | ||
205 | + u"[Colab] Warning - Email sent with a blank subject." | ||
206 | + ), | ||
207 | + message=render_to_string( | ||
208 | + u'superarchives/emails/email_blank_subject.txt', | ||
209 | + { | ||
210 | + 'email_body': email_msg.get_body(), | ||
211 | + 'mailinglist': mailinglist.name, | ||
212 | + 'user': email_addr.get_full_name() | ||
213 | + } | ||
214 | + ), | ||
215 | + to=email_addr.address | ||
216 | + ) | ||
199 | 217 | ||
200 | email = Message.all_objects.create( | 218 | email = Message.all_objects.create( |
201 | message_id=email_msg.get('Message-ID'), | 219 | message_id=email_msg.get('Message-ID'), |
src/super_archives/models.py
@@ -326,18 +326,27 @@ class Message(models.Model): | @@ -326,18 +326,27 @@ class Message(models.Model): | ||
326 | 326 | ||
327 | @property | 327 | @property |
328 | def author(self): | 328 | def author(self): |
329 | - from_address = self.from_address | ||
330 | - if from_address.user: | ||
331 | - return from_address.user.username | 329 | + return self.fullname |
330 | + | ||
331 | + @property | ||
332 | + def author_url(self): | ||
333 | + if self.from_address.user_id: | ||
334 | + return self.from_address.user.get_absolute_url() | ||
332 | return None | 335 | return None |
333 | 336 | ||
337 | + # An alias for author | ||
334 | @property | 338 | @property |
335 | - def fullname(self): | ||
336 | - return self.from_address.get_full_name() | 339 | + def modified_by(self): |
340 | + return self.author | ||
337 | 341 | ||
342 | + # An alias for author_url | ||
338 | @property | 343 | @property |
339 | - def author_url(self): | ||
340 | - return self.from_address.user.get_absolute_url() | 344 | + def modified_by_url(self): |
345 | + return self.author_url | ||
346 | + | ||
347 | + @property | ||
348 | + def fullname(self): | ||
349 | + return self.from_address.get_full_name() | ||
341 | 350 | ||
342 | @property | 351 | @property |
343 | def icon_name(self): | 352 | def icon_name(self): |
src/super_archives/search_indexes.py
@@ -50,17 +50,34 @@ class ThreadIndex(BaseIndex, indexes.Indexable): | @@ -50,17 +50,34 @@ class ThreadIndex(BaseIndex, indexes.Indexable): | ||
50 | ) | 50 | ) |
51 | 51 | ||
52 | def prepare_author(self, obj): | 52 | def prepare_author(self, obj): |
53 | - return obj.latest_message.author | 53 | + first_message = obj.message_set.first() |
54 | + return first_message.from_address.get_full_name() | ||
54 | 55 | ||
55 | def prepare_author_url(self, obj): | 56 | def prepare_author_url(self, obj): |
56 | first_message = obj.message_set.first() | 57 | first_message = obj.message_set.first() |
57 | - if first_message.from_address.user: | ||
58 | - return first_message.from_address.user.get_absolute_url() | 58 | + return first_message.author_url |
59 | + | ||
60 | + def prepare_modified_by(self, obj): | ||
61 | + modified_by = obj.latest_message.modified_by | ||
62 | + if modified_by: | ||
63 | + return modified_by | ||
64 | + return obj.message_set.first().author | ||
65 | + | ||
66 | + def prepare_modified_by_url(self, obj): | ||
67 | + modified_by_url = obj.latest_message.modified_by_url | ||
68 | + if modified_by_url: | ||
69 | + return modified_by_url | ||
59 | return None | 70 | return None |
60 | 71 | ||
61 | def prepare_created(self, obj): | 72 | def prepare_created(self, obj): |
62 | return obj.message_set.first().received_time | 73 | return obj.message_set.first().received_time |
63 | 74 | ||
75 | + def prepare_fullname(self, obj): | ||
76 | + fullname = obj.latest_message.from_address.get_full_name() | ||
77 | + if not fullname: | ||
78 | + fullname = obj.message_set.first().from_address.get_full_name() | ||
79 | + return fullname | ||
80 | + | ||
64 | def prepare_icon_name(self, obj): | 81 | def prepare_icon_name(self, obj): |
65 | return u'envelope' | 82 | return u'envelope' |
66 | 83 |
src/super_archives/templates/message-preview.html
@@ -28,33 +28,41 @@ | @@ -28,33 +28,41 @@ | ||
28 | {% highlight result.description with query max_length "150" %} | 28 | {% highlight result.description with query max_length "150" %} |
29 | {% else %} | 29 | {% else %} |
30 | {% if result.latest_description %} | 30 | {% if result.latest_description %} |
31 | - {{ result.latest_description|escape|truncatechars:150 }} | 31 | + {{ result.latest_description|striptags|escape|truncatechars:150 }} |
32 | {% elif result.description %} | 32 | {% elif result.description %} |
33 | - {{ result.description|escape|truncatechars:150 }} | 33 | + {{ result.description|striptags|escape|truncatechars:150 }} |
34 | {% endif %} | 34 | {% endif %} |
35 | {% endif %} | 35 | {% endif %} |
36 | </span> | 36 | </span> |
37 | {% endif %} | 37 | {% endif %} |
38 | 38 | ||
39 | -{% if result.fullname or result.modified %} | 39 | +{% if result.fullname or result.modified or result.modified_by %} |
40 | <div class="quiet"> | 40 | <div class="quiet"> |
41 | - {% if result.fullname %} | 41 | + {% if result.modified_by %} |
42 | <span class="pull-left">{% trans "by" %} | 42 | <span class="pull-left">{% trans "by" %} |
43 | - {% if result.fullname and result.author_url %} | ||
44 | - <a href="{{ result.author_url }}"> | ||
45 | - {% if query %} | ||
46 | - {% highlight result.fullname with query %} | ||
47 | - {% else %} | ||
48 | - {{ result.fullname }} | ||
49 | - {% endif %} | 43 | + {% if result.modified_by_url %} |
44 | + <a href="{{ result.modified_by_url }}"> | ||
45 | + {% else %} | ||
46 | + <span> | ||
47 | + {% endif %} | ||
48 | + | ||
49 | + {% if query %} | ||
50 | + {% highlight result.modified_by with query %} | ||
51 | + {% else %} | ||
52 | + {{ result.modified_by }} | ||
53 | + {% endif %} | ||
54 | + | ||
55 | + {% if result.modified_by_url %} | ||
50 | </a> | 56 | </a> |
51 | {% else %} | 57 | {% else %} |
52 | - <span>{{ result.fullname }}</span> | 58 | + </span> |
53 | {% endif %} | 59 | {% endif %} |
54 | </span> | 60 | </span> |
61 | + {% else %} | ||
62 | + <span class="pull-left">{% trans "by" %} {% trans "Anonymous" %}</span> | ||
55 | {% endif %} | 63 | {% endif %} |
56 | {% if result.modified %} | 64 | {% if result.modified %} |
57 | - <span class="pull-right">{{ result.modified|localtime|timesince }} {% trans "ago" %}</span> | 65 | + <span class="pull-right">{{ result.modified|localtime|timesince }} {% trans "ago" %}</span> |
58 | {% endif %} | 66 | {% endif %} |
59 | </div> | 67 | </div> |
60 | {% endif %} | 68 | {% endif %} |
src/super_archives/templates/message-thread.html
@@ -3,6 +3,8 @@ | @@ -3,6 +3,8 @@ | ||
3 | 3 | ||
4 | {% trans "Anonymous" as anonymous %} | 4 | {% trans "Anonymous" as anonymous %} |
5 | 5 | ||
6 | +{% block title %}{{ first_msg.subject_clean }}{% endblock %} | ||
7 | + | ||
6 | {% block head_js %} | 8 | {% block head_js %} |
7 | 9 | ||
8 | <script> | 10 | <script> |
@@ -98,6 +100,8 @@ | @@ -98,6 +100,8 @@ | ||
98 | {% if user.is_active %} | 100 | {% if user.is_active %} |
99 | $('.reply.btn', this).on('click', focus_reply); | 101 | $('.reply.btn', this).on('click', focus_reply); |
100 | {% endif %} | 102 | {% endif %} |
103 | + | ||
104 | + $('.message-link').popover({'placement': 'right'}); | ||
101 | }); | 105 | }); |
102 | 106 | ||
103 | </script> | 107 | </script> |
src/super_archives/templates/superarchives/emails/email_blank_subject.txt
0 → 100644
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +{% load i18n %} | ||
2 | +{% trans 'Hello' %} {{ user }}, | ||
3 | +{% blocktrans with body=email_body mailinglist=mailinglist %} | ||
4 | +You've sent an email to {{ mailinglist }} with a blank subject and the following content: | ||
5 | + | ||
6 | +"{{ body }}" | ||
7 | + | ||
8 | +Please, fill the subject in every email you send it. | ||
9 | + | ||
10 | +Thank you. | ||
11 | +{% endblocktrans %} |
src/super_archives/templates/superarchives/includes/message.html
@@ -13,6 +13,13 @@ | @@ -13,6 +13,13 @@ | ||
13 | {% if userprofile.get_absolute_url %} | 13 | {% if userprofile.get_absolute_url %} |
14 | </a> | 14 | </a> |
15 | {% endif %} | 15 | {% endif %} |
16 | + {% if email.id %} | ||
17 | + <div class="hidden-xs hidden-sm div-message-link" title="{% trans 'Link to this message' %}"> | ||
18 | + <button class="btn btn-default message-link" data-toggle="popover" data-content="<input type='text' value='{{ request.get_host }}{{ request.path }}#msg-{{ email.id }}' class='form-control' />" data-title="{% trans 'Link to this message' %}" data-html="true" data-container="body"> | ||
19 | + <span class="glyphicon glyphicon-link"></span> | ||
20 | + </button> | ||
21 | + </div> | ||
22 | + {% endif %} | ||
16 | </div> | 23 | </div> |
17 | 24 | ||
18 | {% if not reply %} | 25 | {% if not reply %} |
src/super_archives/templates/superarchives/thread-dashboard.html
@@ -2,12 +2,12 @@ | @@ -2,12 +2,12 @@ | ||
2 | {% load i18n %} | 2 | {% load i18n %} |
3 | 3 | ||
4 | {% block main-content %} | 4 | {% block main-content %} |
5 | - <h2>{% trans 'Discussions'|title %}</h2> | 5 | + <h2>{% trans 'Groups'|title %}</h2> |
6 | <hr/> | 6 | <hr/> |
7 | 7 | ||
8 | - {% for listname, latest, most_relevant in lists %} | 8 | + {% for listname, description, latest, most_relevant in lists %} |
9 | {% if latest or most_relevant %} | 9 | {% if latest or most_relevant %} |
10 | - <h3 class="text-center"><b>{{ listname|title }}</b></h3> | 10 | + <h3 class="text-center"><b>{{ listname|title }} {% if description %} ({{ description }}){% endif %}</b></h3> |
11 | <hr/> | 11 | <hr/> |
12 | 12 | ||
13 | <div class="row"> | 13 | <div class="row"> |
src/super_archives/views.py
@@ -20,6 +20,7 @@ from django.shortcuts import render, redirect, get_object_or_404 | @@ -20,6 +20,7 @@ from django.shortcuts import render, redirect, get_object_or_404 | ||
20 | 20 | ||
21 | from haystack.query import SearchQuerySet | 21 | from haystack.query import SearchQuerySet |
22 | 22 | ||
23 | +from accounts.utils import mailman | ||
23 | from .utils.email import send_verification_email | 24 | from .utils.email import send_verification_email |
24 | from .models import MailingList, Thread, EmailAddress, \ | 25 | from .models import MailingList, Thread, EmailAddress, \ |
25 | EmailAddressValidation, Message | 26 | EmailAddressValidation, Message |
@@ -74,6 +75,7 @@ class ThreadView(View): | @@ -74,6 +75,7 @@ class ThreadView(View): | ||
74 | raise http.Http404 | 75 | raise http.Http404 |
75 | 76 | ||
76 | data = { | 77 | data = { |
78 | + 'in_reply_to': thread.message_set.last().message_id, | ||
77 | 'email_from': request.user.email, | 79 | 'email_from': request.user.email, |
78 | 'name_from': request.user.get_full_name(), | 80 | 'name_from': request.user.get_full_name(), |
79 | 'subject': thread.message_set.first().subject_clean, | 81 | 'subject': thread.message_set.first().subject_clean, |
@@ -93,10 +95,12 @@ class ThreadView(View): | @@ -93,10 +95,12 @@ class ThreadView(View): | ||
93 | error_msg = _('Timeout trying to connect to Mailman API') | 95 | error_msg = _('Timeout trying to connect to Mailman API') |
94 | 96 | ||
95 | if resp and resp.status_code == 200: | 97 | if resp and resp.status_code == 200: |
96 | - messages.success(request, _("Your message was sent. It may take " | ||
97 | - "some minutes before it's delivered. " | ||
98 | - "Why don't you breath some fresh air " | ||
99 | - "in the meanwhile?")) | 98 | + messages.success(request, _( |
99 | + "Your message was sent to this topic. " | ||
100 | + "It may take some minutes before it's delivered by email " | ||
101 | + "to the group. Why don't you breath some fresh air in the " | ||
102 | + "meanwhile?" | ||
103 | + )) | ||
100 | else: | 104 | else: |
101 | if not error_msg: | 105 | if not error_msg: |
102 | if resp is not None: | 106 | if resp is not None: |
@@ -117,13 +121,17 @@ class ThreadDashboardView(View): | @@ -117,13 +121,17 @@ class ThreadDashboardView(View): | ||
117 | def get(self, request): | 121 | def get(self, request): |
118 | MAX = 6 | 122 | MAX = 6 |
119 | context = {} | 123 | context = {} |
124 | + all_lists = mailman.all_lists(description=True) | ||
120 | 125 | ||
121 | context['lists'] = [] | 126 | context['lists'] = [] |
122 | lists = MailingList.objects.filter() | 127 | lists = MailingList.objects.filter() |
123 | for list_ in MailingList.objects.order_by('name'): | 128 | for list_ in MailingList.objects.order_by('name'): |
124 | context['lists'].append(( | 129 | context['lists'].append(( |
125 | list_.name, | 130 | list_.name, |
126 | - list_.thread_set.filter(spam=False)[:MAX], | 131 | + mailman.get_list_description(list_.name, all_lists), |
132 | + list_.thread_set.filter(spam=False).order_by( | ||
133 | + '-latest_message__received_time' | ||
134 | + )[:MAX], | ||
127 | SearchQuerySet().filter(type='thread', tag=list_.name)[:MAX], | 135 | SearchQuerySet().filter(type='thread', tag=list_.name)[:MAX], |
128 | )) | 136 | )) |
129 | 137 |
src/templates/base.html
@@ -5,6 +5,12 @@ | @@ -5,6 +5,12 @@ | ||
5 | {% block head %} | 5 | {% block head %} |
6 | <meta charset="UTF-8" /> | 6 | <meta charset="UTF-8" /> |
7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> |
8 | + {% block metarobots %} | ||
9 | + {% if ROBOTS_NOINDEX %} | ||
10 | + <meta name="robots" content="noindex, nofollow" /> | ||
11 | + {% endif %} | ||
12 | + {% endblock %} | ||
13 | + | ||
8 | <title>Colab - {% block title %}Colab{% endblock %}</title> | 14 | <title>Colab - {% block title %}Colab{% endblock %}</title> |
9 | 15 | ||
10 | <link rel="shortcut icon" type="image/x-icon" href="{{ STATIC_URL }}img/interlegis.ico"> | 16 | <link rel="shortcut icon" type="image/x-icon" href="{{ STATIC_URL }}img/interlegis.ico"> |
@@ -22,6 +28,7 @@ | @@ -22,6 +28,7 @@ | ||
22 | <link rel="stylesheet" href="{{ STATIC_URL }}css/screen.css" | 28 | <link rel="stylesheet" href="{{ STATIC_URL }}css/screen.css" |
23 | type="text/css" media="screen" /> | 29 | type="text/css" media="screen" /> |
24 | 30 | ||
31 | + <!-- JQuery 2+ won't work for IE < 9 --> | ||
25 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery-2.0.3.min.js"></script> | 32 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery-2.0.3.min.js"></script> |
26 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery.debouncedresize.js"></script> | 33 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery.debouncedresize.js"></script> |
27 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery.cookie.js"></script> | 34 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery.cookie.js"></script> |
@@ -69,7 +76,7 @@ | @@ -69,7 +76,7 @@ | ||
69 | <div class="collapse navbar-collapse navbar-main"> | 76 | <div class="collapse navbar-collapse navbar-main"> |
70 | <ul class="nav navbar-nav"> | 77 | <ul class="nav navbar-nav"> |
71 | <li> | 78 | <li> |
72 | - <a href="{% url 'thread_list' %}">{% trans "Discussions" %}</a> | 79 | + <a href="{% url 'thread_list' %}">{% trans "Groups" %}</a> |
73 | </li> | 80 | </li> |
74 | <li> | 81 | <li> |
75 | <a href="{% url "feedzilla_index" %}">{% trans "Planet" %}</a> | 82 | <a href="{% url "feedzilla_index" %}">{% trans "Planet" %}</a> |
@@ -78,13 +85,13 @@ | @@ -78,13 +85,13 @@ | ||
78 | <a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Contribute" %} <b class="caret"></b></a> | 85 | <a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Contribute" %} <b class="caret"></b></a> |
79 | <ul class="dropdown-menu"> | 86 | <ul class="dropdown-menu"> |
80 | <li><a href="/wiki">Wiki</a></li> | 87 | <li><a href="/wiki">Wiki</a></li> |
88 | + <li><a href="/timeline">{% trans "Timeline" %}</a></li> | ||
89 | + <li><a href="/roadmap">{% trans "Roadmap" %}</a></li> | ||
81 | {% if user.is_active %} | 90 | {% if user.is_active %} |
82 | <li><a href="/newticket">{% trans "New Ticket" %}</a></li> | 91 | <li><a href="/newticket">{% trans "New Ticket" %}</a></li> |
83 | {% endif %} | 92 | {% endif %} |
84 | - <li><a href="/timeline">{% trans "Timeline" %}</a></li> | ||
85 | - <li><a href="/roadmap">{% trans "Roadmap" %}</a></li> | ||
86 | - <li><a href="/browser">{% trans "Browse Source" %}</a></li> | ||
87 | <li><a href="/report">{% trans "View Tickets" %}</a></li> | 93 | <li><a href="/report">{% trans "View Tickets" %}</a></li> |
94 | + <li><a href="/browser">{% trans "Browse Source" %}</a></li> | ||
88 | </ul> | 95 | </ul> |
89 | </li> | 96 | </li> |
90 | <li class="hidden-lg hidden-md"> | 97 | <li class="hidden-lg hidden-md"> |
@@ -95,7 +102,8 @@ | @@ -95,7 +102,8 @@ | ||
95 | <ul class="nav navbar-nav navbar-right"> | 102 | <ul class="nav navbar-nav navbar-right"> |
96 | {% if not user.is_authenticated %} | 103 | {% if not user.is_authenticated %} |
97 | <li><a href="{% url 'signup' %}">{% trans "Register" %}</a></li> | 104 | <li><a href="{% url 'signup' %}">{% trans "Register" %}</a></li> |
98 | - <li>{% browserid_login text='Login' %}</li> | 105 | + {% trans 'Login' as login_text %} |
106 | + <li>{% browserid_login text=login_text %}</li> | ||
99 | {% else %} | 107 | {% else %} |
100 | <li id="user-menu" class="dropdown"> | 108 | <li id="user-menu" class="dropdown"> |
101 | <a href="#" class="dropdown-toggle user" data-toggle="dropdown">{% gravatar user.email 40 %} <b class="caret"></b> </a> | 109 | <a href="#" class="dropdown-toggle user" data-toggle="dropdown">{% gravatar user.email 40 %} <b class="caret"></b> </a> |
@@ -109,7 +117,8 @@ | @@ -109,7 +117,8 @@ | ||
109 | </div> | 117 | </div> |
110 | <div> | 118 | <div> |
111 | <a class="btn btn-info pull-left" href="{% url 'user_profile' user.username %}">{% trans "My Profile" %}</a> | 119 | <a class="btn btn-info pull-left" href="{% url 'user_profile' user.username %}">{% trans "My Profile" %}</a> |
112 | - {% browserid_logout text='Logout' link_class='btn btn-default pull-right' %} | 120 | + {% trans 'Logout' as logout_text %} |
121 | + {% browserid_logout text=logout_text link_class='btn btn-default pull-right' %} | ||
113 | </div> | 122 | </div> |
114 | </div> | 123 | </div> |
115 | </li> | 124 | </li> |
@@ -161,16 +170,17 @@ | @@ -161,16 +170,17 @@ | ||
161 | <div class="row"> </div> | 170 | <div class="row"> </div> |
162 | 171 | ||
163 | {% block footer %} | 172 | {% block footer %} |
164 | - <p class="col-lg-12 text-center">{% trans "Last email imported at" %} {{ last_imported_message.received_time|date:'DATETIME_FORMAT' }}</p> | ||
165 | - <div class="row"> | ||
166 | - </div> | ||
167 | <div class="row"> | 173 | <div class="row"> |
168 | - <p class="col-lg-12 text-center"> | ||
169 | - {% trans "The contents of this site is published under license" %} | ||
170 | - <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/br/"> | ||
171 | - {% trans "Creative Commons - attribution, non-commercial" %} | ||
172 | - </a> | ||
173 | - </p> | 174 | + <p class="col-lg-12 text-center"> |
175 | + <a href="{% url 'opendata' %}"><img src="{{ STATIC_URL }}img/opendata3.png"/></a> | ||
176 | + </p> | ||
177 | + <p class="col-lg-12 text-center">{% trans "Last email imported at" %} {{ last_imported_message.received_time|date:'DATETIME_FORMAT' }}</p> | ||
178 | + <p class="col-lg-12 text-center"> | ||
179 | + {% trans "The contents of this site is published under license" %} | ||
180 | + <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/br/"> | ||
181 | + {% trans "Creative Commons - attribution, non-commercial" %} | ||
182 | + </a> | ||
183 | + </p> | ||
174 | </div> | 184 | </div> |
175 | {% endblock %} | 185 | {% endblock %} |
176 | 186 |
src/templates/home.html
@@ -2,7 +2,9 @@ | @@ -2,7 +2,9 @@ | ||
2 | {% load i18n %} | 2 | {% load i18n %} |
3 | 3 | ||
4 | {% block head_js %} | 4 | {% block head_js %} |
5 | - {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=330 %} | 5 | + {% trans "Contributions" as collabs_name %} |
6 | + | ||
7 | + {% include "pizza-chart.html" with chart_data=type_count chart_div="collabs" chart_height=330 name=collabs_name %} | ||
6 | {% endblock %} | 8 | {% endblock %} |
7 | 9 | ||
8 | {% block header %} | 10 | {% block header %} |
@@ -0,0 +1,144 @@ | @@ -0,0 +1,144 @@ | ||
1 | +{% extends "base.html" %} | ||
2 | +{% load i18n %} | ||
3 | + | ||
4 | +{% block main-content %} | ||
5 | + <div class="col-lg-12"> | ||
6 | + <h2>{% trans "OpenData - Communities Interlegis" %}</h2> | ||
7 | + <p>{% trans "If you are interested in any other data that is not provided by this API, please contact us via the ticketing system (you must be registered in order to create a ticket)." %}</p> | ||
8 | + | ||
9 | + <h3>{% trans "Retrieving data via API" %}</h3> | ||
10 | + <p>{% trans "Colab API works through HTTP/REST, always returning JSON objects." %}</p> | ||
11 | + <p> | ||
12 | + {% trans "The base API URL is" %}: | ||
13 | + {% url 'api_v1_top_level' api_name='v1' as BASE_API_URL %} | ||
14 | + <a href="{{ BASE_API_URL }}">{{ BASE_API_URL }}</a> | ||
15 | + </p> | ||
16 | + | ||
17 | + <ul class="list-unstyled"> | ||
18 | + <li> | ||
19 | + <p>{% trans "Each model listed below has a resource_uri field available, which is the object's data URI." %}</p> | ||
20 | + <p>{% trans "The following list contains the available models to retrieve data and its fields available for filtering" %}:</p> | ||
21 | + <ul> | ||
22 | + <li> | ||
23 | + <strong><a href="{{ BASE_API_URL }}user/">user</a></strong>: | ||
24 | + {% trans "Fields" %}: <i>username, email, institution, role, first_name, last_name and bio</i> | ||
25 | + <p><strong>{% trans "The email field is not shown for user's privacy, but you can use it to filter" %}</strong></p> | ||
26 | + <ul> | ||
27 | + <li><i>username</i> - {% trans "The user's username" %}</li> | ||
28 | + <li><i>email</i> - {% trans "The user's email address" %}</li> | ||
29 | + <li><i>institution</i> - {% trans "What is the user's institution" %}</li> | ||
30 | + <li><i>role</i> - {% trans "What is the user's role" %}</li> | ||
31 | + <li><i>first_name</i> - {% trans "The user's first name" %}</li> | ||
32 | + <li><i>last_name</i> - {% trans "The user's last name" %}</li> | ||
33 | + <li><i>bio</i> - {% trans "A mini bio of the user" %}</li> | ||
34 | + </ul> | ||
35 | + <br /> | ||
36 | + </li> | ||
37 | + <li> | ||
38 | + <strong><a href="{{ BASE_API_URL }}emailaddress/">emailaddress</a></strong>: | ||
39 | + {% trans "Fields" %}: <i>user, address and real_name</i> | ||
40 | + <p><strong>{% trans "The address field is not shown for user's privacy, but you can use it to filter" %}</strong></p> | ||
41 | + <ul> | ||
42 | + <li><i>user</i> - {% trans "It has a relationshop with the user described above" %}</li> | ||
43 | + <li><i>address</i> - {% trans "An email address" %}</li> | ||
44 | + <li><i>real_name</i> - {% trans "The user's real name" %}</li> | ||
45 | + </ul> | ||
46 | + <br /> | ||
47 | + </li> | ||
48 | + <li> | ||
49 | + <strong><a href="{{ BASE_API_URL }}message/">message</a></strong>: | ||
50 | + {% trans "Fields" %}: <i>from_address, body, id, received_time and subject</i> | ||
51 | + <ul> | ||
52 | + <li><i>from_address</i> - {% trans "It has a relationship with the emailaddress described above" %}</li> | ||
53 | + <li><i>body</i> - {% trans "The message's body" %}</li> | ||
54 | + <li><i>subject</i> - {% trans "The message's subject" %}</li> | ||
55 | + <li><i>id</i> - {% trans "The message's id" %}</li> | ||
56 | + <li><i>received_time</i> - {% trans "The message's received time" %}</li> | ||
57 | + </ul> | ||
58 | + <br /> | ||
59 | + </li> | ||
60 | + <li> | ||
61 | + <strong><a href="{{ BASE_API_URL }}revision/">revision</a></strong>: | ||
62 | + {% trans "Fields" %}: <i>author, created, key, message and repository_name</i> | ||
63 | + <ul> | ||
64 | + <li><i>author</i> - {% trans "The revision's author username" %}</li> | ||
65 | + <li><i>created</i> - {% trans "When the revision's were created" %}</li> | ||
66 | + <li><i>key</i> - {% trans "The revision's key" %}</li> | ||
67 | + <li><i>message</i> - {% trans "The revision's message" %}</li> | ||
68 | + <li><i>repository_name</i> - {% trans "The revision's repository name" %}</li> | ||
69 | + </ul> | ||
70 | + <br /> | ||
71 | + </li> | ||
72 | + <li> | ||
73 | + <strong><a href="{{ BASE_API_URL }}ticket/">ticket</a></strong>: | ||
74 | + {% trans "Fields" %}: <i>author, component, created, description, id, keywords, milestone, modified, modified_by, priority, reporter, severity, status, summary and version</i> | ||
75 | + <ul> | ||
76 | + <li><i>author</i> - {% trans "The ticket's author username" %}</li> | ||
77 | + <li><i>component</i> - {% trans "The ticket's component" %}</li> | ||
78 | + <li><i>created</i> - {% trans "When the ticket's were created" %}</li> | ||
79 | + <li><i>description</i> - {% trans "The ticket's description" %}</li> | ||
80 | + <li><i>id</i> - {% trans "The ticket's id" %}</li> | ||
81 | + <li><i>keywords</i> - {% trans "The ticket's keywords" %}</li> | ||
82 | + <li><i>milestone</i> - {% trans "The ticket's milestone" %}</li> | ||
83 | + <li><i>modified</i> - {% trans "The time of the last modification" %}</li> | ||
84 | + <li><i>modified_by</i> - {% trans "The username of the last user who modified the ticket" %}</li> | ||
85 | + <li><i>priority</i> - {% trans "The ticket's priority" %}</li> | ||
86 | + <li><i>severity</i> - {% trans "The ticket's severity" %}</li> | ||
87 | + <li><i>status</i> - {% trans "The ticket's status" %}</li> | ||
88 | + <li><i>summary</i> - {% trans "The ticket's summary" %}</li> | ||
89 | + <li><i>version</i> - {% trans "The ticket's version" %}</li> | ||
90 | + </ul> | ||
91 | + <br /> | ||
92 | + </li> | ||
93 | + <li> | ||
94 | + <strong><a href="{{ BASE_API_URL }}wiki/">wiki</a></strong>: | ||
95 | + {% trans "Fields" %}: <i>author, created, modified, modified_by, name and wiki_text</i> | ||
96 | + <ul> | ||
97 | + <li><i>author</i> - {% trans "The wiki's author username" %}</li> | ||
98 | + <li><i>created</i> - {% trans "When the wiki's were created" %}</li> | ||
99 | + <li><i>modified</i> - {% trans "The time of the last modification" %}</li> | ||
100 | + <li><i>modified_by</i> - {% trans "The username of the last user who modified the wiki" %}</li> | ||
101 | + <li><i>name</i> - {% trans "The wiki's name" %}</li> | ||
102 | + <li><i>wiki_text</i> - {% trans "the wiki's content" %}</li> | ||
103 | + </ul> | ||
104 | + </li> | ||
105 | + </ul> | ||
106 | + </li> | ||
107 | + </ul> | ||
108 | + <ul class="list-unstyled"> | ||
109 | + <li><h3>{% trans 'Parameters' %}:</h3></li> | ||
110 | + <li class="divider"></li> | ||
111 | + <li> | ||
112 | + <h4><i>limit</i> - {% trans "Results per page" %}</h4> | ||
113 | + {% trans "Number of results to be displayed per page." %} | ||
114 | + <i>{% trans "Default: 20" %}</i>. | ||
115 | + </li> | ||
116 | + <li class="divider"></li> | ||
117 | + <li> | ||
118 | + <h4><i>offset</i> - {% trans "Starts of n element" %}</h4> | ||
119 | + {% trans "Where n is the index of the first result to appear in the page." %} | ||
120 | + <i>{% trans "Default: 0" %}</i>. | ||
121 | + </li> | ||
122 | + <li class="divider"><h3>{% trans "Filtering" %}:</h3></li> | ||
123 | + <li> | ||
124 | + <h4><i>fieldname</i> - {% trans "The field name" %}</h4> | ||
125 | + {% trans "If you are looking for a specific wiki, and you know the wiki's name, you can filter it as below" %} | ||
126 | + <p><i>...{{ BASE_API_URL }}wiki/?name={% trans "WikiName" %}</i></p> | ||
127 | + <p>{% trans "Where "name" is the fieldname and "WikiName" is the value you want to filter." %}</p> | ||
128 | + <h4>{% trans "Usage" %}</h4> | ||
129 | + <p>{% trans "You can also filter using Django lookup fields with the double underscores, just as below" %}</p> | ||
130 | + <p><i>...{{ BASE_API_URL }}wiki/?wiki_text__startswith={% trans "Wiki" %}</i></p> | ||
131 | + <p><i>...{{ BASE_API_URL }}ticket/?author__endswith={% trans "test" %}</i></p> | ||
132 | + <p><i>...{{ BASE_API_URL }}message/?body__contains={% trans "test" %}</i></p> | ||
133 | + <h4>{% trans "Usage with relationships" %}</h4> | ||
134 | + <p>{% trans "You can use related fields to filter too. So, you can filter by any field of emailaddress using the 'from_address' field of message, which has a relation to emailaddress. You will achieve the related fields by using double underscore and the field's name. See the example below" %}</p> | ||
135 | + <p><i>...{{ BASE_API_URL }}message/?from_address__real_name__contains=Name</i></p> | ||
136 | + <p>{% trans "So, real_name is a field of emailaddress, and you had access to this field by a message field called from_address and using double underscore to say you want to use a field of that relationship" %}</p> | ||
137 | + <p><strong>{% trans "Note: email filters must be exact. Which means that __contains, __startswith, __endswith and others won't work" %}</strong></p> | ||
138 | + <p>{% trans "Another example of usage with relations. Used to retrieve all messages of a given user, using the username or the email field" %}</p> | ||
139 | + <p><i>...{{ BASE_API_URL }}message/?from_address__user__username=username</i></p> | ||
140 | + <p><i>...{{ BASE_API_URL }}message/?from_address__user__email=usermailexample@host.com</i></p> | ||
141 | + </li> | ||
142 | + </ul> | ||
143 | + </div> | ||
144 | +{% endblock %} |
src/templates/pizza-chart.html
1 | {% load i18n %} | 1 | {% load i18n %} |
2 | 2 | ||
3 | - <!--Load the AJAX API--> | ||
4 | - <script type="text/javascript" src="https://www.google.com/jsapi"></script> | ||
5 | - <script type="text/javascript"> | ||
6 | - | ||
7 | - // Load the Visualization API and the piechart package. | ||
8 | - google.load('visualization', '1.0', {'packages':['corechart']}); | ||
9 | - | ||
10 | - // Set a callback to run when the Google Visualization API is loaded. | ||
11 | - google.setOnLoadCallback(drawChart); | ||
12 | - | ||
13 | - // Callback that creates and populates a data table, | ||
14 | - // instantiates the pie chart, passes in the data and | ||
15 | - // draws it. | ||
16 | - function drawChart() { | 3 | +<script src="{{ STATIC_URL }}third-party/highcharts/js/highcharts.js"></script> |
4 | +<script> | ||
5 | +$(function () { | ||
6 | + $('#{{ chart_div }}').highcharts({ | ||
7 | + chart: { | ||
8 | + type: 'pie', | ||
9 | + height: {{ chart_height }}, | ||
10 | + }, | ||
17 | 11 | ||
18 | - // Create the data table. | ||
19 | - var data = new google.visualization.DataTable(); | ||
20 | - data.addColumn('string', 'Topping'); | ||
21 | - data.addColumn('number', 'Slices'); | ||
22 | - data.addRows([ | ||
23 | - {% for key, value in chart_data.items %} | ||
24 | - ['{{ key }}', {{ value }} ], | ||
25 | - {% empty %} | ||
26 | - ['{% trans "Willing to help" %}', 100], | ||
27 | - {% endfor %} | ||
28 | - ]); | ||
29 | - | ||
30 | - // Set chart options | ||
31 | - var options = { | ||
32 | - height: '{{ chart_height }}', | ||
33 | - legend: { | ||
34 | - position: 'bottom', | ||
35 | - alignment: 'center', | ||
36 | - }, | ||
37 | - chartArea: { | ||
38 | - height: "85%", | ||
39 | - width: "95%", | ||
40 | - top: 10, | 12 | + // Add selectpoint and legends to the chart |
13 | + plotOptions: { | ||
14 | + pie: { | ||
15 | + allowPointSelect: true, | ||
16 | + cursor: 'pointer', | ||
17 | + dataLabels: { | ||
18 | + enabled: false | ||
41 | }, | 19 | }, |
42 | - }; | 20 | + showInLegend: true, |
21 | + } | ||
22 | + }, | ||
43 | 23 | ||
44 | - // Instantiate and draw our chart, passing in some options. | ||
45 | - var chart = new google.visualization.PieChart(document.getElementById('{{ chart_div }}')); | ||
46 | - chart.draw(data, options); | 24 | + // Removes highcharts watermark |
25 | + credits: { | ||
26 | + enabled: false | ||
27 | + }, | ||
47 | 28 | ||
48 | - $(window).on("debouncedresize", function( event ) { | ||
49 | - chart.draw(data, options); | ||
50 | - }); | ||
51 | - } | ||
52 | - </script> | 29 | + title: { |
30 | + text: {% if chart_title %}'{{ chart_title }}'{% else %}''{% endif %} | ||
31 | + }, | ||
32 | + | ||
33 | + series: [{ | ||
34 | + data: [ | ||
35 | + {% for option, value in chart_data.items %} | ||
36 | + ['{{ option }}', {{ value }}], | ||
37 | + {% endfor %} | ||
38 | + ], | ||
39 | + name: '{{ name }}' | ||
40 | + }] | ||
41 | + }); | ||
42 | +}); | ||
43 | +</script> |