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 | 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 | 20 | } |
21 | 21 | |
22 | 22 | Mailalias { |
23 | - notify => Exec['newaliases'], | |
23 | + notify => Exec['newaliases'], | |
24 | + require => Class['postfix'], | |
24 | 25 | } |
25 | 26 | |
26 | 27 | exec { 'newaliases': |
27 | - path => '/usr/bin/newaliases', | |
28 | + command => 'sendmail -bi', | |
29 | + path => '/usr/sbin', | |
28 | 30 | refreshonly => true, |
29 | 31 | } |
30 | 32 | ... | ... |
puppet/modules/colab/manifests/requirements.pp
requirements.txt
1 | -Django>=1.6,<1.7 | |
1 | +Django>=1.6.1,<1.7 | |
2 | 2 | South==0.8.1 |
3 | 3 | psycopg2==2.5.1 |
4 | 4 | django-piston==0.2.3 |
... | ... | @@ -17,6 +17,7 @@ python-memcached==1.53 |
17 | 17 | django-hitcounter==0.1.1 |
18 | 18 | Pillow==2.2.1 |
19 | 19 | django-i18n-model==0.0.7 |
20 | +django-tastypie==0.11.0 | |
20 | 21 | |
21 | 22 | gunicorn==18.0 |
22 | 23 | gevent==0.13.8 |
... | ... | @@ -31,7 +32,7 @@ git+https://github.com/mozilla/django-browserid |
31 | 32 | django-revproxy==0.2.7 |
32 | 33 | |
33 | 34 | # Converse.js (XMPP client) |
34 | -django-conversejs==0.2.9 | |
35 | +django-conversejs==0.3 | |
35 | 36 | git+https://github.com/TracyWebTech/SleekXMPP@fix-gevent |
36 | 37 | |
37 | 38 | # Feedzilla (planet) and deps | ... | ... |
src/accounts/forms.py
... | ... | @@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _ |
6 | 6 | |
7 | 7 | from conversejs.models import XMPPAccount |
8 | 8 | |
9 | +from accounts.utils import mailman | |
9 | 10 | from super_archives.models import MailingList |
10 | 11 | from .utils.validators import validate_social_account |
11 | 12 | |
... | ... | @@ -49,19 +50,29 @@ class UserCreationForm(UserForm): |
49 | 50 | |
50 | 51 | |
51 | 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 | 61 | class Meta: |
54 | 62 | model = User |
55 | 63 | fields = ('first_name', 'last_name', |
56 | 64 | 'institution', 'role', 'twitter', 'facebook', |
57 | - 'google_talk', 'webpage') | |
65 | + 'google_talk', 'github', 'webpage', 'bio') | |
58 | 66 | |
59 | 67 | twitter = SocialAccountField(url='https://twitter.com/', required=False) |
60 | 68 | facebook = SocialAccountField(url='https://graph.facebook.com/', required=False) |
61 | 69 | |
62 | 70 | |
63 | 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 | 76 | lists = forms.MultipleChoiceField(label=_(u'Mailing lists'), |
66 | 77 | required=False, |
67 | 78 | widget=forms.CheckboxSelectMultiple, | ... | ... |
... | ... | @@ -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 @@ |
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 | 71 | \ No newline at end of file | ... | ... |
src/accounts/migrations/0009_auto__add_field_user_identi_ca.py
0 → 100644
... | ... | @@ -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 | 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 @@ |
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 | 80 | \ No newline at end of file | ... | ... |
src/accounts/models.py
... | ... | @@ -5,7 +5,9 @@ import urlparse |
5 | 5 | from django.db import models, DatabaseError |
6 | 6 | from django.contrib.auth.hashers import check_password |
7 | 7 | from django.contrib.auth.models import AbstractUser |
8 | +from django.core import validators | |
8 | 9 | from django.core.urlresolvers import reverse |
10 | +from django.utils.translation import ugettext_lazy as _ | |
9 | 11 | |
10 | 12 | from conversejs import xmpp |
11 | 13 | |
... | ... | @@ -18,9 +20,12 @@ class User(AbstractUser): |
18 | 20 | twitter = models.CharField(max_length=128, null=True, blank=True) |
19 | 21 | facebook = models.CharField(max_length=128, null=True, blank=True) |
20 | 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 | 25 | webpage = models.CharField(max_length=256, null=True, blank=True) |
22 | 26 | verification_hash = models.CharField(max_length=32, null=True, blank=True) |
23 | 27 | modified = models.DateTimeField(auto_now=True) |
28 | + bio = models.CharField(max_length=200, null=True, blank=True) | |
24 | 29 | |
25 | 30 | def check_password(self, raw_password): |
26 | 31 | |
... | ... | @@ -50,3 +55,12 @@ class User(AbstractUser): |
50 | 55 | # The following workaroud allows to change email field to unique |
51 | 56 | # without having to rewrite all AbstractUser here |
52 | 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 | 41 | self._badge_counters = get_users_counters() |
42 | 42 | return self._badge_counters |
43 | 43 | |
44 | - def get_updated_field(self): | |
45 | - return 'modified' | |
46 | - | |
47 | 44 | def prepare(self, obj): |
48 | 45 | prepared_data = super(UserIndex, self).prepare(obj) |
49 | 46 | ... | ... |
src/accounts/templates/accounts/manage_subscriptions.html
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | |
4 | 4 | {% block main-content %} |
5 | 5 | |
6 | - <h2>{% blocktrans %}Mailing List Subscriptions{% endblocktrans %}</h2> | |
6 | + <h2>{% blocktrans %}Group Subscriptions{% endblocktrans %}</h2> | |
7 | 7 | <h3>{% gravatar user_.email 50 %} {{ user_.get_full_name }} ({{ user_.username }})</h3> |
8 | 8 | <br> |
9 | 9 | |
... | ... | @@ -19,9 +19,9 @@ |
19 | 19 | </div> |
20 | 20 | <div class="panel-body"> |
21 | 21 | {% for list, checked in lists %} |
22 | - <div class="checkbox"> | |
22 | + <div class="checkbox" title="{{ list.description }}"> | |
23 | 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 | 25 | </label> |
26 | 26 | </div> |
27 | 27 | {% endfor %} | ... | ... |
src/accounts/templates/accounts/user_create_form.html
... | ... | @@ -43,7 +43,7 @@ |
43 | 43 | <div class="col-md-6 col-lg-6 col-sm-6 col-xs-12" style="display: inline-block; vertical-align:top;"> |
44 | 44 | <div class="well"> |
45 | 45 | <fieldset> |
46 | - <legend>{% trans 'Subscribe to mail lists' %}</legend> | |
46 | + <legend>{% trans 'Subscribe to groups' %}</legend> | |
47 | 47 | {% for choice in lists_form.lists %} |
48 | 48 | <div class="checkbox">{{ choice }}</div> |
49 | 49 | {% endfor %} | ... | ... |
src/accounts/templates/accounts/user_detail.html
... | ... | @@ -4,8 +4,11 @@ |
4 | 4 | |
5 | 5 | |
6 | 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 | 12 | {% endblock %} |
10 | 13 | |
11 | 14 | {% block main-content %} |
... | ... | @@ -22,16 +25,26 @@ |
22 | 25 | </h1> |
23 | 26 | |
24 | 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 | 42 | {% endif %} |
28 | 43 | |
29 | 44 | <div class="divider"></div> |
30 | 45 | {% if request.user.is_active %} |
31 | 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 | 48 | </ul> |
36 | 49 | <div class="divider"></div> |
37 | 50 | {% endif %} |
... | ... | @@ -48,26 +61,31 @@ |
48 | 61 | {% if request.user.is_active %} |
49 | 62 | <li> |
50 | 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 | 65 | {% endif %} |
53 | 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 | 68 | {% endif %} |
56 | 69 | </li> |
57 | 70 | |
58 | 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 | 77 | {% endif %} |
78 | + | |
61 | 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 | 81 | {% endif %} |
64 | 82 | {% endif %} |
65 | 83 | </ul> |
66 | 84 | |
67 | 85 | {% if user_.mailinglists %} |
68 | - <b>{% trans 'Subscribes: ' %}</b> | |
86 | + <b>{% trans 'Groups: ' %}</b> | |
69 | 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 | 89 | {% endfor %} |
72 | 90 | {% endif %} |
73 | 91 | |
... | ... | @@ -78,7 +96,7 @@ |
78 | 96 | <div class="col-lg-4 col-md-4 col-sm-7"> |
79 | 97 | <div class="panel panel-default"> |
80 | 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 | 100 | </div> |
83 | 101 | <div class="panel-body"> |
84 | 102 | <div id="collabs"></div> |
... | ... | @@ -90,7 +108,7 @@ |
90 | 108 | <div class="col-lg-4 col-md-4 col-sm-7"> |
91 | 109 | <div class="panel panel-default"> |
92 | 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 | 112 | </div> |
95 | 113 | <div class="panel-body"> |
96 | 114 | <div id="collabs2"></div> |
... | ... | @@ -130,6 +148,10 @@ |
130 | 148 | <li>{% trans "There are no posts by this user so far." %}</li> |
131 | 149 | {% endfor %} |
132 | 150 | </ul> |
151 | + <a href="{% url 'haystack_search' %}?type=thread&author={{ user_.username }}"> | |
152 | + {% trans "View more discussions..." %} | |
153 | + </a> | |
154 | + <div> </div> | |
133 | 155 | </div> |
134 | 156 | |
135 | 157 | <div class="col-lg-6 col-md-6 col-sm-12"> |
... | ... | @@ -141,6 +163,10 @@ |
141 | 163 | <li>{% trans "No contributions of this user so far." %}</li> |
142 | 164 | {% endfor %} |
143 | 165 | </ul> |
166 | + <a href="{% url 'haystack_search' %}?order=latest&collaborators={{ user_.username }}"> | |
167 | + {% trans "View more contributions..." %} | |
168 | + </a> | |
169 | + <div> </div> | |
144 | 170 | </div> |
145 | 171 | |
146 | 172 | </div> | ... | ... |
src/accounts/templates/accounts/user_update_form.html
... | ... | @@ -178,22 +178,26 @@ $(function() { |
178 | 178 | </div> |
179 | 179 | </div> |
180 | 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 | 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 | 196 | </div> |
194 | 197 | </div> |
195 | - | |
198 | + </div> | |
196 | 199 | </div> |
200 | + | |
197 | 201 | <div class="row"> |
198 | 202 | <div class="submit"> |
199 | 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 | 44 | subscribe(maillist, address) |
45 | 45 | |
46 | 46 | |
47 | -def address_lists(address): | |
47 | +def address_lists(address, description=''): | |
48 | 48 | url = get_url() |
49 | + | |
50 | + params = {'address': address, | |
51 | + 'description': description} | |
52 | + | |
49 | 53 | try: |
50 | - lists = requests.get(url, timeout=TIMEOUT, params={'address': address}) | |
54 | + lists = requests.get(url, timeout=TIMEOUT, params=params) | |
51 | 55 | except requests.exceptions.RequestException: |
52 | 56 | return [] |
53 | 57 | |
54 | 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 | 65 | def user_lists(user): |
... | ... | @@ -65,3 +69,12 @@ def user_lists(user): |
65 | 69 | list_set.update(address_lists(email)) |
66 | 70 | |
67 | 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 | 23 | from super_archives.models import EmailAddress, Message |
24 | 24 | from super_archives.utils.email import send_email_lists |
25 | 25 | from search.utils import trans |
26 | +from proxy.models import WikiCollabCount, TicketCollabCount | |
26 | 27 | from .forms import (UserCreationForm, ListsForm, UserUpdateForm, |
27 | 28 | ChangeXMPPPasswordForm) |
28 | 29 | from .errors import XMPPChangePwdException |
... | ... | @@ -65,11 +66,28 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): |
65 | 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 | 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 | 92 | context['type_count'] = count_types |
75 | 93 | |
... | ... | @@ -85,7 +103,6 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): |
85 | 103 | context['emails'] = query[:10] |
86 | 104 | |
87 | 105 | count_by = 'thread__mailinglist__name' |
88 | - messages = Message.objects.filter(from_address__user__pk=user.pk) | |
89 | 106 | context['list_activity'] = dict(messages.values_list(count_by)\ |
90 | 107 | .annotate(Count(count_by))\ |
91 | 108 | .order_by(count_by)) |
... | ... | @@ -157,17 +174,20 @@ class ManageUserSubscriptionsView(UserProfileBaseMixin, DetailView): |
157 | 174 | |
158 | 175 | user = self.get_object() |
159 | 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 | 179 | for email in emails: |
163 | 180 | lists = [] |
164 | 181 | lists_for_address = mailman.address_lists(email) |
165 | - for listname in all_lists: | |
182 | + for listname, description in all_lists: | |
166 | 183 | if listname in lists_for_address: |
167 | 184 | checked = True |
168 | 185 | else: |
169 | 186 | checked = False |
170 | - lists.append((listname, checked)) | |
187 | + lists.append(( | |
188 | + {'listname': listname, 'description': description}, | |
189 | + checked | |
190 | + )) | |
171 | 191 | |
172 | 192 | context['membership'].update({email: lists}) |
173 | 193 | ... | ... |
... | ... | @@ -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 | 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 | 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 | 21 | urlpatterns = patterns('', |
8 | 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 | 2 | |
3 | 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 | 7 | from accounts.models import User |
7 | 8 | |
8 | 9 | |
9 | 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 | 15 | def get_revision_counters(): |
... | ... | @@ -23,11 +21,8 @@ def get_revision_counters(): |
23 | 21 | |
24 | 22 | |
25 | 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 | 28 | def get_users_counters(): | ... | ... |
src/colab/custom_settings.py
... | ... | @@ -210,6 +210,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( |
210 | 210 | 'django_browserid.context_processors.browserid', |
211 | 211 | 'django_mobile.context_processors.is_mobile', |
212 | 212 | 'super_archives.context_processors.mailarchive', |
213 | + 'home.context_processors.robots', | |
213 | 214 | ) |
214 | 215 | |
215 | 216 | MIDDLEWARE_CLASSES = ( |
... | ... | @@ -294,6 +295,12 @@ REVPROXY_ADD_REMOTE_USER = True |
294 | 295 | CONVERSEJS_BOSH_SERVICE_URL = SITE_URL + '/http-bind' |
295 | 296 | |
296 | 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 | 306 | try: | ... | ... |
src/colab/local_settings-dev.py
src/colab/urls.py
... | ... | @@ -12,6 +12,10 @@ admin.autodiscover() |
12 | 12 | |
13 | 13 | urlpatterns = patterns('', |
14 | 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 | 20 | url(r'^search/', include('search.urls')), |
17 | 21 | url(r'^archives/', include('super_archives.urls')), | ... | ... |
src/home/views.py
1 | 1 | |
2 | 2 | from collections import OrderedDict |
3 | 3 | |
4 | +from django.conf import settings | |
5 | +from django.core.cache import cache | |
4 | 6 | from django.shortcuts import render |
5 | -from django.utils import timezone | |
7 | +from django.http import HttpResponse, Http404 | |
6 | 8 | |
7 | 9 | from search.utils import trans |
8 | 10 | from haystack.query import SearchQuerySet |
9 | 11 | |
12 | +from proxy.models import WikiCollabCount, TicketCollabCount | |
10 | 13 | from super_archives.models import Thread |
11 | 14 | |
12 | 15 | |
... | ... | @@ -17,13 +20,22 @@ def index(request): |
17 | 20 | latest_threads = Thread.objects.all()[:6] |
18 | 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 | 40 | context = { |
29 | 41 | 'hottest_threads': hottest_threads[:6], |
... | ... | @@ -34,3 +46,11 @@ def index(request): |
34 | 46 | )[:6], |
35 | 47 | } |
36 | 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 | msgstr "" |
8 | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
9 | 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 | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
12 | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
... | ... | @@ -29,35 +29,52 @@ msgstr "Permissões" |
29 | 29 | msgid "Important dates" |
30 | 30 | msgstr "Datas importantes" |
31 | 31 | |
32 | -#: accounts/forms.py:24 | |
32 | +#: accounts/forms.py:25 | |
33 | 33 | msgid "Social account does not exist" |
34 | 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 | 45 | msgid "Mailing lists" |
38 | 46 | msgstr "Listas de e-mail" |
39 | 47 | |
40 | -#: accounts/forms.py:72 | |
48 | +#: accounts/forms.py:83 | |
41 | 49 | msgid "Password" |
42 | 50 | msgstr "Senha" |
43 | 51 | |
44 | -#: accounts/forms.py:74 | |
52 | +#: accounts/forms.py:85 | |
45 | 53 | msgid "Password confirmation" |
46 | 54 | msgstr "Confirmação de senha" |
47 | 55 | |
48 | -#: accounts/forms.py:76 | |
56 | +#: accounts/forms.py:87 | |
49 | 57 | msgid "Enter the same password as above, for verification." |
50 | 58 | msgstr "Digite a mesma senha que acima, para verificação." |
51 | 59 | |
52 | -#: accounts/forms.py:94 | |
60 | +#: accounts/forms.py:105 | |
53 | 61 | msgid "Password mismatch" |
54 | 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 | 74 | msgid "Your profile has been created!" |
58 | 75 | msgstr "Seu perfil foi criado!" |
59 | 76 | |
60 | -#: accounts/views.py:128 | |
77 | +#: accounts/views.py:145 | |
61 | 78 | msgid "" |
62 | 79 | "You must login to validated your profile. Profiles not validated are deleted " |
63 | 80 | "in 24h." |
... | ... | @@ -65,12 +82,12 @@ msgstr "" |
65 | 82 | "Você deve se logar para validar seu perfil. Perfis não validados serão " |
66 | 83 | "deletados em 24h." |
67 | 84 | |
68 | -#: accounts/views.py:209 | |
85 | +#: accounts/views.py:229 | |
69 | 86 | msgid "Could not change your password. Please, try again later." |
70 | 87 | msgstr "" |
71 | 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 | 91 | msgid "You've changed your password successfully!" |
75 | 92 | msgstr "Senha alterada com sucesso!" |
76 | 93 | |
... | ... | @@ -81,16 +98,16 @@ msgstr "%(count)s usuários deletados." |
81 | 98 | |
82 | 99 | #: accounts/templates/accounts/change_password.html:8 |
83 | 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 | 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 | 105 | msgid "Change Password" |
89 | 106 | msgstr "Trocar senha" |
90 | 107 | |
91 | 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 | 112 | #: accounts/templates/accounts/manage_subscriptions.html:36 |
96 | 113 | msgid "Update subscriptions" |
... | ... | @@ -113,65 +130,82 @@ msgid "Personal Information" |
113 | 130 | msgstr "Informações pessoais" |
114 | 131 | |
115 | 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 | 137 | msgid "Register" |
121 | 138 | msgstr "Cadastre-se" |
122 | 139 | |
123 | 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 | 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 | 149 | msgid "Twitter account" |
133 | 150 | msgstr "Conta Twitter" |
134 | 151 | |
135 | -#: accounts/templates/accounts/user_detail.html:54 | |
152 | +#: accounts/templates/accounts/user_detail.html:64 | |
136 | 153 | msgid "Facebook account" |
137 | 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 | 165 | msgid "Personal webpage" |
141 | 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 | 181 | msgid "Badges" |
157 | 182 | msgstr "Medalhas" |
158 | 183 | |
159 | -#: accounts/templates/accounts/user_detail.html:125 | |
184 | +#: accounts/templates/accounts/user_detail.html:140 | |
160 | 185 | msgid "Latest posted" |
161 | 186 | msgstr "Últimas postagens" |
162 | 187 | |
163 | -#: accounts/templates/accounts/user_detail.html:130 | |
188 | +#: accounts/templates/accounts/user_detail.html:145 | |
164 | 189 | msgid "There are no posts by this user so far." |
165 | 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 | 198 | msgid "Contributions" |
169 | 199 | msgstr "Contribuições" |
170 | 200 | |
171 | -#: accounts/templates/accounts/user_detail.html:141 | |
201 | +#: accounts/templates/accounts/user_detail.html:160 | |
172 | 202 | msgid "No contributions of this user so far." |
173 | 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 | 209 | #: accounts/templates/accounts/user_update_form.html:65 |
176 | 210 | msgid "We sent a verification email to " |
177 | 211 | msgstr "Enviamos um email de verificação para " |
... | ... | @@ -229,96 +263,115 @@ msgstr "Adicionar outro endereço de e-mail" |
229 | 263 | msgid "Add" |
230 | 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 | 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 | 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 | 290 | msgid "Update" |
246 | 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 | 302 | msgid "Greater than or equal" |
250 | 303 | msgstr "Maior que ou igual" |
251 | 304 | |
252 | -#: badger/models.py:14 | |
305 | +#: badger/models.py:13 | |
253 | 306 | msgid "less than or equal" |
254 | 307 | msgstr "menor que ou igual" |
255 | 308 | |
256 | -#: badger/models.py:15 | |
309 | +#: badger/models.py:14 | |
257 | 310 | msgid "Equal" |
258 | 311 | msgstr "Igual" |
259 | 312 | |
260 | -#: badger/models.py:16 | |
313 | +#: badger/models.py:15 | |
261 | 314 | msgid "Biggest" |
262 | 315 | msgstr "Maior" |
263 | 316 | |
264 | -#: badger/models.py:19 | |
317 | +#: badger/models.py:18 | |
265 | 318 | msgid "Automatically" |
266 | 319 | msgstr "Automaticamente" |
267 | 320 | |
268 | -#: badger/models.py:20 | |
321 | +#: badger/models.py:19 | |
269 | 322 | msgid "Manual" |
270 | 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 | 326 | msgid "Messages" |
274 | 327 | msgstr "Mensagens" |
275 | 328 | |
276 | -#: badger/models.py:25 | |
329 | +#: badger/models.py:24 | |
277 | 330 | msgid "Wikis" |
278 | 331 | msgstr "Wikis" |
279 | 332 | |
280 | -#: badger/models.py:26 | |
333 | +#: badger/models.py:25 | |
281 | 334 | msgid "Revisions" |
282 | 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 | 338 | #: search/templates/search/includes/search_filters.html:124 |
286 | 339 | msgid "Ticket" |
287 | 340 | msgstr "Tíquetes" |
288 | 341 | |
289 | -#: badger/models.py:37 | |
342 | +#: badger/models.py:36 | |
290 | 343 | msgid "Title" |
291 | 344 | msgstr "Título" |
292 | 345 | |
293 | -#: badger/models.py:39 | |
346 | +#: badger/models.py:38 | |
294 | 347 | msgid "Description" |
295 | 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 | 351 | msgid "Type" |
299 | 352 | msgstr "Tipo" |
300 | 353 | |
301 | -#: badger/models.py:44 | |
354 | +#: badger/models.py:43 | |
302 | 355 | msgid "User attribute" |
303 | 356 | msgstr "Atributo do usuário" |
304 | 357 | |
305 | -#: badger/models.py:50 | |
358 | +#: badger/models.py:49 | |
306 | 359 | msgid "Comparison" |
307 | 360 | msgstr "Comparação" |
308 | 361 | |
309 | -#: badger/models.py:57 | |
362 | +#: badger/models.py:56 | |
310 | 363 | msgid "Value" |
311 | 364 | msgstr "Valor" |
312 | 365 | |
313 | -#: badger/models.py:63 | |
366 | +#: badger/models.py:62 | |
314 | 367 | msgid "Awardees" |
315 | 368 | msgstr "Premiados" |
316 | 369 | |
317 | -#: badger/models.py:67 | |
370 | +#: badger/models.py:66 | |
318 | 371 | msgid "Order" |
319 | 372 | msgstr "Ordem" |
320 | 373 | |
321 | -#: badger/models.py:70 | |
374 | +#: badger/models.py:69 | |
322 | 375 | msgid "Badge" |
323 | 376 | msgstr "Medalha" |
324 | 377 | |
... | ... | @@ -362,19 +415,15 @@ msgstr "Código" |
362 | 415 | msgid "Compressed" |
363 | 416 | msgstr "Compactado" |
364 | 417 | |
365 | -#: colab/custom_settings.py:53 | |
366 | -msgid "Image" | |
367 | -msgstr "Imagem" | |
368 | - | |
369 | 418 | #: colab/custom_settings.py:55 |
370 | 419 | msgid "Spreadsheet" |
371 | 420 | msgstr "Planilha" |
372 | 421 | |
373 | -#: colab/custom_settings.py:263 | |
422 | +#: colab/custom_settings.py:265 | |
374 | 423 | msgid "Planet Colab" |
375 | 424 | msgstr "" |
376 | 425 | |
377 | -#: colab/custom_settings.py:264 | |
426 | +#: colab/custom_settings.py:266 | |
378 | 427 | msgid "Colab blog aggregator" |
379 | 428 | msgstr "Agregador de blog Colab" |
380 | 429 | |
... | ... | @@ -390,9 +439,9 @@ msgstr "em" |
390 | 439 | msgid "Read original" |
391 | 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 | 446 | #: planet/templates/feedzilla/base.html:15 |
398 | 447 | msgid "Tags" |
... | ... | @@ -402,7 +451,7 @@ msgstr "Etiquetas" |
402 | 451 | msgid "Source Blogs" |
403 | 452 | msgstr "Blogs de origem" |
404 | 453 | |
405 | -#: planet/templates/feedzilla/base.html:22 | |
454 | +#: planet/templates/feedzilla/base.html:23 | |
406 | 455 | #: planet/templates/feedzilla/submit_blog.html:5 |
407 | 456 | msgid "Submit a blog" |
408 | 457 | msgstr "Sugerir um blog" |
... | ... | @@ -456,7 +505,7 @@ msgid "Latest collaborations" |
456 | 505 | msgstr "Últimas colaborações" |
457 | 506 | |
458 | 507 | #: search/forms.py:16 search/templates/search/search.html:41 |
459 | -#: templates/base.html:91 | |
508 | +#: templates/base.html:92 | |
460 | 509 | msgid "Search" |
461 | 510 | msgstr "Busca" |
462 | 511 | |
... | ... | @@ -465,89 +514,93 @@ msgstr "Busca" |
465 | 514 | msgid "Author" |
466 | 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 | 522 | msgid "Status" |
470 | 523 | msgstr "" |
471 | 524 | |
472 | -#: search/forms.py:25 search/views.py:36 | |
525 | +#: search/forms.py:26 search/views.py:36 | |
473 | 526 | msgid "Mailinglist" |
474 | 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 | 530 | msgid "Milestone" |
478 | 531 | msgstr "Etapa" |
479 | 532 | |
480 | -#: search/forms.py:30 search/views.py:51 | |
533 | +#: search/forms.py:31 search/views.py:51 | |
481 | 534 | msgid "Priority" |
482 | 535 | msgstr "Prioridade" |
483 | 536 | |
484 | -#: search/forms.py:31 search/views.py:56 | |
537 | +#: search/forms.py:32 search/views.py:56 | |
485 | 538 | msgid "Component" |
486 | 539 | msgstr "Componente" |
487 | 540 | |
488 | -#: search/forms.py:32 search/views.py:61 | |
541 | +#: search/forms.py:33 search/views.py:61 | |
489 | 542 | msgid "Severity" |
490 | 543 | msgstr "Seriedade" |
491 | 544 | |
492 | -#: search/forms.py:33 search/views.py:66 | |
545 | +#: search/forms.py:34 search/views.py:66 | |
493 | 546 | msgid "Reporter" |
494 | 547 | msgstr "Relator" |
495 | 548 | |
496 | -#: search/forms.py:34 search/views.py:73 | |
549 | +#: search/forms.py:35 search/views.py:73 | |
497 | 550 | msgid "Keywords" |
498 | 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 | 554 | msgid "Collaborators" |
502 | 555 | msgstr "Colaboradores" |
503 | 556 | |
504 | -#: search/forms.py:36 search/views.py:89 | |
557 | +#: search/forms.py:37 search/views.py:89 | |
505 | 558 | msgid "Repository" |
506 | 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 | 562 | msgid "Username" |
510 | 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 | 566 | msgid "Name" |
514 | 567 | msgstr "Nome" |
515 | 568 | |
516 | -#: search/forms.py:39 search/views.py:105 | |
569 | +#: search/forms.py:40 search/views.py:105 | |
517 | 570 | msgid "Institution" |
518 | 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 | 574 | msgid "Role" |
522 | 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 | 578 | #: search/templates/search/includes/search_filters.html:153 |
526 | 579 | #: search/templates/search/includes/search_filters.html:185 |
527 | 580 | #: search/templates/search/includes/search_filters.html:186 |
528 | 581 | msgid "Since" |
529 | 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 | 585 | #: search/templates/search/includes/search_filters.html:162 |
533 | 586 | #: search/templates/search/includes/search_filters.html:189 |
534 | 587 | #: search/templates/search/includes/search_filters.html:190 |
535 | 588 | msgid "Until" |
536 | 589 | msgstr "Até" |
537 | 590 | |
538 | -#: search/forms.py:43 search/views.py:116 | |
591 | +#: search/forms.py:44 search/views.py:116 | |
539 | 592 | msgid "Filename" |
540 | 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 | 596 | msgid "Used by" |
544 | 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 | 600 | msgid "File type" |
548 | 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 | 604 | msgid "Size" |
552 | 605 | msgstr "Tamanho" |
553 | 606 | |
... | ... | @@ -627,7 +680,9 @@ msgstr "Ordenar por" |
627 | 680 | msgid "Types" |
628 | 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 | 686 | msgid "Anonymous" |
632 | 687 | msgstr "Anônimo" |
633 | 688 | |
... | ... | @@ -683,35 +738,37 @@ msgstr "Por favor, digite o corpo da mensagem" |
683 | 738 | msgid "Message" |
684 | 739 | msgstr "Mensagem" |
685 | 740 | |
686 | -#: super_archives/views.py:90 | |
741 | +#: super_archives/views.py:92 | |
687 | 742 | msgid "Error trying to connect to Mailman API" |
688 | 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 | 746 | msgid "Timeout trying to connect to Mailman API" |
692 | 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 | 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 | 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 | 760 | msgid "You cannot send an empty email" |
704 | 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 | 764 | msgid "Mailing list does not exist" |
708 | 765 | msgstr "Lista de e-mail não existe" |
709 | 766 | |
710 | -#: super_archives/views.py:108 | |
767 | +#: super_archives/views.py:112 | |
711 | 768 | msgid "Unknown error trying to connect to Mailman API" |
712 | 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 | 772 | msgid "" |
716 | 773 | "The email address you are trying to verify either has already been verified " |
717 | 774 | "or does not exist." |
... | ... | @@ -719,7 +776,7 @@ msgstr "" |
719 | 776 | "O endereço de e-mail que você está tentando verificar ou já foi verificado " |
720 | 777 | "ou não existe." |
721 | 778 | |
722 | -#: super_archives/views.py:154 | |
779 | +#: super_archives/views.py:162 | |
723 | 780 | msgid "" |
724 | 781 | "The email address you are trying to verify is already an active email " |
725 | 782 | "address." |
... | ... | @@ -727,73 +784,78 @@ msgstr "" |
727 | 784 | "O endereço de e-mail que você está tentando verificar já é um endereço de e-" |
728 | 785 | "mail ativo" |
729 | 786 | |
730 | -#: super_archives/views.py:164 | |
787 | +#: super_archives/views.py:172 | |
731 | 788 | msgid "Email address verified!" |
732 | 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 | 795 | #: super_archives/templates/message-preview.html:42 |
796 | +#: super_archives/templates/message-preview.html:62 | |
735 | 797 | msgid "by" |
736 | 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 | 802 | msgid "ago" |
741 | 803 | msgstr "atrás" |
742 | 804 | |
743 | -#: super_archives/templates/message-thread.html:33 | |
805 | +#: super_archives/templates/message-thread.html:35 | |
744 | 806 | msgid "You must login before voting." |
745 | 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 | 810 | msgid "Order by" |
749 | 811 | msgstr "Ordernar por" |
750 | 812 | |
751 | -#: super_archives/templates/message-thread.html:132 | |
813 | +#: super_archives/templates/message-thread.html:136 | |
752 | 814 | msgid "Votes" |
753 | 815 | msgstr "Votos" |
754 | 816 | |
755 | -#: super_archives/templates/message-thread.html:136 | |
817 | +#: super_archives/templates/message-thread.html:140 | |
756 | 818 | msgid "Date" |
757 | 819 | msgstr "Data" |
758 | 820 | |
759 | -#: super_archives/templates/message-thread.html:141 | |
821 | +#: super_archives/templates/message-thread.html:145 | |
760 | 822 | msgid "Related:" |
761 | 823 | msgstr "Relacionado:" |
762 | 824 | |
763 | -#: super_archives/templates/message-thread.html:152 | |
825 | +#: super_archives/templates/message-thread.html:156 | |
764 | 826 | msgid "Statistics:" |
765 | 827 | msgstr "Estátisticas:" |
766 | 828 | |
767 | -#: super_archives/templates/message-thread.html:156 | |
829 | +#: super_archives/templates/message-thread.html:160 | |
768 | 830 | msgid "started at" |
769 | 831 | msgstr "começou às" |
770 | 832 | |
771 | -#: super_archives/templates/message-thread.html:162 | |
833 | +#: super_archives/templates/message-thread.html:166 | |
772 | 834 | msgid "viewed" |
773 | 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 | 840 | msgid "times" |
779 | 841 | msgstr "vezes" |
780 | 842 | |
781 | -#: super_archives/templates/message-thread.html:167 | |
843 | +#: super_archives/templates/message-thread.html:171 | |
782 | 844 | msgid "answered" |
783 | 845 | msgstr "respondido" |
784 | 846 | |
785 | -#: super_archives/templates/message-thread.html:172 | |
847 | +#: super_archives/templates/message-thread.html:176 | |
786 | 848 | msgid "voted" |
787 | 849 | msgstr "votado" |
788 | 850 | |
789 | -#: super_archives/templates/message-thread.html:178 | |
851 | +#: super_archives/templates/message-thread.html:182 | |
790 | 852 | msgid "Tags:" |
791 | 853 | msgstr "Etiquetas:" |
792 | 854 | |
793 | 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 | 860 | #: super_archives/templates/superarchives/thread-dashboard.html:15 |
799 | 861 | msgid "latest" |
... | ... | @@ -808,6 +870,33 @@ msgstr "mais..." |
808 | 870 | msgid "most relevant" |
809 | 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 | 900 | #: super_archives/templates/superarchives/emails/email_verification.txt:2 |
812 | 901 | #, python-format |
813 | 902 | msgid "" |
... | ... | @@ -826,15 +915,20 @@ msgstr "" |
826 | 915 | "Se você não é %(username)s ou não pediu uma verificação você pode ignorar " |
827 | 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 | 924 | msgid "Reply" |
831 | 925 | msgstr "Responder" |
832 | 926 | |
833 | -#: super_archives/templates/superarchives/includes/message.html:56 | |
927 | +#: super_archives/templates/superarchives/includes/message.html:63 | |
834 | 928 | msgid "Send a message" |
835 | 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 | 932 | msgid "" |
839 | 933 | "After sending a message it will take few minutes before it shows up in here. " |
840 | 934 | "Why don't you grab a coffee?" |
... | ... | @@ -842,7 +936,7 @@ msgstr "" |
842 | 936 | "Depois de enviar uma mensagem levará alguns minutos antes dela aparecer " |
843 | 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 | 940 | msgid "Send" |
847 | 941 | msgstr "Enviar" |
848 | 942 | |
... | ... | @@ -862,51 +956,63 @@ msgstr "Não encontrado. Continue procurando! :)" |
862 | 956 | msgid "Ooopz... something went wrong!" |
863 | 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 | 964 | msgid "Contribute" |
867 | 965 | msgstr "Contribua" |
868 | 966 | |
869 | 967 | #: templates/base.html:82 |
870 | -msgid "New Ticket" | |
871 | -msgstr "Novo Tíquete" | |
872 | - | |
873 | -#: templates/base.html:84 | |
874 | 968 | msgid "Timeline" |
875 | 969 | msgstr "Histórico" |
876 | 970 | |
877 | -#: templates/base.html:85 | |
971 | +#: templates/base.html:83 | |
878 | 972 | msgid "Roadmap" |
879 | 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 | 979 | #: templates/base.html:87 |
886 | 980 | msgid "View Tickets" |
887 | 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 | 992 | msgid "My Profile" |
891 | 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 | 1000 | msgid "Search here..." |
895 | 1001 | msgstr "Pesquise aqui..." |
896 | 1002 | |
897 | -#: templates/base.html:139 | |
1003 | +#: templates/base.html:142 | |
898 | 1004 | msgid "The login has failed. Please, try again." |
899 | 1005 | msgstr "O login falhou. Por favor, tente novamente." |
900 | 1006 | |
901 | -#: templates/base.html:164 | |
1007 | +#: templates/base.html:167 | |
902 | 1008 | msgid "Last email imported at" |
903 | 1009 | msgstr "Último e-mail importado em" |
904 | 1010 | |
905 | -#: templates/base.html:169 | |
1011 | +#: templates/base.html:172 | |
906 | 1012 | msgid "The contents of this site is published under license" |
907 | 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 | 1016 | msgid "Creative Commons - attribution, non-commercial" |
911 | 1017 | msgstr "Creative Commons - atribuição e não-comercial" |
912 | 1018 | |
... | ... | @@ -934,10 +1040,6 @@ msgstr "Discussões Mais Relevantes" |
934 | 1040 | msgid "RSS - Most Relevant Threads" |
935 | 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 | 1043 | #: templates/home.html:64 |
942 | 1044 | msgid "Latest Threads" |
943 | 1045 | msgstr "Últimas Discussões" |
... | ... | @@ -954,6 +1056,37 @@ msgstr "Vontade de ajudar" |
954 | 1056 | msgid "INTERLEGIS COMMUNITIES" |
955 | 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 | 1090 | #~ msgid "Community inside participations" |
958 | 1091 | #~ msgstr "Participações internas da comunidade" |
959 | 1092 | ... | ... |
src/planet/templates/feedzilla/base.html
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | {% load i18n feedzilla_tags %} |
3 | 3 | |
4 | 4 | {% block main-content %} |
5 | - <h2>{% trans 'Planet' %}</h2> | |
5 | + <h2>{% trans 'Planet - Community Blogs' %}</h2> | |
6 | 6 | <hr/> |
7 | 7 | |
8 | 8 | <div id="planet" class="row"> |
... | ... | @@ -17,10 +17,12 @@ |
17 | 17 | </div> |
18 | 18 | <div class="well"> |
19 | 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 | 26 | </div> |
25 | 27 | </div> |
26 | 28 | </div> | ... | ... |
... | ... | @@ -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 @@ |
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 | 4 | import urllib2 |
5 | 5 | |
6 | 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 | 11 | from accounts.models import User |
10 | 12 | from hitcounter.models import HitCounterModelMixin |
... | ... | @@ -81,6 +83,7 @@ class Ticket(models.Model, HitCounterModelMixin): |
81 | 83 | collaborators = models.TextField(blank=True) |
82 | 84 | created = models.DateTimeField(blank=True, null=True) |
83 | 85 | modified = models.DateTimeField(blank=True, null=True) |
86 | + modified_by = models.TextField(blank=True) | |
84 | 87 | |
85 | 88 | class Meta: |
86 | 89 | managed = False |
... | ... | @@ -95,6 +98,12 @@ class Ticket(models.Model, HitCounterModelMixin): |
95 | 98 | except User.DoesNotExist: |
96 | 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 | 108 | class Wiki(models.Model, HitCounterModelMixin): |
100 | 109 | name = models.TextField(primary_key=True) |
... | ... | @@ -103,6 +112,7 @@ class Wiki(models.Model, HitCounterModelMixin): |
103 | 112 | collaborators = models.TextField(blank=True) |
104 | 113 | created = models.DateTimeField(blank=True, null=True) |
105 | 114 | modified = models.DateTimeField(blank=True, null=True) |
115 | + modified_by = models.TextField(blank=True) | |
106 | 116 | |
107 | 117 | class Meta: |
108 | 118 | managed = False |
... | ... | @@ -116,3 +126,54 @@ class Wiki(models.Model, HitCounterModelMixin): |
116 | 126 | return User.objects.get(username=self.author) |
117 | 127 | except User.DoesNotExist: |
118 | 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 | 19 | icon_name = indexes.CharField(indexed=False) |
20 | 20 | fullname_and_username = indexes.CharField(null=True, stored=False) |
21 | 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 | 25 | def get_updated_field(self): |
24 | 26 | return 'modified' |
... | ... | @@ -30,33 +32,63 @@ class BaseIndex(indexes.SearchIndex): |
30 | 32 | return math.log(obj.hits) |
31 | 33 | |
32 | 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 | 39 | data = super(BaseIndex, self).prepare(obj) |
34 | 40 | data['boost'] = self.get_boost(obj) |
41 | + | |
35 | 42 | return data |
36 | 43 | |
37 | 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 | 61 | return obj.author |
42 | 62 | |
43 | 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 | 72 | return obj.author |
47 | 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 | 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 | 17 | order = forms.CharField(widget=forms.HiddenInput(), required=False) |
18 | 18 | type = forms.CharField(required=False, label=_(u'Type')) |
19 | 19 | author = forms.CharField(required=False, label=_(u'Author')) |
20 | + modified_by = forms.CharField(required=False, label=_(u'Modified by')) | |
20 | 21 | # ticket status |
21 | 22 | tag = forms.CharField(required=False, label=_(u'Status')) |
22 | 23 | # mailinglist tag |
... | ... | @@ -122,6 +123,11 @@ class ColabSearchForm(SearchForm): |
122 | 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 | 131 | if self.cleaned_data['milestone']: |
126 | 132 | sqs = sqs.filter(milestone=self.cleaned_data['milestone']) |
127 | 133 | if self.cleaned_data['priority']: | ... | ... |
src/static/css/screen.css
... | ... | @@ -413,3 +413,18 @@ span.highlighted { |
413 | 413 | .vcard .label { |
414 | 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 @@ |
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 | 11 | |
12 | 12 | from django.db import transaction |
13 | 13 | from django.template.defaultfilters import slugify |
14 | +from super_archives.utils.email import colab_send_email | |
14 | 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 | 19 | from super_archives.models import MailingList, Message, \ |
17 | 20 | Thread, EmailAddress |
... | ... | @@ -196,6 +199,21 @@ class Command(BaseCommand, object): |
196 | 199 | email_addr.save() |
197 | 200 | |
198 | 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 | 218 | email = Message.all_objects.create( |
201 | 219 | message_id=email_msg.get('Message-ID'), | ... | ... |
src/super_archives/models.py
... | ... | @@ -326,18 +326,27 @@ class Message(models.Model): |
326 | 326 | |
327 | 327 | @property |
328 | 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 | 335 | return None |
333 | 336 | |
337 | + # An alias for author | |
334 | 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 | 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 | 351 | @property |
343 | 352 | def icon_name(self): | ... | ... |
src/super_archives/search_indexes.py
... | ... | @@ -50,17 +50,34 @@ class ThreadIndex(BaseIndex, indexes.Indexable): |
50 | 50 | ) |
51 | 51 | |
52 | 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 | 56 | def prepare_author_url(self, obj): |
56 | 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 | 70 | return None |
60 | 71 | |
61 | 72 | def prepare_created(self, obj): |
62 | 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 | 81 | def prepare_icon_name(self, obj): |
65 | 82 | return u'envelope' |
66 | 83 | ... | ... |
src/super_archives/templates/message-preview.html
... | ... | @@ -28,33 +28,41 @@ |
28 | 28 | {% highlight result.description with query max_length "150" %} |
29 | 29 | {% else %} |
30 | 30 | {% if result.latest_description %} |
31 | - {{ result.latest_description|escape|truncatechars:150 }} | |
31 | + {{ result.latest_description|striptags|escape|truncatechars:150 }} | |
32 | 32 | {% elif result.description %} |
33 | - {{ result.description|escape|truncatechars:150 }} | |
33 | + {{ result.description|striptags|escape|truncatechars:150 }} | |
34 | 34 | {% endif %} |
35 | 35 | {% endif %} |
36 | 36 | </span> |
37 | 37 | {% endif %} |
38 | 38 | |
39 | -{% if result.fullname or result.modified %} | |
39 | +{% if result.fullname or result.modified or result.modified_by %} | |
40 | 40 | <div class="quiet"> |
41 | - {% if result.fullname %} | |
41 | + {% if result.modified_by %} | |
42 | 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 | 56 | </a> |
51 | 57 | {% else %} |
52 | - <span>{{ result.fullname }}</span> | |
58 | + </span> | |
53 | 59 | {% endif %} |
54 | 60 | </span> |
61 | + {% else %} | |
62 | + <span class="pull-left">{% trans "by" %} {% trans "Anonymous" %}</span> | |
55 | 63 | {% endif %} |
56 | 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 | 66 | {% endif %} |
59 | 67 | </div> |
60 | 68 | {% endif %} | ... | ... |
src/super_archives/templates/message-thread.html
... | ... | @@ -3,6 +3,8 @@ |
3 | 3 | |
4 | 4 | {% trans "Anonymous" as anonymous %} |
5 | 5 | |
6 | +{% block title %}{{ first_msg.subject_clean }}{% endblock %} | |
7 | + | |
6 | 8 | {% block head_js %} |
7 | 9 | |
8 | 10 | <script> |
... | ... | @@ -98,6 +100,8 @@ |
98 | 100 | {% if user.is_active %} |
99 | 101 | $('.reply.btn', this).on('click', focus_reply); |
100 | 102 | {% endif %} |
103 | + | |
104 | + $('.message-link').popover({'placement': 'right'}); | |
101 | 105 | }); |
102 | 106 | |
103 | 107 | </script> | ... | ... |
src/super_archives/templates/superarchives/emails/email_blank_subject.txt
0 → 100644
... | ... | @@ -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 | 13 | {% if userprofile.get_absolute_url %} |
14 | 14 | </a> |
15 | 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 | 23 | </div> |
17 | 24 | |
18 | 25 | {% if not reply %} | ... | ... |
src/super_archives/templates/superarchives/thread-dashboard.html
... | ... | @@ -2,12 +2,12 @@ |
2 | 2 | {% load i18n %} |
3 | 3 | |
4 | 4 | {% block main-content %} |
5 | - <h2>{% trans 'Discussions'|title %}</h2> | |
5 | + <h2>{% trans 'Groups'|title %}</h2> | |
6 | 6 | <hr/> |
7 | 7 | |
8 | - {% for listname, latest, most_relevant in lists %} | |
8 | + {% for listname, description, latest, most_relevant in lists %} | |
9 | 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 | 11 | <hr/> |
12 | 12 | |
13 | 13 | <div class="row"> | ... | ... |
src/super_archives/views.py
... | ... | @@ -20,6 +20,7 @@ from django.shortcuts import render, redirect, get_object_or_404 |
20 | 20 | |
21 | 21 | from haystack.query import SearchQuerySet |
22 | 22 | |
23 | +from accounts.utils import mailman | |
23 | 24 | from .utils.email import send_verification_email |
24 | 25 | from .models import MailingList, Thread, EmailAddress, \ |
25 | 26 | EmailAddressValidation, Message |
... | ... | @@ -74,6 +75,7 @@ class ThreadView(View): |
74 | 75 | raise http.Http404 |
75 | 76 | |
76 | 77 | data = { |
78 | + 'in_reply_to': thread.message_set.last().message_id, | |
77 | 79 | 'email_from': request.user.email, |
78 | 80 | 'name_from': request.user.get_full_name(), |
79 | 81 | 'subject': thread.message_set.first().subject_clean, |
... | ... | @@ -93,10 +95,12 @@ class ThreadView(View): |
93 | 95 | error_msg = _('Timeout trying to connect to Mailman API') |
94 | 96 | |
95 | 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 | 104 | else: |
101 | 105 | if not error_msg: |
102 | 106 | if resp is not None: |
... | ... | @@ -117,13 +121,17 @@ class ThreadDashboardView(View): |
117 | 121 | def get(self, request): |
118 | 122 | MAX = 6 |
119 | 123 | context = {} |
124 | + all_lists = mailman.all_lists(description=True) | |
120 | 125 | |
121 | 126 | context['lists'] = [] |
122 | 127 | lists = MailingList.objects.filter() |
123 | 128 | for list_ in MailingList.objects.order_by('name'): |
124 | 129 | context['lists'].append(( |
125 | 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 | 135 | SearchQuerySet().filter(type='thread', tag=list_.name)[:MAX], |
128 | 136 | )) |
129 | 137 | ... | ... |
src/templates/base.html
... | ... | @@ -5,6 +5,12 @@ |
5 | 5 | {% block head %} |
6 | 6 | <meta charset="UTF-8" /> |
7 | 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 | 14 | <title>Colab - {% block title %}Colab{% endblock %}</title> |
9 | 15 | |
10 | 16 | <link rel="shortcut icon" type="image/x-icon" href="{{ STATIC_URL }}img/interlegis.ico"> |
... | ... | @@ -22,6 +28,7 @@ |
22 | 28 | <link rel="stylesheet" href="{{ STATIC_URL }}css/screen.css" |
23 | 29 | type="text/css" media="screen" /> |
24 | 30 | |
31 | + <!-- JQuery 2+ won't work for IE < 9 --> | |
25 | 32 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery-2.0.3.min.js"></script> |
26 | 33 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery.debouncedresize.js"></script> |
27 | 34 | <script type="text/javascript" src="{{ STATIC_URL }}third-party/jquery.cookie.js"></script> |
... | ... | @@ -69,7 +76,7 @@ |
69 | 76 | <div class="collapse navbar-collapse navbar-main"> |
70 | 77 | <ul class="nav navbar-nav"> |
71 | 78 | <li> |
72 | - <a href="{% url 'thread_list' %}">{% trans "Discussions" %}</a> | |
79 | + <a href="{% url 'thread_list' %}">{% trans "Groups" %}</a> | |
73 | 80 | </li> |
74 | 81 | <li> |
75 | 82 | <a href="{% url "feedzilla_index" %}">{% trans "Planet" %}</a> |
... | ... | @@ -78,13 +85,13 @@ |
78 | 85 | <a href="#" class="dropdown-toggle" data-toggle="dropdown">{% trans "Contribute" %} <b class="caret"></b></a> |
79 | 86 | <ul class="dropdown-menu"> |
80 | 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 | 90 | {% if user.is_active %} |
82 | 91 | <li><a href="/newticket">{% trans "New Ticket" %}</a></li> |
83 | 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 | 93 | <li><a href="/report">{% trans "View Tickets" %}</a></li> |
94 | + <li><a href="/browser">{% trans "Browse Source" %}</a></li> | |
88 | 95 | </ul> |
89 | 96 | </li> |
90 | 97 | <li class="hidden-lg hidden-md"> |
... | ... | @@ -95,7 +102,8 @@ |
95 | 102 | <ul class="nav navbar-nav navbar-right"> |
96 | 103 | {% if not user.is_authenticated %} |
97 | 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 | 107 | {% else %} |
100 | 108 | <li id="user-menu" class="dropdown"> |
101 | 109 | <a href="#" class="dropdown-toggle user" data-toggle="dropdown">{% gravatar user.email 40 %} <b class="caret"></b> </a> |
... | ... | @@ -109,7 +117,8 @@ |
109 | 117 | </div> |
110 | 118 | <div> |
111 | 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 | 122 | </div> |
114 | 123 | </div> |
115 | 124 | </li> |
... | ... | @@ -161,16 +170,17 @@ |
161 | 170 | <div class="row"> </div> |
162 | 171 | |
163 | 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 | 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 | 184 | </div> |
175 | 185 | {% endblock %} |
176 | 186 | ... | ... |
src/templates/home.html
... | ... | @@ -2,7 +2,9 @@ |
2 | 2 | {% load i18n %} |
3 | 3 | |
4 | 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 | 8 | {% endblock %} |
7 | 9 | |
8 | 10 | {% block header %} | ... | ... |
... | ... | @@ -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 | 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> | ... | ... |