diff --git a/.dockerignore b/.dockerignore
index 8f4c8f147..318700ad6 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,4 +1,14 @@
media
collected_static
.git
+.gitignore
whoosh
+bower
+*.log
+~*
+*.pyc
+.cache
+.project
+.travis.yml
+.env
+.idea
diff --git a/Dockerfile b/Dockerfile
index 9c33fcd0f..2f2fe688b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,9 @@
-FROM alpine:3.8
+FROM alpine:3.10
ENV BUILD_PACKAGES postgresql-dev graphviz-dev graphviz build-base git pkgconfig \
python3-dev libxml2-dev jpeg-dev libressl-dev libffi-dev libxslt-dev \
nodejs py3-lxml py3-magic postgresql-client poppler-utils antiword \
- curl jq openssh-client vim bash
+ curl jq openssh-client vim bash postgresql-client cairo-dev
RUN apk update --update-cache && apk upgrade
@@ -13,6 +13,7 @@ RUN apk add --no-cache python3 nginx tzdata && \
python3 -m ensurepip && \
rm -r /usr/lib/python*/ensurepip && \
pip3 install --upgrade pip setuptools && \
+ pip3 install wheel && \
rm -r /root/.cache && \
rm -f /etc/nginx/conf.d/*
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 93cb12778..3d689856f 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -20,12 +20,12 @@ easy-thumbnails==2.5
python-decouple==3.1
psycopg2-binary==2.7.6.1
pyyaml==4.2b1
-pytz==2018.9
+pytz==2019.3
rtyaml==0.0.5
python-magic==0.4.15
unipath==1.1
-WeasyPrint==44
-Pillow==5.1.0
+WeasyPrint==50
+Pillow==6.2.0
gunicorn==19.9.0
kombu==4.2.0
billiard==3.5.0.2
diff --git a/sapl/api/views.py b/sapl/api/views.py
index b9f0a2403..7a7579a01 100644
--- a/sapl/api/views.py
+++ b/sapl/api/views.py
@@ -3,6 +3,7 @@ import logging
from django import apps
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import FieldError
from django.db.models import Q
from django.db.models.fields.files import FileField
from django.utils.decorators import classonlymethod
@@ -26,10 +27,11 @@ from sapl.base.models import Autor, AppConfig, DOC_ADM_OSTENSIVO
from sapl.materia.models import Proposicao, TipoMateriaLegislativa,\
MateriaLegislativa, Tramitacao
from sapl.norma.models import NormaJuridica
+from sapl.painel.models import Cronometro
from sapl.parlamentares.models import Parlamentar
from sapl.protocoloadm.models import DocumentoAdministrativo,\
DocumentoAcessorioAdministrativo, TramitacaoAdministrativo, Anexado
-from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao
+from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao, SessaoPlenariaPresenca
from sapl.utils import models_with_gr_for_model, choice_anos_com_sessaoplenaria
@@ -514,7 +516,6 @@ class _SessaoPlenariaViewSet:
@action(detail=False)
def years(self, request, *args, **kwargs):
years = choice_anos_com_sessaoplenaria()
-
serializer = ChoiceSerializer(years, many=True)
return Response(serializer.data)
@@ -533,6 +534,21 @@ class _SessaoPlenariaViewSet:
return Response(serializer.data)
+ @action(detail=True, methods=['GET'])
+ def parlamentares_presentes(self, request, *args, **kwargs):
+ sessao = self.get_object()
+ parlamentares = Parlamentar.objects.filter(sessaoplenariapresenca__sessao_plenaria=sessao)
+
+ page = self.paginate_queryset(parlamentares)
+ if page is not None:
+ serializer = SaplApiViewSetConstrutor.get_class_for_model(
+ Parlamentar).serializer_class(page, many=True)
+ return self.get_paginated_response(serializer.data)
+
+ serializer = self.get_serializer(page, many=True)
+ return Response(serializer.data)
+
+
@customize(NormaJuridica)
class _NormaJuridicaViewset:
@@ -540,3 +556,17 @@ class _NormaJuridicaViewset:
def destaques(self, request, *args, **kwargs):
self.queryset = self.get_queryset().filter(norma_de_destaque=True)
return self.list(request, *args, **kwargs)
+
+
+@customize(Cronometro)
+class _CronometroViewSet:
+
+ def get_queryset(self, *args, **kwargs):
+ qs = super().get_queryset()
+
+ try:
+ filter_condition = {k:v[0] for (k,v) in self.request.GET.items()}
+ qs = qs.filter(**filter_condition)
+ except FieldError as e:
+ pass
+ return qs
\ No newline at end of file
diff --git a/sapl/audiencia/forms.py b/sapl/audiencia/forms.py
index d62900df6..09e161917 100755
--- a/sapl/audiencia/forms.py
+++ b/sapl/audiencia/forms.py
@@ -1,17 +1,16 @@
import logging
from django import forms
-from sapl.settings import MAX_DOC_UPLOAD_SIZE
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import transaction
from django.utils.translation import ugettext_lazy as _
-from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica, AnexoAudienciaPublica
-from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout
-from sapl.crispy_layout_mixin import SaplFormHelper
-from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
+from crispy_forms.layout import Button, Column, Fieldset, HTML, Layout
+
+from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica, AnexoAudienciaPublica
+from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, SaplFormLayout, to_row
from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
-from sapl.utils import timezone, FileFieldCheckMixin
+from sapl.utils import timezone, FileFieldCheckMixin, validar_arquivo
class AudienciaForm(FileFieldCheckMixin, forms.ModelForm):
logger = logging.getLogger(__name__)
@@ -119,17 +118,14 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm):
upload_ata = self.cleaned_data.get('upload_ata', False)
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_pauta and upload_pauta.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Pauta da Audiência Pública deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_pauta.size/1024)/1024))
+ if upload_pauta:
+ validar_arquivo(upload_pauta, "Pauta da Audiência Pública")
- if upload_ata and upload_ata.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Ata da Audiência Pública deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_ata.size/1024)/1024))
+ if upload_ata:
+ validar_arquivo(upload_ata, "Ata da Audiência Pública")
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo da Audiência Pública deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo da Audiência Pública")
return cleaned_data
@@ -164,8 +160,7 @@ class AnexoAudienciaPublicaForm(forms.ModelForm):
arquivo = self.cleaned_data.get('arquivo', False)
- if arquivo and arquivo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (arquivo.size/1024)/1024))
+ if arquivo:
+ validar_arquivo(arquivo, "Arquivo")
return self.cleaned_data
diff --git a/sapl/audiencia/migrations/0013_auto_20191023_1522.py b/sapl/audiencia/migrations/0013_auto_20191023_1522.py
new file mode 100644
index 000000000..63886a25f
--- /dev/null
+++ b/sapl/audiencia/migrations/0013_auto_20191023_1522.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-23 18:22
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.audiencia.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('audiencia', '0012_auto_20191001_1115'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='audienciapublica',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.audiencia.models.anexo_upload_path, verbose_name='Anexo da Audiência Pública'),
+ ),
+ migrations.AlterField(
+ model_name='audienciapublica',
+ name='upload_ata',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.audiencia.models.ata_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Ata da Audiência Pública'),
+ ),
+ migrations.AlterField(
+ model_name='audienciapublica',
+ name='upload_pauta',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.audiencia.models.pauta_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Pauta da Audiência Pública'),
+ ),
+ ]
diff --git a/sapl/audiencia/migrations/0014_auto_20191023_1538.py b/sapl/audiencia/migrations/0014_auto_20191023_1538.py
new file mode 100644
index 000000000..4b9cdfbb3
--- /dev/null
+++ b/sapl/audiencia/migrations/0014_auto_20191023_1538.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-23 18:38
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('audiencia', '0013_auto_20191023_1522'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='anexoaudienciapublica',
+ name='arquivo',
+ field=models.FileField(max_length=300, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.utils.texto_upload_path, verbose_name='Arquivo'),
+ ),
+ ]
diff --git a/sapl/audiencia/models.py b/sapl/audiencia/models.py
index 22a1accc9..d4c1b11cb 100755
--- a/sapl/audiencia/models.py
+++ b/sapl/audiencia/models.py
@@ -87,7 +87,7 @@ class AudienciaPublica(models.Model):
max_length=150, blank=True,
verbose_name=_('URL Arquivo Vídeo (Formatos MP4 / FLV / WebM)'))
upload_pauta = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=pauta_upload_path,
@@ -95,7 +95,7 @@ class AudienciaPublica(models.Model):
verbose_name=_('Pauta da Audiência Pública'),
validators=[restringe_tipos_de_arquivo_txt])
upload_ata = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=ata_upload_path,
@@ -103,7 +103,7 @@ class AudienciaPublica(models.Model):
storage=OverwriteStorage(),
validators=[restringe_tipos_de_arquivo_txt])
upload_anexo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=anexo_upload_path,
@@ -167,7 +167,7 @@ class AnexoAudienciaPublica(models.Model):
audiencia = models.ForeignKey(AudienciaPublica,
on_delete=models.PROTECT)
arquivo = models.FileField(
- max_length=200,
+ max_length=300,
upload_to=texto_upload_path,
storage=OverwriteStorage(),
verbose_name=_('Arquivo'))
diff --git a/sapl/base/admin.py b/sapl/base/admin.py
index 88633b0fb..46ab77bf3 100644
--- a/sapl/base/admin.py
+++ b/sapl/base/admin.py
@@ -1,8 +1,9 @@
from django.contrib import admin
-from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from reversion.models import Revision
+
+from sapl.base.models import AuditLog
from sapl.utils import register_all_models_in_admin
register_all_models_in_admin(__name__)
@@ -20,5 +21,31 @@ class RevisionAdmin(admin.ModelAdmin):
self.message_user(request, _('You cannot change history.'))
return redirect('admin:reversion_revision_changelist')
-
admin.site.register(Revision, RevisionAdmin)
+
+
+class AuditLogAdmin(admin.ModelAdmin):
+ pass
+
+ def has_add_permission(self, request):
+ return False
+
+ # def has_change_permission(self, request, obj=None):
+ # return False
+ #
+ def has_delete_permission(self, request, obj=None):
+ return False
+
+ def save_model(self, request, obj, form, change):
+ pass
+
+ def delete_model(self, request, obj):
+ pass
+
+ def save_related(self, request, form, formsets, change):
+ pass
+
+
+# Na linha acima register_all_models_in_admin registrou AuditLog
+admin.site.unregister(AuditLog)
+admin.site.register(AuditLog, AuditLogAdmin)
diff --git a/sapl/base/forms.py b/sapl/base/forms.py
index 10ff7e983..22179991b 100644
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -843,16 +843,18 @@ class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet):
self.form.initial['exibir_ordem_dia'] = True
self.filters['data_inicio'].label = 'Período (Inicial - Final)'
+
+ self.form.fields['legislatura'].required = True
tipo_sessao_ordinaria = self.filters['tipo'].queryset.filter(nome='Ordinária')
if tipo_sessao_ordinaria:
self.form.initial['tipo'] = tipo_sessao_ordinaria.first()
- row1 = to_row([('data_inicio', 12)])
- row2 = to_row([('legislatura', 4),
+ row1 = to_row([('legislatura', 4),
('sessao_legislativa', 4),
('tipo', 4)])
- row3 = to_row([('exibir_ordem_dia', 12)])
+ row2 = to_row([('exibir_ordem_dia', 12)])
+ row3 = to_row([('data_inicio', 12)])
buttons = FormActions(
*[
@@ -1326,9 +1328,14 @@ class ConfiguracoesAppForm(ModelForm):
'tramitacao_materia',
'tramitacao_documento']
- def clean_mostrar_brasao_painel(self):
- mostrar_brasao_painel = self.cleaned_data.get(
- 'mostrar_brasao_painel', False)
+
+ def clean(self):
+ cleaned_data = super().clean()
+
+ if not self.is_valid():
+ return cleaned_data
+
+ mostrar_brasao_painel = self.cleaned_data.get('mostrar_brasao_painel', False)
casa = CasaLegislativa.objects.first()
if not casa:
@@ -1341,7 +1348,7 @@ class ConfiguracoesAppForm(ModelForm):
raise ValidationError("Não há logitipo configurado para esta "
"Casa legislativa.")
- return mostrar_brasao_painel
+ return cleaned_data
class RecuperarSenhaForm(PasswordResetForm):
diff --git a/sapl/base/migrations/0038_auditlog.py b/sapl/base/migrations/0038_auditlog.py
new file mode 100644
index 000000000..ba89599e7
--- /dev/null
+++ b/sapl/base/migrations/0038_auditlog.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-15 13:33
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('base', '0037_auto_20190527_0901'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='AuditLog',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('username', models.CharField(blank=True, db_index=True, max_length=100, verbose_name='username')),
+ ('operation', models.CharField(db_index=True, max_length=1, verbose_name='operation')),
+ ('timestamp', models.DateTimeField(db_index=True, verbose_name='timestamp')),
+ ('object', models.CharField(blank=True, max_length=4096, verbose_name='object')),
+ ('object_id', models.PositiveIntegerField(db_index=True, verbose_name='object_id')),
+ ('model_name', models.CharField(db_index=True, max_length=100, verbose_name='model')),
+ ('app_name', models.CharField(db_index=True, max_length=100, verbose_name='app')),
+ ],
+ options={
+ 'verbose_name': 'AuditLog',
+ 'verbose_name_plural': 'AuditLogs',
+ 'ordering': ('-id',),
+ },
+ ),
+ ]
diff --git a/sapl/base/migrations/0040_merge_20191030_1655.py b/sapl/base/migrations/0040_merge_20191030_1655.py
new file mode 100644
index 000000000..a9f1d2e39
--- /dev/null
+++ b/sapl/base/migrations/0040_merge_20191030_1655.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-30 19:55
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('base', '0038_auditlog'),
+ ('base', '0039_auto_20190913_1228'),
+ ]
+
+ operations = [
+ ]
diff --git a/sapl/base/migrations/0041_auto_20191204_1130.py b/sapl/base/migrations/0041_auto_20191204_1130.py
new file mode 100644
index 000000000..fa6cd6b98
--- /dev/null
+++ b/sapl/base/migrations/0041_auto_20191204_1130.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-12-04 14:30
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('base', '0040_merge_20191030_1655'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='appconfig',
+ name='assinatura_ata',
+ field=models.CharField(choices=[('M', 'Mesa Diretora da Sessão'), ('P', 'Apenas o Presidente da Sessão'), ('T', 'Todos os Parlamentares Presentes na Sessão')], default='T', max_length=1, verbose_name='Quem deve assinar a ata'),
+ ),
+ ]
diff --git a/sapl/base/models.py b/sapl/base/models.py
index 7f2ea8d6b..2b4c1a810 100644
--- a/sapl/base/models.py
+++ b/sapl/base/models.py
@@ -136,7 +136,7 @@ class AppConfig(models.Model):
max_length=1, choices=POLITICA_PROTOCOLO_CHOICES, default='O')
assinatura_ata = models.CharField(
- verbose_name=_('Quem deve assina a ata'),
+ verbose_name=_('Quem deve assinar a ata'),
max_length=1, choices=ASSINATURA_ATA_CHOICES, default='T')
mostrar_brasao_painel = models.BooleanField(
@@ -265,3 +265,43 @@ class AutorUser(models.Model):
def __str__(self):
return "%s - %s" % (self.autor, self.user)
+
+
+class AuditLog(models.Model):
+
+ operation = ('C', 'D', 'U')
+
+ MAX_DATA_LENGTH = 4096 # 4KB de texto
+
+ username = models.CharField(max_length=100,
+ verbose_name=_('username'),
+ blank=True,
+ db_index=True)
+ operation = models.CharField(max_length=1,
+ verbose_name=_('operation'),
+ db_index=True)
+ timestamp = models.DateTimeField(verbose_name=_('timestamp'),
+ db_index=True)
+ object = models.CharField(max_length=MAX_DATA_LENGTH,
+ blank=True,
+ verbose_name=_('object'))
+ object_id = models.PositiveIntegerField(verbose_name=_('object_id'),
+ db_index=True)
+ model_name = models.CharField(max_length=100, verbose_name=_('model'),
+ db_index=True)
+ app_name = models.CharField(max_length=100,
+ verbose_name=_('app'),
+ db_index=True)
+
+ class Meta:
+ verbose_name = _('AuditLog')
+ verbose_name_plural = _('AuditLogs')
+ ordering = ('-id',)
+
+ def __str__(self):
+ return "[%s] %s %s.%s %s" % (self.timestamp,
+ self.operation,
+ self.app_name,
+ self.model_name,
+ self.username,
+ )
\ No newline at end of file
diff --git a/sapl/base/receivers.py b/sapl/base/receivers.py
index a33edeee0..0cf8756da 100644
--- a/sapl/base/receivers.py
+++ b/sapl/base/receivers.py
@@ -1,7 +1,13 @@
+import logging
+
+from django.core import serializers
from django.db.models.signals import post_delete
from django.dispatch import receiver
+from django.utils import timezone
-from sapl.base.signals import tramitacao_signal
+from sapl.base.email_utils import do_envia_email_tramitacao
+from sapl.base.models import AuditLog
+from sapl.base.signals import tramitacao_signal, post_delete_signal, post_save_signal
from sapl.materia.models import Tramitacao
from sapl.protocoloadm.models import TramitacaoAdministrativo
from sapl.utils import get_base_url
@@ -39,3 +45,37 @@ def status_tramitacao_materia(sender, instance, **kwargs):
documento = instance.documento
documento.tramitacao = True
documento.save()
+
+
+@receiver(post_delete_signal)
+@receiver(post_save_signal)
+def audit_log(sender, **kwargs):
+ logger = logging.getLogger(__name__)
+
+ instance = kwargs.get('instance')
+ operation = kwargs.get('operation')
+ user = kwargs.get('request').user
+ model_name = instance.__class__.__name__
+ app_name = instance._meta.app_label
+ object_id = instance.id
+ data = serializers.serialize('json', [instance])
+
+ if len(data) > AuditLog.MAX_DATA_LENGTH:
+ data = data[:AuditLog.MAX_DATA_LENGTH]
+
+ if user:
+ username = user.username
+ else:
+ username = ''
+
+ try:
+ AuditLog.objects.create(username=username,
+ operation=operation,
+ model_name=model_name,
+ app_name=app_name,
+ timestamp=timezone.now(),
+ object_id=object_id,
+ object=data)
+ except Exception as e:
+ logger.error('Error saving auditing log object')
+ logger.error(e)
diff --git a/sapl/base/signals.py b/sapl/base/signals.py
index b2cda2028..a2caf67df 100644
--- a/sapl/base/signals.py
+++ b/sapl/base/signals.py
@@ -46,3 +46,6 @@ def cria_models_tipo_autor(app_config=None, verbosity=2, interactive=True,
post_migrate.connect(receiver=cria_models_tipo_autor)
+post_delete_signal = django.dispatch.Signal(providing_args=['instance', 'request'])
+
+post_save_signal = django.dispatch.Signal(providing_args=['instance', 'operation', 'request'])
diff --git a/sapl/base/tests/test_login.py b/sapl/base/tests/test_login.py
index 6c6a75cb8..bbe9f0695 100755
--- a/sapl/base/tests/test_login.py
+++ b/sapl/base/tests/test_login.py
@@ -12,9 +12,13 @@ def user():
def test_login_aparece_na_barra_para_usuario_nao_logado(client):
+ import re
response = client.get('/')
- assert ' ' in str(
- response.content)
+ content = str(response.content)
+ query = ' '
+
+ result = re.findall(query, content)
+ assert len(result) > 0
def test_username_do_usuario_logado_aparece_na_barra(client, user):
diff --git a/sapl/base/views.py b/sapl/base/views.py
index 7113d0052..dba31a20c 100644
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -2053,8 +2053,6 @@ class AppConfigCrud(CrudAux):
reverse('sapl.base:appconfig_update',
kwargs={'pk': app_config.pk}))
- def post(self, request, *args, **kwargs):
- return self.get(request, *args, **kwargs)
class ListView(CrudAux.ListView):
diff --git a/sapl/comissoes/forms.py b/sapl/comissoes/forms.py
index e395fdf90..0c08e17da 100644
--- a/sapl/comissoes/forms.py
+++ b/sapl/comissoes/forms.py
@@ -12,13 +12,16 @@ from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
from sapl.base.models import Autor, TipoAutor
-from sapl.comissoes.models import (Comissao, Composicao, DocumentoAcessorio,
- Participacao, Periodo, Reuniao)
-from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, to_row
+from sapl.comissoes.models import (Comissao, Composicao,
+ DocumentoAcessorio, Participacao,
+ Periodo, Reuniao)
+from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper,
+ to_row)
from sapl.materia.models import MateriaEmTramitacao, PautaReuniao
-from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar
-from sapl.settings import MAX_DOC_UPLOAD_SIZE
-from sapl.utils import FileFieldCheckMixin, FilterOverridesMetaMixin
+from sapl.parlamentares.models import (Legislatura, Mandato,
+ Parlamentar)
+from sapl.utils import (FileFieldCheckMixin, FilterOverridesMetaMixin,
+ validar_arquivo)
class ComposicaoForm(forms.ModelForm):
@@ -405,17 +408,14 @@ class ReuniaoForm(ModelForm):
upload_ata = self.cleaned_data.get('upload_ata', False)
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_pauta and upload_pauta.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Pauta da Reunião deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_pauta.size/1024)/1024))
+ if upload_pauta:
+ validar_arquivo(upload_pauta, "Pauta da Reunião")
- if upload_ata and upload_ata.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Ata da Reunião deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_ata.size/1024)/1024))
+ if upload_ata:
+ validar_arquivo(upload_ata, "Ata da Reunião")
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo da Reunião deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo da Reunião")
return self.cleaned_data
@@ -431,9 +431,10 @@ class PautaReuniaoFilterSet(django_filters.FilterSet):
self.filters['materia__tipo'].label = "Tipo da Matéria"
self.filters['materia__ano'].label = "Ano da Matéria"
+ self.filters['materia__numero'].label = "Número da Matéria"
self.filters['materia__data_apresentacao'].label = "Data (Inicial - Final)"
- row1 = to_row([('materia__numero', 4), ('materia__tipo', 4), ('materia__ano', 4)])
+ row1 = to_row([('materia__tipo', 4), ('materia__ano', 4), ('materia__numero', 4)])
row2 = to_row([('materia__data_apresentacao', 12)])
self.form.helper = SaplFormHelper()
@@ -482,9 +483,8 @@ class DocumentoAcessorioCreateForm(FileFieldCheckMixin, forms.ModelForm):
arquivo = self.cleaned_data.get('arquivo', False)
- if arquivo and arquivo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Integral deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (arquivo.size/1024)/1024))
+ if arquivo:
+ validar_arquivo(arquivo, "Texto Integral")
return self.cleaned_data
@@ -509,8 +509,7 @@ class DocumentoAcessorioEditForm(FileFieldCheckMixin, forms.ModelForm):
arquivo = self.cleaned_data.get('arquivo', False)
- if arquivo and arquivo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Integral deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (arquivo.size/1024)/1024))
+ if arquivo:
+ validar_arquivo(arquivo, "Texto Integral")
return self.cleaned_data
diff --git a/sapl/comissoes/migrations/0022_auto_20191120_1440.py b/sapl/comissoes/migrations/0022_auto_20191120_1440.py
new file mode 100644
index 000000000..a0a527fc3
--- /dev/null
+++ b/sapl/comissoes/migrations/0022_auto_20191120_1440.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-11-20 17:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.comissoes.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('comissoes', '0021_auto_20191001_1115'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='documentoacessorio',
+ name='arquivo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.comissoes.models.anexo_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Integral'),
+ ),
+ migrations.AlterField(
+ model_name='documentoacessorio',
+ name='autor',
+ field=models.CharField(max_length=200, verbose_name='Autor'),
+ ),
+ migrations.AlterField(
+ model_name='reuniao',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.comissoes.models.anexo_upload_path, verbose_name='Anexo da Reunião'),
+ ),
+ migrations.AlterField(
+ model_name='reuniao',
+ name='upload_ata',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.comissoes.models.ata_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Ata da Reunião'),
+ ),
+ migrations.AlterField(
+ model_name='reuniao',
+ name='upload_pauta',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.comissoes.models.pauta_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Pauta da Reunião'),
+ ),
+ ]
diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py
index bf876b5ef..4e7c6e2de 100644
--- a/sapl/comissoes/models.py
+++ b/sapl/comissoes/models.py
@@ -236,21 +236,21 @@ class Reuniao(models.Model):
max_length=150, blank=True,
verbose_name=_('URL do Arquivo de Vídeo (Formatos MP4 / FLV / WebM)'))
upload_pauta = models.FileField(
- max_length=200,
+ max_length=300,
blank=True, null=True,
upload_to=pauta_upload_path,
verbose_name=_('Pauta da Reunião'),
storage=OverwriteStorage(),
validators=[restringe_tipos_de_arquivo_txt])
upload_ata = models.FileField(
- max_length=200,
+ max_length=300,
blank=True, null=True,
upload_to=ata_upload_path,
verbose_name=_('Ata da Reunião'),
storage=OverwriteStorage(),
validators=[restringe_tipos_de_arquivo_txt])
upload_anexo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True, null=True,
upload_to=anexo_upload_path,
storage=OverwriteStorage(),
@@ -317,11 +317,11 @@ class DocumentoAcessorio(models.Model):
data = models.DateField(blank=True, null=True,
default=None, verbose_name=_('Data'))
autor = models.CharField(
- max_length=100, verbose_name=_('Autor'))
+ max_length=200, verbose_name=_('Autor'))
ementa = models.TextField(blank=True, verbose_name=_('Ementa'))
indexacao = models.TextField(blank=True)
arquivo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=anexo_upload_path,
diff --git a/sapl/compilacao/forms.py b/sapl/compilacao/forms.py
index e82d58f63..0a7542a46 100644
--- a/sapl/compilacao/forms.py
+++ b/sapl/compilacao/forms.py
@@ -13,6 +13,7 @@ from django.forms.forms import Form
from django.forms.models import ModelForm
from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
+from model_utils.choices import Choices
from sapl import utils
from sapl.compilacao.models import (NOTAS_PUBLICIDADE_CHOICES,
@@ -115,7 +116,7 @@ class TaForm(ModelForm):
queryset=TipoTextoArticulado.objects.all(),
required=True,
empty_label=None)
- numero = forms.IntegerField(
+ numero = forms.CharField(
label=TextoArticulado._meta.get_field(
'numero').verbose_name,
required=True)
@@ -744,6 +745,12 @@ class DispositivoEdicaoBasicaForm(ModelForm):
class DispositivoSearchModalForm(Form):
+ TIPO_RESULTADO_CHOICES = Choices(
+ ('C', 'coincidentes', _('Apenas Coincidentes')),
+ ('I', 'internos', _('Incluir Internos')),
+ ('S', 'coin_sequentes', _('Coincidentes e seus sequentes')),
+ )
+
tipo_ta = forms.ModelChoiceField(
label=_('Tipo do Texto Articulado'),
queryset=TipoTextoArticulado.objects.all(),
@@ -758,9 +765,9 @@ class DispositivoSearchModalForm(Form):
ano_ta = forms.IntegerField(
label=_('Ano do Documento'), required=False)
- dispositivos_internos = forms.ChoiceField(
- label=_('Dispositivos Internos?'),
- choices=utils.YES_NO_CHOICES,
+ tipo_resultado = forms.ChoiceField(
+ label=_('Tipo do Resultado?'),
+ choices=TIPO_RESULTADO_CHOICES,
widget=forms.RadioSelect(),
required=False)
@@ -769,7 +776,7 @@ class DispositivoSearchModalForm(Form):
choices=[(10, _('Dez Dispositivos')),
(30, _('Trinta Dispositivos')),
(50, _('Cinquenta Dispositivos')),
- (0, _('Tudo que atender aos Critérios da Busca'))],
+ (100, _('Cem Dispositivos'))],
widget=forms.Select(),
required=False)
@@ -789,22 +796,33 @@ class DispositivoSearchModalForm(Form):
to_column(('num_ta', 4)),
to_column(('ano_ta', 4)),
to_column(('max_results', 4))),
+
Row(
- to_column(('tipo_ta', 6)),
- to_column(('tipo_model', 6))),
- Row(to_column((InlineRadios('dispositivos_internos'), 3)),
- to_column(('rotulo_dispositivo', 2)),
- to_column((FieldWithButtons(
- Field(
- 'texto_dispositivo',
- placeholder=_('Digite palavras, letras, '
- 'números ou algo'
- ' que estejam no texto.')),
- StrictButton(
- _('Buscar'),
- css_class='btn-busca btn-primary')), 7))
+ to_column(('tipo_resultado', 3)),
+ to_column(
+ (
+ Div(
+ Row(
+ to_column(('tipo_ta', 6)),
+ to_column(('tipo_model', 6))),
+ Row(
+ to_column(('rotulo_dispositivo', 4)),
+ to_column(
+ (
+ FieldWithButtons(
+ Field(
+ 'texto_dispositivo',
+ placeholder=_('Digite palavras, letras, '
+ 'números ou algo'
+ ' que estejam no texto.')),
+ StrictButton(
+ _('Buscar'),
+ css_class='btn-busca btn-primary')), 8))
+ )
+ ), 9
+ )
)
- )
+ ))
self.helper = SaplFormHelper()
self.helper.layout = Layout(
@@ -821,7 +839,7 @@ class DispositivoSearchModalForm(Form):
choice = ch(kwargs['instance'].ta.tipo_ta_id)
self.base_fields['tipo_model'].choices = choice
- kwargs['initial'].update({'dispositivos_internos': False})
+ kwargs['initial'].update({'tipo_resultado': 'C'})
super(DispositivoSearchModalForm, self).__init__(*args, **kwargs)
diff --git a/sapl/compilacao/migrations/0013_auto_20190924_0830.py b/sapl/compilacao/migrations/0013_auto_20190924_0830.py
new file mode 100644
index 000000000..c984718ef
--- /dev/null
+++ b/sapl/compilacao/migrations/0013_auto_20190924_0830.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.24 on 2019-09-24 11:30
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0012_bug_auto_inserido'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='textoarticulado',
+ name='editable_only_by_owners',
+ field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=True,
+ verbose_name='Editável apenas pelos donos do Texto Articulado?'),
+ ),
+ migrations.AlterField(
+ model_name='textoarticulado',
+ name='editing_locked',
+ field=models.BooleanField(choices=[(
+ True, 'Sim'), (False, 'Não')], default=True, verbose_name='Texto Articulado em Edição?'),
+ ),
+ ]
diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py
index f64285aee..bac67b535 100644
--- a/sapl/compilacao/models.py
+++ b/sapl/compilacao/models.py
@@ -221,12 +221,12 @@ class TextoArticulado(TimestampedMixin):
editable_only_by_owners = models.BooleanField(
choices=YES_NO_CHOICES,
default=True,
- verbose_name=_('Editável apenas pelos donos do Texto Articulado'))
+ verbose_name=_('Editável apenas pelos donos do Texto Articulado?'))
editing_locked = models.BooleanField(
choices=YES_NO_CHOICES,
default=True,
- verbose_name=_('Texto Articulado em Edição'))
+ verbose_name=_('Texto Articulado em Edição?'))
privacidade = models.IntegerField(
_('Privacidade'),
@@ -416,8 +416,8 @@ class TextoArticulado(TimestampedMixin):
def clone_for(self, obj):
# O clone gera um texto válido original dada a base self,
- # mesmo sendo esta base um texto compilado.
- # Os dispositivos a clonar será com base no texto compilado
+ # mesmo sendo esta base um Texto Articulado.
+ # Os dispositivos a clonar será com base no Texto Articulado
assert self.tipo_ta and self.tipo_ta.content_type, _(
'Não é permitido chamar o método clone_for '
@@ -1072,6 +1072,10 @@ class Dispositivo(BaseModel, TimestampedMixin):
'Permissão alteração global do dispositivo de vigência')),
)
+ def ws_sync(self):
+ return self.ta and self.ta.privacidade in (
+ STATUS_TA_IMMUTABLE_PUBLIC, STATUS_TA_PUBLIC)
+
def clean(self):
"""
Check for instances with null values in unique_together fields.
@@ -1113,14 +1117,15 @@ class Dispositivo(BaseModel, TimestampedMixin):
self.contagem_continua = self.tipo_dispositivo.contagem_continua
- try:
+ """try:
if self.texto:
+ self.texto = self.texto.replace('\xa0', '')
self.texto = str(BeautifulSoup(self.texto, "html.parser"))
if self.texto_atualizador:
self.texto_atualizador = str(BeautifulSoup(
self.texto_atualizador, "html.parser"))
except:
- pass
+ pass"""
return super().save(
force_insert=force_insert, force_update=force_update, using=using,
@@ -1624,7 +1629,7 @@ class Dispositivo(BaseModel, TimestampedMixin):
yield ultimo
@staticmethod
- def new_instance_based_on(dispositivo_base, tipo_base):
+ def new_instance_based_on(dispositivo_base, tipo_base, base_alteracao=None):
dp = Dispositivo()
dp.tipo_dispositivo = tipo_base
@@ -1639,6 +1644,16 @@ class Dispositivo(BaseModel, TimestampedMixin):
dp.dispositivo_pai = dispositivo_base.dispositivo_pai
dp.publicacao = dispositivo_base.publicacao
+ b = base_alteracao if base_alteracao else dispositivo_base
+
+ # teste de criação inversa de itens alterados por mesmo bloco
+ dp.ta_publicado = b.ta_publicado
+ dp.dispositivo_atualizador = b.dispositivo_atualizador
+
+ if dp.ta_publicado:
+ dp.ordem_bloco_atualizador = b.ordem_bloco_atualizador + \
+ Dispositivo.INTERVALO_ORDEM
+
dp.dispositivo_vigencia = dispositivo_base.dispositivo_vigencia
if dp.dispositivo_vigencia:
dp.inicio_eficacia = dp.dispositivo_vigencia.inicio_eficacia
diff --git a/sapl/compilacao/templatetags/compilacao_filters.py b/sapl/compilacao/templatetags/compilacao_filters.py
index a7fb2eada..201e0d62c 100644
--- a/sapl/compilacao/templatetags/compilacao_filters.py
+++ b/sapl/compilacao/templatetags/compilacao_filters.py
@@ -65,6 +65,8 @@ def get_bloco_atualizador(pk_atualizador):
@register.simple_tag
def dispositivo_desativado(dispositivo, inicio_vigencia, fim_vigencia):
+ if dispositivo.dispositivo_de_revogacao:
+ return 'revogado'
if inicio_vigencia and fim_vigencia:
if dispositivo.fim_vigencia is None:
return ''
@@ -292,7 +294,6 @@ def nomenclatura_heranca(d, ignore_ultimo=0, ignore_primeiro=0):
return result
-
@register.filter
def list(obj):
return [obj, ]
diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py
index d27d85f1a..9f0ed2b46 100644
--- a/sapl/compilacao/views.py
+++ b/sapl/compilacao/views.py
@@ -10,7 +10,7 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.contenttypes.models import ContentType
-from django.core.exceptions import ValidationError
+from django.core.exceptions import ValidationError, PermissionDenied
from django.core.signing import Signer
from django.core.urlresolvers import reverse, reverse_lazy
from django.db import transaction
@@ -494,6 +494,18 @@ class TaListView(CompMixin, ListView):
~Q(owners=self.request.user.id),
privacidade=STATUS_TA_PRIVATE)
+ if 'check' in self.request.GET:
+ qs = qs.filter(
+ temp_check_migrations=False,
+ privacidade=0,
+ ).exclude(dispositivos_set__tipo_dispositivo_id=3)
+
+ if 'check_dvt' in self.request.GET:
+ qs = qs.filter(
+ ).filter(
+ dispositivos_set__isnull=False,
+ dispositivos_set__dispositivo_vigencia__isnull=True).distinct()
+
return qs
@@ -565,13 +577,29 @@ class TaDeleteView(CompMixin, DeleteView):
template_name = "crud/confirm_delete.html"
permission_required = 'compilacao.delete_textoarticulado'
+ def post(self, request, *args, **kwargs):
+ if not request.user.is_superuser:
+ raise PermissionDenied
+ return DeleteView.post(self, request, *args, **kwargs)
+
@property
def detail_url(self):
return reverse_lazy('sapl.compilacao:ta_detail',
kwargs={'pk': self.kwargs['pk']})
def get_success_url(self):
- return reverse_lazy('sapl.compilacao:ta_list')
+ messages.info(self.request, 'Texto Articulado excluido com sucesso!')
+
+ reverse_url = '%s:%s_detail' % (
+ self.object.content_object._meta.app_config.name,
+ self.object.content_object._meta.model_name)
+
+ return reverse_lazy(reverse_url,
+ kwargs={'pk': self.object.content_object.pk})
+
+ @property
+ def title(self):
+ return 'Texto Articulado: %s' % self.object
class DispositivoSuccessUrlMixin(CompMixin):
@@ -849,6 +877,10 @@ class TextView(CompMixin, ListView):
fim_vigencia = None
ta_vigencia = None
+ @property
+ def title(self):
+ return 'Texto Articulado: %s' % self.object
+
def has_permission(self):
self.object = self.ta
return self.object.has_view_permission(self.request)
@@ -1078,7 +1110,7 @@ class TextEditView(CompMixin, TemplateView):
self.object.content_object.save()
else:
- if 'lock' in request.GET:
+ if 'lock' in request.GET or 'check' in request.GET:
# TODO - implementar logging de ação de usuário
notificacoes = self.get_notificacoes(
@@ -1097,11 +1129,17 @@ class TextEditView(CompMixin, TemplateView):
'sapl.compilacao:ta_text_notificacoes', kwargs={
'ta_id': self.object.id}))
- self.object.editing_locked = True
- self.object.privacidade = STATUS_TA_PUBLIC
- self.object.save()
- messages.success(request, _(
- 'Texto Articulado bloqueado com sucesso.'))
+ if 'lock' in request.GET:
+ self.object.editing_locked = True
+ self.object.privacidade = STATUS_TA_PUBLIC
+ self.object.save()
+ messages.success(request, _(
+ 'Texto Articulado publicado com sucesso.'))
+ else:
+ self.object.temp_check_migrations = True
+ self.object.save()
+ messages.success(request, _(
+ 'Texto Articulado Checado...'))
if self.object.content_object:
self.object.content_object.save()
@@ -2083,6 +2121,10 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
if len(result) > 2:
result.pop()
+ result[0]['itens'] = result[1]['itens'] + result[0]['itens']
+ result[0]['tipo_insert'] = 'Inserção'
+ result[1]['itens'] = []
+
return result
except Exception as e:
@@ -2097,7 +2139,6 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
dvt = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id'])
if dvt.auto_inserido:
dvt = dvt.dispositivo_pai
-
try:
Dispositivo.objects.filter(
ta=dvt.ta, ta_publicado__isnull=True
@@ -2109,7 +2150,7 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
Dispositivo.objects.filter(ta_publicado=dvt.ta
).update(
dispositivo_vigencia=dvt,
- inicio_vigencia=dvt.inicio_eficacia,
+ inicio_vigencia=dvt.inicio_vigencia,
inicio_eficacia=dvt.inicio_eficacia)
dps = Dispositivo.objects.filter(dispositivo_vigencia=dvt)
@@ -2162,6 +2203,10 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
dp_auto_insert = None
base = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id'])
+
+ if base.dispositivo_atualizador:
+ registro_inclusao = True
+
tipo = TipoDispositivo.objects.get(pk=context['tipo_pk'])
pub_last = Publicacao.objects.order_by(
'data', 'hora').filter(ta=base.ta).last()
@@ -2197,11 +2242,13 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
dp_pai = dp
if dp_irmao is not None:
- dp = Dispositivo.new_instance_based_on(dp_irmao, tipo)
+ dp = Dispositivo.new_instance_based_on(
+ dp_irmao, tipo, base_alteracao=base)
dp.transform_in_next(variacao)
else:
# Inserção sem precedente
- dp = Dispositivo.new_instance_based_on(dp_pai, tipo)
+ dp = Dispositivo.new_instance_based_on(
+ dp_pai, tipo, base_alteracao=base)
dp.dispositivo_pai = dp_pai
dp.nivel += 1
@@ -2224,6 +2271,9 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
else:
dp.set_numero_completo([1, 0, 0, 0, 0, 0, ])
+ if dp.dispositivo_atualizador:
+ registro_inclusao = True
+
# verificar se existe restrição de quantidade de itens
if dp.dispositivo_pai:
for perfil in perfil_parents:
@@ -2262,7 +2312,8 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
dp.incrementar_irmaos(variacao, [local_add, ], force=False)
dp.publicacao = pub_last
- dp.save()
+
+ dp.save(clean=not registro_inclusao)
count_auto_insert = 0
if create_auto_inserts:
@@ -2314,6 +2365,10 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin):
ordem += Dispositivo.INTERVALO_ORDEM
dp = Dispositivo.objects.get(pk=dp_pk)
+ dp.ta_publicado = None
+ dp.dispositivo_atualizador = None
+ dp.ordem_bloco_atualizador = 0
+ dp.save(clean=False)
''' Reenquadrar todos os dispositivos que possuem pai
antes da inserção atual e que são inferiores a dp,
@@ -2624,8 +2679,12 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
ds = d
while ds.dispositivo_subsequente:
ds = ds.dispositivo_subsequente
+
dsps_ids.add(ds.pk)
+ if revogacao and ds.dispositivo_de_revogacao:
+ dsps_ids.remove(ds.pk)
+
if em_bloco:
proximo_bloco = Dispositivo.objects.filter(
ordem__gt=ds.ordem,
@@ -2636,9 +2695,18 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
'ta_id': ds.ta_id,
'nivel__gte': ds.nivel,
'ordem__gte': ds.ordem,
- 'dispositivo_subsequente__isnull': True
+ 'dispositivo_subsequente__isnull': True,
}
+ if revogacao:
+ params.update(
+ {
+ 'dispositivo_de_revogacao': False,
+ 'tipo_dispositivo__dispositivo_de_articulacao': False
+ }
+
+ )
+
if proximo_bloco:
params['ordem__lt'] = proximo_bloco.ordem
@@ -2655,9 +2723,9 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
dsps_ids = Dispositivo.objects.filter(
id__in=dsps_ids
- ).values_list('id', flat="True")
- for dsp in dsps_ids:
- with transaction.atomic():
+ ).values_list('id', flat="True").order_by('ordem')
+ with transaction.atomic():
+ for dsp in dsps_ids:
data.update(
self.registra_alteracao(
bloco_alteracao,
@@ -2713,10 +2781,10 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
if ndp.dispositivo_vigencia:
ndp.inicio_eficacia = ndp.dispositivo_vigencia.inicio_eficacia
- ndp.inicio_vigencia = ndp.dispositivo_vigencia.inicio_eficacia
+ ndp.inicio_vigencia = ndp.dispositivo_vigencia.inicio_vigencia
else:
ndp.inicio_eficacia = bloco_alteracao.inicio_eficacia
- ndp.inicio_vigencia = bloco_alteracao.inicio_eficacia
+ ndp.inicio_vigencia = bloco_alteracao.inicio_vigencia
try:
ordem = dsp_a_alterar.criar_espaco(
@@ -2748,6 +2816,7 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
).ordem_bloco_atualizador + Dispositivo.INTERVALO_ORDEM
else:
ndp.ordem_bloco_atualizador = Dispositivo.INTERVALO_ORDEM
+
ndp.save()
p.dispositivo_subsequente = ndp
@@ -2765,10 +2834,10 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin,
filhos_diretos = dsp_a_alterar.dispositivos_filhos_set
for d in filhos_diretos.all():
d.dispositivo_pai = ndp
- d.save()
+ d.save(clean=False)
- ndp.ta.reordenar_dispositivos()
- bloco_alteracao.ordenar_bloco_alteracao()
+ # ndp.ta.reordenar_dispositivos()
+ # bloco_alteracao.ordenar_bloco_alteracao()
if not revogacao:
if 'message' not in data:
@@ -2980,201 +3049,174 @@ class DispositivoSearchFragmentFormView(ListView):
itens.append(item)
return JsonResponse(itens, safe=False)
- response = ListView.get(self, request, *args, **kwargs)
-
- if not self.object_list or \
- not isinstance(self.object_list, list) and \
- not self.object_list.exists():
- messages.info(
- request, _('Não foram encontrados resultados '
- 'com seus critérios de busca!'))
- username = self.request.user.username
- self.logger.error("user=" + username + ". Não foram encontrados "
- "resultados com esses critérios de busca. "
- "id_tipo_ta=".format(request.GET['tipo_ta']))
-
- try:
- r = response.render()
- return response
- except Exception as e:
- messages.error(request, "Erro - %s" % str(e))
- context = {}
- self.template_name = 'compilacao/messages.html'
- username = self.request.user.username
- self.logger.error("user=" + username + ". " + str(e))
- return self.render_to_response(context)
+ return ListView.get(self, request, *args, **kwargs)
def get_queryset(self):
- try:
- n = 10
- if 'max_results' in self.request.GET:
- n = int(self.request.GET['max_results'])
-
- q = Q()
- if 'initial_ref' in self.request.GET:
- initial_ref = self.request.GET['initial_ref']
- if initial_ref:
- q = q & Q(pk=initial_ref)
-
- result = Dispositivo.objects.filter(q).select_related(
- 'ta').exclude(
- tipo_dispositivo__dispositivo_de_alteracao=True)
-
- return result[:n]
-
- str_texto = ''
- texto = ''
- rotulo = ''
- num_ta = ''
- ano_ta = ''
-
- if 'texto' in self.request.GET:
- str_texto = self.request.GET['texto']
+ result = []
+ try:
+ tipo_model = self.request.GET.get('tipo_model', '')
+ limit = int(self.request.GET.get('max_results', 100))
+ tipo_ta = self.request.GET.get('tipo_ta', '')
+ num_ta = self.request.GET.get('num_ta', '')
+ ano_ta = self.request.GET.get('ano_ta', '')
+ rotulo = self.request.GET.get('rotulo', '')
+ str_texto = self.request.GET.get('texto', '')
texto = str_texto.split(' ')
- if 'rotulo' in self.request.GET:
- rotulo = self.request.GET['rotulo']
- if rotulo:
- q = q & Q(rotulo__icontains=rotulo)
-
- for item in texto:
- if not item:
- continue
- if q:
- q = q & (Q(texto__icontains=item) |
- Q(texto_atualizador__icontains=item))
- else:
- q = (Q(texto__icontains=item) |
- Q(texto_atualizador__icontains=item))
-
- if 'tipo_ta' in self.request.GET:
- tipo_ta = self.request.GET['tipo_ta']
- if tipo_ta:
- q = q & Q(ta__tipo_ta_id=tipo_ta)
-
- if 'num_ta' in self.request.GET:
- num_ta = self.request.GET['num_ta']
- if num_ta:
- q = q & Q(ta__numero=num_ta)
-
- if 'ano_ta' in self.request.GET:
- ano_ta = self.request.GET['ano_ta']
- if ano_ta:
- q = q & Q(ta__ano=ano_ta)
-
- if not q.children and not n:
- n = 10
- q = q & Q(nivel__gt=0)
-
- result = Dispositivo.objects.order_by(
- '-ta__data',
- '-ta__ano',
- '-ta__numero',
- 'ta',
- 'ordem').filter(q).select_related('ta')
-
- if 'data_type_selection' in self.request.GET and\
- self.request.GET['data_type_selection'] == 'checkbox':
- result = result.exclude(
- tipo_dispositivo__dispositivo_de_alteracao=True)
- else:
- if 'data_function' in self.request.GET and\
- self.request.GET['data_function'] == 'alterador':
- result = result.exclude(
- tipo_dispositivo__dispositivo_de_alteracao=False,
- )
- result = result.exclude(
- tipo_dispositivo__dispositivo_de_articulacao=False,
- )
- print(str(result.query))
-
- def resultados(r):
- if n:
- return r[:n]
- else:
- return r
+ tipo_resultado = self.request.GET.get('tipo_resultado', '')
+ tipo_resultado = '' if tipo_resultado == 'False' else tipo_resultado
- """if num_ta and ano_ta and not rotulo and not str_texto and\
- 'data_type_selection' in self.request.GET and\
- self.request.GET['data_type_selection'] == 'checkbox':
- return r
- else:
- return r[:n]"""
+ model_class = None
- if 'tipo_model' not in self.request.GET:
- return resultados(result)
+ if tipo_ta:
+ tipo_ta = TipoTextoArticulado.objects.get(pk=tipo_ta)
+
+ if tipo_ta and tipo_model:
+ integrations_view_names = get_integrations_view_names()
+ for item in integrations_view_names:
+ if hasattr(item, 'model_type_foreignkey') and\
+ hasattr(item, 'model'):
+ if (tipo_ta.content_type.model ==
+ item.model.__name__.lower() and
+ tipo_ta.content_type.app_label ==
+ item.model._meta.app_label):
+
+ model_class = item.model
+ model_type_class = item.model_type_foreignkey
+ tipo_model = item.model_type_foreignkey.objects.get(
+ pk=tipo_model)
+ break
- tipo_model = self.request.GET['tipo_model']
- if not tipo_model:
- return resultados(result)
+ column_field = ''
+ if model_class:
+ for field in model_class._meta.fields:
+ if field.related_model == model_type_class:
+ column_field = field.column
+ break
- integrations_view_names = get_integrations_view_names()
+ dts = self.request.GET.get('data_type_selection', '')
+ df = self.request.GET.get('data_function', '')
- tipo_ta = TipoTextoArticulado.objects.get(pk=tipo_ta)
+ AND_CONTROLS = ''
+ if dts == 'checkbox':
+ AND_CONTROLS = 'AND td.dispositivo_de_alteracao = false'
+ else:
+ if df == 'alterador':
+ AND_CONTROLS = '''AND td.dispositivo_de_alteracao = true
+ AND td.dispositivo_de_articulacao = true'''
+
+ texto = list(map("d.texto ~* '{}'".format, texto))
+ AND_TEXTO_ROTULO = ''
+ if str_texto and rotulo:
+ AND_TEXTO_ROTULO = '''AND ( ({BUSCA_TEXTO} AND d.rotulo ~* '{BUSCA_ROTULO}') OR
+ ({BUSCA_TEXTO} AND d.rotulo = '' AND dp.rotulo ~* '{BUSCA_ROTULO}')
+ )'''.format(
+ BUSCA_TEXTO=' AND '.join(texto),
+ BUSCA_ROTULO=rotulo
+ )
+ elif str_texto:
+ AND_TEXTO_ROTULO = ' AND %s' % ' AND '.join(texto)
+ elif rotulo:
+ AND_TEXTO_ROTULO = "AND d.rotulo ~* '{BUSCA_ROTULO}'".format(
+ BUSCA_ROTULO=rotulo)
+ else:
+ AND_TEXTO_ROTULO = ''
+
+ jtms = '' # JOIN_TYPE_MODEL_SELECTED
+ atms = '' # AND_TYPE_MODEL_SELECTED
+ if tipo_model:
+ jtms = 'JOIN {gfk_table} gfkt on (gfkt.id = ta.object_id)'.format(
+ gfk_table=model_class._meta.db_table)
+ atms = 'AND gfkt.{gfk_field_type} = {gfk_field_type_id}'.format(
+ gfk_field_type=column_field,
+ gfk_field_type_id=tipo_model.id,
+ )
- model_class = None
- for item in integrations_view_names:
- if hasattr(item, 'model_type_foreignkey') and\
- hasattr(item, 'model'):
- if (tipo_ta.content_type.model ==
- item.model.__name__.lower() and
- tipo_ta.content_type.app_label ==
- item.model._meta.app_label):
-
- model_class = item.model
- model_type_class = item.model_type_foreignkey
- tipo_model = item.model_type_foreignkey.objects.get(
- pk=tipo_model)
- break
+ sql = '''
+ SELECT d.* FROM compilacao_dispositivo d
+ JOIN compilacao_dispositivo dp on (d.dispositivo_pai_id = dp.id)
+ JOIN compilacao_tipodispositivo td on (d.tipo_dispositivo_id = td.id)
+ JOIN compilacao_textoarticulado ta on (d.ta_id = ta.id)
+
+ {JOIN_TYPE_MODEL_SELECTED}
+
+ where d.nivel > 0
+
+ {AND_TYPE_MODEL_SELECTED}
+
+ {AND_TEXTO_ROTULO}
+ {AND1_NUMERO}
+ {AND2_ANO}
+ {AND3_TIPO_TA}
+ {AND_CONTROLS}
+
+ order by ta.data desc,
+ ta.numero desc,
+ ta.id desc,
+ d.ordem
+ {limit};
+ '''.format(
+
+ limit='limit {}'.format(limit) if limit else '',
+
+ JOIN_TYPE_MODEL_SELECTED=jtms,
+ AND_TYPE_MODEL_SELECTED=atms,
+
+ AND3_TIPO_TA="AND ta.tipo_ta_id = {}".format(
+ tipo_ta.id) if tipo_ta else '',
+
+ AND2_ANO="AND ta.ano = {}".format(
+ ano_ta) if ano_ta else '',
+
+ AND1_NUMERO="AND ta.numero ~* '{}'".format(
+ num_ta) if num_ta else '',
+
+ AND_TEXTO_ROTULO=AND_TEXTO_ROTULO if AND_TEXTO_ROTULO else '',
+ AND_CONTROLS=AND_CONTROLS if AND_CONTROLS else ''
+ )
- if not model_class:
- return resultados(result)
+ result = Dispositivo.objects.raw(sql)
- column_field = ''
- for field in model_class._meta.fields:
- if field.related_model == model_type_class:
- column_field = field.column
- break
+ r = []
+ ids = set()
- if not column_field:
- return resultados(result)
+ def proc_dispositivos(ds):
- r = []
+ for d in ds:
- """
- ao integrar um model ao app de compilação, se este model possuir
+ if d.id not in ids:
+ r.append(d)
+ ids.add(d.id)
- texto_articulado = GenericRelation(
- TextoArticulado, related_query_name='texto_articulado')
+ if tipo_resultado == 'I':
+ if ds != result:
+ d.I = True
+ proc_dispositivos(d.dispositivos_filhos_set.filter(
+ tipo_dispositivo__dispositivo_de_alteracao=False
+ ))
+ elif tipo_resultado == 'S' and ds == result:
- será uma integração mais eficiente para as buscas de Dispositivos
- """
- if hasattr(model_class, 'texto_articulado'):
- q = q & Q(**{
- 'ta__texto_articulado__' + column_field: tipo_model.pk
- })
- if n:
- result = result.filter(q)[:n]
- else:
- result = result.filter(q)
+ seq = Dispositivo.objects.filter(
+ ta=d.ta,
+ ordem__gt=d.ordem,
+ nivel__gt=0,
+ tipo_dispositivo__dispositivo_de_alteracao=False
+ )
+ proc_dispositivos(seq[:limit])
- for d in result:
- if not d.ta.content_object or\
- not hasattr(d.ta.content_object, column_field):
- continue
+ elif tipo_resultado == 'S':
+ d.S = True
- if tipo_model.pk == getattr(d.ta.content_object, column_field):
- r.append(d)
+ proc_dispositivos(result)
- if (len(r) == n and (not num_ta or
- not ano_ta or rotulo or str_texto)):
- break
return r
except Exception as e:
username = self.request.user.username
self.logger.error("user=" + username + ". " + str(e))
+ return []
+ pass
class DispositivoSearchModalView(FormView):
diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py
index b6af79427..2574a4a46 100644
--- a/sapl/crispy_layout_mixin.py
+++ b/sapl/crispy_layout_mixin.py
@@ -55,28 +55,28 @@ def form_actions(more=[Div(css_class='clearfix')],
class SaplFormHelper(FormHelper):
render_hidden_fields = True # default = False
"""
- até a release 1.6.1 do django-crispy-forms, os fields em Meta.Fields eram
+ até a release 1.6.1 do django-crispy-forms, os fields em Meta.Fields eram
renderizados mesmo se não mencionados no helper.
Com esta mudança (https://github.com/django-crispy-forms/django-crispy-forms/commit/6b93e8a362422db8fe54aa731319c7cbc39990ba)
render_hidden_fields foi adicionado uma condição em que a cada
instância do Helper, fosse decidido se os fields não mencionados serião ou
- não renderizados...
+ não renderizados...
O Sapl até este commit: https://github.com/interlegis/sapl/commit/22b87f36ebc8659a6ecaf8831ab0f425206b0993
utilizou o django-crispy-forms na versão 1.6.1, ou seja,
- sem a condição render_hidden_fields o que fazia o FormHelper, na 1.6.1
+ sem a condição render_hidden_fields o que fazia o FormHelper, na 1.6.1
set comportar como se, agora, na 1.7.2 o default fosse True.
- Como todos os Forms do Sapl foram construídos assumindo que fields
+ Como todos os Forms do Sapl foram construídos assumindo que fields
não incluídos explicitamente no Helper, o helper o incluiria implicitamente,
e assim o era, de acordo com commit acima do django-crispy-forms, então
cria-se essa classe:
-
+
class SaplFormHelper(FormHelper):
- render_hidden_fields = True
-
+ render_hidden_fields = True
+
onde torna o default, antes False, agora = True, o esperado pelos forms do sapl,
e substituí-se todos os FormHelper por SaplFormHelper dentro do projeto Sapl
-
-
+
+
esta explicação ficará aqui dentro do código, via commit, e na issue #2456.
"""
@@ -258,7 +258,12 @@ class CrispyLayoutFormMixin:
if func:
verbose_name, text = getattr(self, func)(obj, fieldname)
else:
- verbose_name, text = get_field_display(obj, fieldname)
+ hook_fieldname = 'hook_%s' % fieldname
+ if hasattr(self, hook_fieldname):
+ verbose_name, text = getattr(
+ self, hook_fieldname)(obj)
+ else:
+ verbose_name, text = get_field_display(obj, fieldname)
return {
'id': fieldname,
diff --git a/sapl/crud/base.py b/sapl/crud/base.py
index 18f3d5c29..f4f86a36f 100644
--- a/sapl/crud/base.py
+++ b/sapl/crud/base.py
@@ -16,7 +16,6 @@ from django.http.response import Http404
from django.shortcuts import redirect
from django.utils.decorators import classonlymethod
from django.utils.encoding import force_text
-from django.utils.functional import cached_property
from django.utils.translation import string_concat
from django.utils.translation import ugettext_lazy as _
from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
@@ -24,16 +23,15 @@ from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
from django.views.generic.base import ContextMixin
from django.views.generic.list import MultipleObjectMixin
+from sapl.base.signals import post_delete_signal, post_save_signal
from sapl.crispy_layout_mixin import CrispyLayoutFormMixin, get_field_display
from sapl.crispy_layout_mixin import SaplFormHelper
from sapl.rules.map_rules import (RP_ADD, RP_CHANGE, RP_DELETE, RP_DETAIL,
RP_LIST)
from sapl.utils import normalize
-
logger = logging.getLogger(settings.BASE_DIR.name)
-
ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \
'list', 'create', 'detail', 'update', 'delete'
@@ -82,7 +80,6 @@ def make_pagination(index, num_pages):
head = from_to(1, PAGINATION_LENGTH - len(tail) - 1)
return head + [None] + tail
-
"""
variáveis do crud:
help_topic
@@ -386,12 +383,13 @@ class CrudBaseMixin(CrispyLayoutFormMixin):
class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
- permission_required = (RP_LIST, )
+ permission_required = (RP_LIST,)
logger = logging.getLogger(__name__)
@classmethod
def get_url_regex(cls):
return r'^$'
+
paginate_by = 10
no_entries_msg = _('Nenhum registro encontrado.')
@@ -423,7 +421,13 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
if hasattr(f, 'related_model') and f.related_model:
m = f.related_model
if f:
- s.append(force_text(f.verbose_name))
+ hook = 'hook_header_{}'.format(''.join(fn))
+ if hasattr(self, hook):
+ header = getattr(self, hook)()
+ s.append(header)
+ else:
+ s.append(force_text(f.verbose_name))
+
s = ' / '.join(s)
r.append(s)
return r
@@ -598,7 +602,7 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
model_ordering = (model_ordering,)
for mo in model_ordering:
if mo not in ordering:
- ordering = ordering + (mo, )
+ ordering = ordering + (mo,)
queryset = queryset.order_by(*ordering)
# print(ordering)
@@ -618,9 +622,38 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView):
return queryset
+class AuditLogMixin(object):
+
+ def delete(self, request, *args, **kwargs):
+ # Classe deve implementar um get_object(), i.e., deve ser uma View
+ deleted_object = self.get_object()
+ try:
+ return super(AuditLogMixin, self).delete(request, args, kwargs)
+ finally:
+ post_delete_signal.send(sender=None,
+ instance=deleted_object,
+ operation='D',
+ request=self.request)
+
+ # SAVE/UPDATE method
+ def form_valid(self, form):
+ try:
+ if not form.instance.pk:
+ operation = 'C'
+ else:
+ operation = 'U'
+ return super(AuditLogMixin, self).form_valid(form)
+ finally:
+ post_save_signal.send(sender=None,
+ instance=form.instance,
+ operation=operation,
+ request=self.request
+ )
+
+
class CrudCreateView(PermissionRequiredContainerCrudMixin,
- FormMessagesMixin, CreateView):
- permission_required = (RP_ADD, )
+ FormMessagesMixin, AuditLogMixin, CreateView):
+ permission_required = (RP_ADD,)
logger = logging.getLogger(__name__)
@classmethod
@@ -692,7 +725,7 @@ class CrudCreateView(PermissionRequiredContainerCrudMixin,
class CrudDetailView(PermissionRequiredContainerCrudMixin,
DetailView, MultipleObjectMixin):
- permission_required = (RP_DETAIL, )
+ permission_required = (RP_DETAIL,)
no_entries_msg = _('Nenhum registro Associado.')
paginate_by = 10
logger = logging.getLogger(__name__)
@@ -837,8 +870,8 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin,
class CrudUpdateView(PermissionRequiredContainerCrudMixin,
- FormMessagesMixin, UpdateView):
- permission_required = (RP_CHANGE, )
+ FormMessagesMixin, AuditLogMixin, UpdateView):
+ permission_required = (RP_CHANGE,)
logger = logging.getLogger(__name__)
def form_valid(self, form):
@@ -868,8 +901,8 @@ class CrudUpdateView(PermissionRequiredContainerCrudMixin,
class CrudDeleteView(PermissionRequiredContainerCrudMixin,
- FormMessagesMixin, DeleteView):
- permission_required = (RP_DELETE, )
+ FormMessagesMixin, AuditLogMixin, DeleteView):
+ permission_required = (RP_DELETE,)
logger = logging.getLogger(__name__)
@classmethod
@@ -929,10 +962,12 @@ class Crud:
def _add_base(view):
if view:
+
class CrudViewWithBase(cls.BaseMixin, view):
model = cls.model
help_topic = cls.help_topic
crud = cls
+
CrudViewWithBase.__name__ = view.__name__
return CrudViewWithBase
@@ -966,11 +1001,13 @@ class Crud:
def build(cls, _model, _help_topic, _model_set=None, list_field_names=[]):
def create_class(_list_field_names):
+
class ModelCrud(cls):
model = _model
model_set = _model_set
help_topic = _help_topic
list_field_names = _list_field_names
+
return ModelCrud
ModelCrud = create_class(list_field_names)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index e2222b737..38595afc3 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -4,8 +4,8 @@ import os
import sapl
from crispy_forms.bootstrap import Alert, InlineRadios
-from crispy_forms.layout import (HTML, Button, Field, Fieldset,
- Layout, Row)
+from crispy_forms.layout import (Button, Field, Fieldset, HTML, Layout, Row)
+
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist, ValidationError
@@ -24,11 +24,12 @@ from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from sapl.base.models import AppConfig, Autor, TipoAutor
+from sapl.base.signals import post_save_signal
from sapl.comissoes.models import Comissao, Composicao, Participacao
from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
STATUS_TA_PRIVATE)
-from sapl.crispy_layout_mixin import (SaplFormLayout, form_actions,
- to_column, to_row, SaplFormHelper)
+from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper,
+ SaplFormLayout, to_column, to_row)
from sapl.materia.models import (AssuntoMateria, Autoria, MateriaAssunto,
MateriaLegislativa, Orgao,
RegimeTramitacao, StatusTramitacao,
@@ -46,7 +47,7 @@ from sapl.utils import (ChoiceWithoutValidationField, choice_anos_com_materias,
autor_label, autor_modal, gerar_hash_arquivo, proposicao_modal,
models_with_gr_for_model, qs_override_django_filter,
RangeWidgetOverride, SEPARADOR_HASH_PROPOSICAO,
- YES_NO_CHOICES)
+ validar_arquivo, YES_NO_CHOICES)
from .models import (AcompanhamentoMateria, Anexada, Autoria,
DespachoInicial, DocumentoAcessorio, Numeracao,
@@ -116,7 +117,7 @@ class ReceberProposicaoForm(Form):
row1 = to_row([('cod_hash', 12)])
row2 = to_row(
[(Button('pesquisar-cod-proposicao',
- 'Pesquisar Código de Proposicoes',
+ 'Pesquisar Código de Proposições por Data',
css_class='btn btn-primary btn-sm'), 4)
])
self.helper = SaplFormHelper()
@@ -258,9 +259,8 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm):
texto_original = self.cleaned_data.get('texto_original', False)
- if texto_original and texto_original.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Original deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb"
- .format((MAX_DOC_UPLOAD_SIZE / 1024) / 1024, (texto_original.size / 1024) / 1024))
+ if texto_original:
+ validar_arquivo(texto_original, "Texto Original")
return cleaned_data
@@ -361,9 +361,8 @@ class DocumentoAcessorioForm(FileFieldCheckMixin, ModelForm):
arquivo = self.cleaned_data.get('arquivo', False)
- if arquivo and arquivo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Integral deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb"
- .format((MAX_DOC_UPLOAD_SIZE / 1024) / 1024, (arquivo.size / 1024) / 1024))
+ if arquivo:
+ validar_arquivo(arquivo, "Texto Integral")
return self.cleaned_data
@@ -1938,9 +1937,8 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
def clean_texto_original(self):
texto_original = self.cleaned_data.get('texto_original', False)
- if texto_original and texto_original.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Original deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb"
- .format((MAX_DOC_UPLOAD_SIZE / 1024) / 1024, (texto_original.size / 1024) / 1024))
+ if texto_original:
+ validar_arquivo(texto_original, "Texto Original")
return texto_original
@@ -2469,7 +2467,7 @@ class ConfirmarProposicaoForm(ProposicaoForm):
# dados básicos
doc = DocumentoAcessorio()
doc.materia = proposicao.materia_de_vinculo
- doc.autor = str(proposicao.autor)
+ doc.autor = str(proposicao.autor)[:200]
doc.tipo = proposicao.tipo.tipo_conteudo_related
doc.ementa = proposicao.descricao
diff --git a/sapl/materia/migrations/0059_auto_20191001_1450.py b/sapl/materia/migrations/0058_auto_20191001_1450.py
similarity index 93%
rename from sapl/materia/migrations/0059_auto_20191001_1450.py
rename to sapl/materia/migrations/0058_auto_20191001_1450.py
index deb7565b3..0abbd9870 100644
--- a/sapl/materia/migrations/0059_auto_20191001_1450.py
+++ b/sapl/materia/migrations/0058_auto_20191001_1450.py
@@ -8,7 +8,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('materia', '0058_auto_20191001_1115'),
+ ('materia', '0057_materiaemtramitacao'),
]
operations = [
diff --git a/sapl/materia/migrations/0059_merge_20191003_0854.py b/sapl/materia/migrations/0059_merge_20191003_0854.py
new file mode 100644
index 000000000..53054ed62
--- /dev/null
+++ b/sapl/materia/migrations/0059_merge_20191003_0854.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-03 11:54
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('materia', '0058_auto_20191001_1450'),
+ ('materia', '0058_auto_20191001_1115'),
+ ]
+
+ operations = [
+ ]
\ No newline at end of file
diff --git a/sapl/materia/migrations/0063_auto_20191010_1228.py b/sapl/materia/migrations/0060_auto_20190930_1136.py
similarity index 77%
rename from sapl/materia/migrations/0063_auto_20191010_1228.py
rename to sapl/materia/migrations/0060_auto_20190930_1136.py
index 1c5773c67..560328c2f 100644
--- a/sapl/materia/migrations/0063_auto_20191010_1228.py
+++ b/sapl/materia/migrations/0060_auto_20190930_1136.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.11.20 on 2019-10-10 15:28
+# Generated by Django 1.11.20 on 2019-09-30 14:36
from __future__ import unicode_literals
from django.db import migrations, models
@@ -8,7 +8,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('materia', '0062_remove_tramitacao_turno'),
+ ('materia', '0059_merge_20191003_0854'),
]
operations = [
@@ -17,4 +17,4 @@ class Migration(migrations.Migration):
name='texto',
field=models.TextField(blank=True, verbose_name='Texto da Ação'),
),
- ]
+ ]
\ No newline at end of file
diff --git a/sapl/materia/migrations/0061_auto_20191120_1440.py b/sapl/materia/migrations/0061_auto_20191120_1440.py
new file mode 100644
index 000000000..84b0f8735
--- /dev/null
+++ b/sapl/materia/migrations/0061_auto_20191120_1440.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-11-20 17:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.materia.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('materia', '0060_auto_20190930_1136'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='documentoacessorio',
+ name='arquivo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.materia.models.anexo_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Integral'),
+ ),
+ migrations.AlterField(
+ model_name='documentoacessorio',
+ name='autor',
+ field=models.CharField(blank=True, max_length=200, verbose_name='Autor'),
+ ),
+ migrations.AlterField(
+ model_name='materialegislativa',
+ name='texto_original',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.materia.models.materia_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Original'),
+ ),
+ migrations.AlterField(
+ model_name='proposicao',
+ name='texto_original',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.materia.models.materia_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Original'),
+ ),
+ ]
diff --git a/sapl/materia/migrations/0060_auto_20190905_1134.py b/sapl/materia/migrations/0062_auto_20190905_1134.py
similarity index 95%
rename from sapl/materia/migrations/0060_auto_20190905_1134.py
rename to sapl/materia/migrations/0062_auto_20190905_1134.py
index 678144a8d..1bb36abae 100644
--- a/sapl/materia/migrations/0060_auto_20190905_1134.py
+++ b/sapl/materia/migrations/0062_auto_20190905_1134.py
@@ -9,7 +9,7 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
- ('materia', '0059_auto_20191001_1450'),
+ ('materia', '0061_auto_20191120_1440'),
]
operations = [
diff --git a/sapl/materia/migrations/0061_auto_20190905_1135.py b/sapl/materia/migrations/0063_auto_20190905_1135.py
similarity index 96%
rename from sapl/materia/migrations/0061_auto_20190905_1135.py
rename to sapl/materia/migrations/0063_auto_20190905_1135.py
index ed1c55d09..fa37de0aa 100644
--- a/sapl/materia/migrations/0061_auto_20190905_1135.py
+++ b/sapl/materia/migrations/0063_auto_20190905_1135.py
@@ -37,7 +37,7 @@ def migra_tipos_turnos_tramitacao(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
- ('materia', '0060_auto_20190905_1134'),
+ ('materia', '0062_auto_20190905_1134')
]
operations = [
diff --git a/sapl/materia/migrations/0062_remove_tramitacao_turno.py b/sapl/materia/migrations/0064_remove_tramitacao_turno.py
similarity index 87%
rename from sapl/materia/migrations/0062_remove_tramitacao_turno.py
rename to sapl/materia/migrations/0064_remove_tramitacao_turno.py
index 421a6f5c2..657f87bbe 100644
--- a/sapl/materia/migrations/0062_remove_tramitacao_turno.py
+++ b/sapl/materia/migrations/0064_remove_tramitacao_turno.py
@@ -8,7 +8,7 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
- ('materia', '0061_auto_20190905_1135'),
+ ('materia', '0063_auto_20190905_1135')
]
operations = [
diff --git a/sapl/materia/models.py b/sapl/materia/models.py
index ebb164841..efd2ed86e 100644
--- a/sapl/materia/models.py
+++ b/sapl/materia/models.py
@@ -257,7 +257,7 @@ class MateriaLegislativa(models.Model):
'materia_principal',
'materia_anexada'))
texto_original = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=materia_upload_path,
@@ -535,13 +535,13 @@ class DocumentoAcessorio(models.Model):
data = models.DateField(blank=True, null=True,
default=None, verbose_name=_('Data'))
autor = models.CharField(
- max_length=50, blank=True, verbose_name=_('Autor'))
+ max_length=200, blank=True, verbose_name=_('Autor'))
ementa = models.TextField(blank=True, verbose_name=_('Ementa'))
indexacao = models.TextField(blank=True)
arquivo = models.FileField(
blank=True,
null=True,
- max_length=255,
+ max_length=300,
upload_to=anexo_upload_path,
verbose_name=_('Texto Integral'),
storage=OverwriteStorage(),
@@ -807,7 +807,7 @@ class Proposicao(models.Model):
('I', 'Incorporada')),
verbose_name=_('Status Proposição'))
texto_original = models.FileField(
- max_length=200,
+ max_length=300,
upload_to=materia_upload_path,
blank=True,
null=True,
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index b2d1b6139..0610f39eb 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -33,13 +33,13 @@ from django_filters.views import FilterView
from sapl.base.email_utils import do_envia_email_confirmacao
from sapl.base.models import Autor, CasaLegislativa, AppConfig as BaseAppConfig
-from sapl.base.signals import tramitacao_signal
+from sapl.base.signals import tramitacao_signal, post_delete_signal, post_save_signal
from sapl.comissoes.models import Comissao, Participacao, Composicao
from sapl.compilacao.models import STATUS_TA_IMMUTABLE_RESTRICT, STATUS_TA_PRIVATE
from sapl.compilacao.views import IntegracaoTaView
from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, SaplFormLayout
from sapl.crud.base import (Crud, CrudAux, make_pagination, MasterDetailCrud,
- PermissionRequiredForAppCrudMixin, RP_DETAIL, RP_LIST)
+ PermissionRequiredForAppCrudMixin, RP_DETAIL, RP_LIST,)
from sapl.materia.forms import (AnexadaForm, AutoriaForm, AutoriaMultiCreateForm,
ConfirmarProposicaoForm, DevolverProposicaoForm,
DespachoInicialCreateForm, LegislacaoCitadaForm,
@@ -324,7 +324,7 @@ def recuperar_proposicao(request):
data = request.GET.get('data')
proposicoes = Proposicao.objects.filter(
- data_envio__date=datetime.strptime(data, '%d/%m/%Y').date(),
+ data_envio__date=datetime.strptime(data, '%Y-%m-%d').date(),
data_envio__isnull=False,
data_recebimento__isnull=True,
data_devolucao__isnull=True
@@ -807,7 +807,7 @@ class ProposicaoCrud(Crud):
p = Proposicao.objects.get(id=kwargs['pk'])
msg_error = ''
- if p and p.autor.user == user:
+ if p and p.autor == user.autoruser.autor:
if action == 'send':
if p.data_envio and p.data_recebimento:
msg_error = _('Proposição já foi enviada e recebida.')
@@ -1408,7 +1408,7 @@ class TramitacaoCrud(MasterDetailCrud):
messages.add_message(request, messages.ERROR, msg)
return HttpResponseRedirect(url)
else:
- tramitacoes_deletar = [tramitacao.id]
+ tramitacoes_deletar = [tramitacao]
if materia.tramitacao_set.count() == 0:
materia.em_tramitacao = False
materia.save()
@@ -1419,11 +1419,18 @@ class TramitacaoCrud(MasterDetailCrud):
for ma in mat_anexadas:
tram_anexada = ma.tramitacao_set.last()
if compara_tramitacoes_mat(tram_anexada, tramitacao):
- tramitacoes_deletar.append(tram_anexada.id)
+ tramitacoes_deletar.append(tram_anexada)
if ma.tramitacao_set.count() == 0:
ma.em_tramitacao = False
ma.save()
- Tramitacao.objects.filter(id__in=tramitacoes_deletar).delete()
+ Tramitacao.objects.filter(id__in=[t.id for t in tramitacoes_deletar]).delete()
+
+ # TODO: otimizar para passar a lista de matérias
+ for tramitacao in tramitacoes_deletar:
+ post_delete_signal.send(sender=None,
+ instance=tramitacao,
+ operation='C',
+ request=self.request)
return HttpResponseRedirect(url)
@@ -2678,9 +2685,9 @@ class MateriaPesquisaSimplesView(PermissionRequiredMixin, FormView):
kwargs.update({'tipo': form.cleaned_data['tipo_materia']})
if form.cleaned_data.get('data_inicial'):
- kwargs.update({'data__gte': form.cleaned_data['data_inicial'],
- 'data__lte': form.cleaned_data['data_final']})
-
+ kwargs.update({'data_apresentacao__gte': form.cleaned_data['data_inicial'],
+ 'data_apresentacao__lte': form.cleaned_data['data_final']})
+
materias = MateriaLegislativa.objects.filter(
**kwargs).order_by('-numero', 'ano')
diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py
index 8b45467eb..9bf9ebab7 100644
--- a/sapl/norma/forms.py
+++ b/sapl/norma/forms.py
@@ -1,27 +1,28 @@
-
+import django_filters
import logging
-from sapl.crispy_layout_mixin import SaplFormHelper
from crispy_forms.layout import Fieldset, Layout
+
from django import forms
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import models
from django.db.models import Q
-from django.forms import ModelForm, widgets, ModelChoiceField
+from django.forms import ModelChoiceField, ModelForm, widgets
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
-import django_filters
from sapl.base.models import Autor, TipoAutor
-from sapl.crispy_layout_mixin import form_actions, to_row
+from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, to_row
from sapl.materia.forms import choice_anos_com_materias
-from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
-from sapl.settings import MAX_DOC_UPLOAD_SIZE
-from sapl.utils import NormaPesquisaOrderingFilter, RangeWidgetOverride, \
- choice_anos_com_normas, FilterOverridesMetaMixin, FileFieldCheckMixin, ANO_CHOICES
+from sapl.materia.models import (MateriaLegislativa,
+ TipoMateriaLegislativa)
+from sapl.utils import (ANO_CHOICES, choice_anos_com_normas,
+ FileFieldCheckMixin, FilterOverridesMetaMixin,
+ NormaPesquisaOrderingFilter, RangeWidgetOverride,
+ validar_arquivo)
-from .models import (AnexoNormaJuridica, AssuntoNorma, NormaJuridica, NormaRelacionada,
- TipoNormaJuridica, AutoriaNorma)
+from .models import (AnexoNormaJuridica, AssuntoNorma, AutoriaNorma,
+ NormaJuridica, NormaRelacionada, TipoNormaJuridica)
def get_esferas():
@@ -217,9 +218,8 @@ class NormaJuridicaForm(FileFieldCheckMixin, ModelForm):
texto_integral = self.cleaned_data.get('texto_integral', False)
- if texto_integral and texto_integral.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Integral deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (texto_integral.size/1024)/1024))
+ if texto_integral:
+ validar_arquivo(texto_integral, "Texto Integral")
return texto_integral
@@ -283,6 +283,14 @@ class AutoriaNormaForm(ModelForm):
class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm):
+
+ logger = logging.getLogger(__name__)
+
+ anexo_arquivo = forms.FileField(
+ required=True,
+ label="Arquivo Anexo"
+ )
+
class Meta:
model = AnexoNormaJuridica
fields = ['norma', 'anexo_arquivo', 'assunto_anexo']
@@ -290,8 +298,6 @@ class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm):
'norma': forms.HiddenInput(),
}
- logger = logging.getLogger(__name__)
-
def clean(self):
cleaned_data = super(AnexoNormaJuridicaForm, self).clean()
@@ -300,9 +306,8 @@ class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm):
anexo_arquivo = self.cleaned_data.get('anexo_arquivo', False)
- if anexo_arquivo and anexo_arquivo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O Arquivo Anexo deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (anexo_arquivo.size/1024)/1024))
+ if anexo_arquivo:
+ validar_arquivo(anexo_arquivo, "Arquivo Anexo")
return cleaned_data
diff --git a/sapl/norma/migrations/0028_auto_20191024_1330.py b/sapl/norma/migrations/0028_auto_20191024_1330.py
new file mode 100644
index 000000000..22bd9e895
--- /dev/null
+++ b/sapl/norma/migrations/0028_auto_20191024_1330.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-24 16:30
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.norma.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('norma', '0027_auto_20191001_1115'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='normajuridica',
+ name='texto_integral',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.norma.models.norma_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Integral'),
+ ),
+ ]
diff --git a/sapl/norma/migrations/0029_auto_20191024_1344.py b/sapl/norma/migrations/0029_auto_20191024_1344.py
new file mode 100644
index 000000000..2768e606e
--- /dev/null
+++ b/sapl/norma/migrations/0029_auto_20191024_1344.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-24 16:44
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.norma.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('norma', '0028_auto_20191024_1330'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='anexonormajuridica',
+ name='anexo_arquivo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.norma.models.norma_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Arquivo Anexo'),
+ ),
+ ]
diff --git a/sapl/norma/migrations/0030_merge_20191204_1129.py b/sapl/norma/migrations/0030_merge_20191204_1129.py
new file mode 100644
index 000000000..2327472ff
--- /dev/null
+++ b/sapl/norma/migrations/0030_merge_20191204_1129.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-12-04 14:29
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('norma', '0029_auto_20191024_1344'),
+ ('norma', '0028_merge_20191003_0909'),
+ ]
+
+ operations = [
+ ]
diff --git a/sapl/norma/models.py b/sapl/norma/models.py
index 8de6fe32c..af1ae7d2d 100644
--- a/sapl/norma/models.py
+++ b/sapl/norma/models.py
@@ -79,7 +79,7 @@ class NormaJuridica(models.Model):
)
texto_integral = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=norma_upload_path,
@@ -184,10 +184,14 @@ class NormaJuridica(models.Model):
return anexos
def __str__(self):
- return _('%(tipo)s nº %(numero)s de %(data)s') % {
+ numero_norma = self.numero
+ if numero_norma.isnumeric():
+ numero_norma = '{0:,}'.format(int(self.numero)).replace(',', '.')
+
+ return _('%(tipo)s nº %(numero)s, de %(data)s') % {
'tipo': self.tipo,
- 'numero': self.numero,
- 'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")}
+ 'numero': numero_norma,
+ 'data': defaultfilters.date(self.data, "d \d\e F \d\e Y").lower()}
@property
def epigrafe(self):
@@ -346,8 +350,8 @@ class NormaRelacionada(models.Model):
def __str__(self):
return _('Principal: %(norma_principal)s'
' - Relacionada: %(norma_relacionada)s') % {
- 'norma_principal': self.norma_principal,
- 'norma_relacionada': self.norma_relacionada}
+ 'norma_principal': str(self.norma_principal),
+ 'norma_relacionada': str(self.norma_relacionada)}
@reversion.register()
@@ -364,7 +368,7 @@ class AnexoNormaJuridica(models.Model):
max_length=250
)
anexo_arquivo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=norma_upload_path,
diff --git a/sapl/norma/views.py b/sapl/norma/views.py
index 6f35d3db5..5fd5f0a5e 100644
--- a/sapl/norma/views.py
+++ b/sapl/norma/views.py
@@ -78,7 +78,7 @@ class NormaDestaquesView(ListView):
class NormaPesquisaView(FilterView):
model = NormaJuridica
filterset_class = NormaFilterSet
- paginate_by = 10
+ paginate_by = 50
def get_queryset(self):
qs = super().get_queryset()
@@ -274,7 +274,8 @@ class NormaCrud(Crud):
pk=self.kwargs['pk']
)
- # Feito desta forma para que sejam materializados os assuntos antigos
+ # Feito desta forma para que sejam materializados os assuntos
+ # antigos
assuntos_antigos = set(norma_antiga.assuntos.all())
dict_objeto_antigo = norma_antiga.__dict__
@@ -282,11 +283,11 @@ class NormaCrud(Crud):
dict_objeto_novo = self.object.__dict__
atributos = ['tipo_id', 'numero', 'ano', 'data', 'esfera_federacao',
- 'complemento', 'materia_id', 'numero',
- 'data_publicacao', 'data_vigencia',
- 'veiculo_publicacao', 'pagina_inicio_publicacao',
- 'pagina_fim_publicacao', 'ementa', 'indexacao',
- 'observacao', 'texto_integral']
+ 'complemento', 'materia_id', 'numero',
+ 'data_publicacao', 'data_vigencia',
+ 'veiculo_publicacao', 'pagina_inicio_publicacao',
+ 'pagina_fim_publicacao', 'ementa', 'indexacao',
+ 'observacao', 'texto_integral']
for atributo in atributos:
if dict_objeto_antigo[atributo] != dict_objeto_novo[atributo]:
@@ -294,8 +295,9 @@ class NormaCrud(Crud):
self.object.ip = get_client_ip(self.request)
self.object.save()
break
-
- # Campo Assuntos não veio no __dict__, então é comparado separadamente
+
+ # Campo Assuntos não veio no __dict__, então é comparado
+ # separadamente
assuntos_novos = set(self.object.assuntos.all())
if assuntos_antigos != assuntos_novos:
self.object.user = self.request.user
@@ -391,7 +393,8 @@ class ImpressosView(PermissionRequiredMixin, TemplateView):
def gerar_pdf_impressos(request, context, template_name):
template = loader.get_template(template_name)
html = template.render(context, request)
- pdf = weasyprint.HTML(string=html, base_url=request.build_absolute_uri()).write_pdf()
+ pdf = weasyprint.HTML(
+ string=html, base_url=request.build_absolute_uri()).write_pdf()
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="relatorio_impressos.pdf"'
@@ -418,7 +421,8 @@ class NormaPesquisaSimplesView(PermissionRequiredMixin, FormView):
kwargs.update({'data__gte': form.cleaned_data['data_inicial'],
'data__lte': form.cleaned_data['data_final']})
- normas = NormaJuridica.objects.filter(**kwargs).order_by('-numero', 'ano')
+ normas = NormaJuridica.objects.filter(
+ **kwargs).order_by('-numero', 'ano')
quantidade_normas = normas.count()
normas = normas[:2000] if quantidade_normas > 2000 else normas
diff --git a/sapl/painel/urls.py b/sapl/painel/urls.py
index 3186e16e6..dfb0e30f3 100644
--- a/sapl/painel/urls.py
+++ b/sapl/painel/urls.py
@@ -4,7 +4,8 @@ from .apps import AppConfig
from .views import (cronometro_painel, get_dados_painel, painel_mensagem_view,
painel_parlamentar_view, painel_view, painel_votacao_view,
switch_painel, verifica_painel, votante_view, CronometroPainelCrud,
- PainelConfigCrud,ordena_cronometro, painel_parcial_view)
+ PainelConfigCrud, ordena_cronometro, painel_parcial_view, painel_discurso_view,
+ get_dados_painel_discurso)
app_name = AppConfig.name
@@ -12,6 +13,7 @@ urlpatterns = [
url(r'^painel-principal/(?P\d+)$', painel_view,
name="painel_principal"),
url(r'^painel/(?P\d+)/dados$', get_dados_painel, name='dados_painel'),
+
url(r'^painel/mensagem$', painel_mensagem_view, name="painel_mensagem"),
url(r'^painel/parlamentar$', painel_parlamentar_view,
name='painel_parlamentar'),
@@ -31,4 +33,9 @@ urlpatterns = [
url(r'^painel-parcial/(?P\d+)/(?P\d+)/$', painel_parcial_view,
name="painel_parcial"),
+
+ url(r'^painel-discurso/(?P\d+)/(?P\d+)/$', painel_discurso_view,
+ name="painel_discurso"),
+ url(r'^painel/(?P\d+)/(?P\d+)/dados-discurso$', get_dados_painel_discurso,
+ name='dados_painel_discurso'),
]
diff --git a/sapl/painel/views.py b/sapl/painel/views.py
index 4eed1c1dd..7424ff0f5 100644
--- a/sapl/painel/views.py
+++ b/sapl/painel/views.py
@@ -1,6 +1,7 @@
import html
import json
import logging
+import os
from django.contrib import messages
from django.contrib.auth.decorators import user_passes_test
@@ -21,7 +22,8 @@ from sapl.parlamentares.models import Legislatura, Parlamentar, Votante
from sapl.sessao.models import (ExpedienteMateria, OradorExpediente, OrdemDia,
PresencaOrdemDia, RegistroVotacao,
SessaoPlenaria, SessaoPlenariaPresenca,
- VotoParlamentar, RegistroLeitura)
+ VotoParlamentar, CronometroLista, ListaDiscurso,
+ ParlamentarLista, RegistroLeitura)
from sapl.utils import filiacao_data, get_client_ip, sort_lista_chave
from .forms import CronometroForm, ConfiguracoesPainelForm
@@ -353,12 +355,15 @@ def painel_view(request, pk):
'resultado': True,
'materia': True
}
+ now = timezone.localtime(timezone.now())
+ utc_offset = now.utcoffset().total_seconds() / 60
context = {'head_title': str(_('Painel Plenário')),
'sessao_id': pk,
'cronometros': Cronometro.objects.filter(ativo=True).order_by('ordenacao'),
'painel_config': PainelConfig.objects.first(),
'casa': CasaLegislativa.objects.last(),
- 'exibicao': exibicao
+ 'exibicao': exibicao,
+ 'utc_offset': utc_offset,
}
return render(request, 'painel/index.html', context)
@@ -375,12 +380,15 @@ def painel_parcial_view(request, pk, opcoes):
'resultado': bit_is_set(opcoes, 3),
'materia': bit_is_set(opcoes, 4)
}
+ now = timezone.localtime(timezone.now())
+ utc_offset = now.utcoffset().total_seconds() / 60
context = {'head_title': str(_('Painel Plenário')),
'sessao_id': pk,
'cronometros': Cronometro.objects.filter(ativo=True).order_by('ordenacao'),
'painel_config': PainelConfig.objects.first(),
'casa': CasaLegislativa.objects.last(),
- 'exibicao': exibicao
+ 'exibicao': exibicao,
+ 'utc_offset': utc_offset,
}
return render(request, 'painel/index.html', context)
@@ -727,19 +735,24 @@ def get_dados_painel(request, pk):
expediente__sessao_plenaria=sessao).order_by('data_hora').last()
# Obtém última matéria que foi votada, através do timestamp mais recente
+ ordem_expediente = None
+ ultimo_timestamp = None
if last_ordem_voto:
ordem_expediente = last_ordem_voto.ordem
ultimo_timestamp = last_ordem_voto.data_hora
- if last_expediente_voto and last_expediente_voto.data_hora > ultimo_timestamp:
+ if (last_expediente_voto and ultimo_timestamp and last_expediente_voto.data_hora > ultimo_timestamp) or \
+ (not ultimo_timestamp and last_expediente_voto):
ordem_expediente = last_expediente_voto.expediente
ultimo_timestamp = last_expediente_voto.data_hora
- if last_ordem_leitura and last_ordem_leitura.data_hora > ultimo_timestamp:
+ if (last_ordem_leitura and ultimo_timestamp and last_ordem_leitura.data_hora > ultimo_timestamp) or \
+ (not ultimo_timestamp and last_ordem_leitura):
ordem_expediente = last_ordem_leitura.ordem
ultimo_timestamp = last_ordem_leitura.data_hora
- if last_expediente_leitura and last_expediente_leitura.data_hora > ultimo_timestamp:
+ if (last_expediente_leitura and ultimo_timestamp and last_expediente_leitura.data_hora > ultimo_timestamp) or \
+ (not ultimo_timestamp and last_expediente_leitura):
ordem_expediente = last_expediente_leitura.expediente
ultimo_timestamp = last_expediente_leitura.data_hora
-
+
if ordem_expediente:
return JsonResponse(get_votos(
get_presentes(pk, response, ordem_expediente),
@@ -748,3 +761,71 @@ def get_dados_painel(request, pk):
# Retorna que não há nenhuma matéria já votada ou aberta
return response_nenhuma_materia(get_presentes(pk, response, None))
+
+@user_passes_test(check_permission)
+def painel_discurso_view(request, sessao_pk, lista_pk):
+ cronometros_ids = CronometroLista.objects.filter(tipo_lista_id=lista_pk).values_list('cronometro', flat=True)
+ cronometros = Cronometro.objects.filter(id__in=cronometros_ids)
+ lista = ListaDiscurso.objects.get(tipo_id=lista_pk, sessao_plenaria_id=sessao_pk)
+
+ context = {
+ 'head_title': str(_('Painel de Discurso')),
+ 'sessao_id': sessao_pk,
+ 'lista': lista,
+ 'cronometros': cronometros,
+ 'casa': CasaLegislativa.objects.last(),
+ 'painel_config': PainelConfig.objects.first(),
+ }
+ return render(request, 'painel/painel_discurso.html', context)
+
+
+@user_passes_test(check_permission)
+def get_dados_painel_discurso(request, pk, lista_pk):
+ sessao = SessaoPlenaria.objects.get(id=pk)
+
+ casa = CasaLegislativa.objects.first()
+
+ app_config = ConfiguracoesAplicacao.objects.first()
+
+ brasao = None
+ if casa and app_config and (bool(casa.logotipo)):
+ brasao = casa.logotipo.url \
+ if app_config.mostrar_brasao_painel else None
+
+ CRONOMETRO_STATUS = {
+ 'I': 'start',
+ 'R': 'reset',
+ 'S': 'stop',
+ 'C': 'increment'
+ }
+
+ cronometros = Cronometro.objects.filter(cronometrolista__tipo_lista_id=lista_pk)
+
+ dict_status_cronometros = dict(cronometros.order_by('ordenacao').values_list('id', 'status'))
+
+ for key, value in dict_status_cronometros.items():
+ dict_status_cronometros[key] = CRONOMETRO_STATUS[dict_status_cronometros[key]]
+
+ dict_duracao_cronometros = dict(cronometros.values_list('id', 'duracao_cronometro'))
+
+ for key, value in dict_duracao_cronometros.items():
+ dict_duracao_cronometros[key] = value.seconds
+
+ lista = ListaDiscurso.objects.get(tipo_id=lista_pk, sessao_plenaria_id=pk)
+ orador = lista.orador_atual
+ oradores = ParlamentarLista.objects.filter(lista=lista).order_by('ordenacao').values_list('parlamentar__nome_parlamentar', flat=True)
+
+ response = {
+ 'sessao_plenaria': str(sessao),
+ 'sessao_plenaria_data': sessao.data_inicio.strftime('%d/%m/%Y'),
+ 'sessao_plenaria_hora_inicio': sessao.hora_inicio,
+ 'cronometros': dict_status_cronometros,
+ 'duracao_cronometros': dict_duracao_cronometros,
+ 'sessao_finalizada': sessao.finalizada,
+ 'brasao': brasao,
+ 'orador': orador.nome_parlamentar if orador else '',
+ 'orador_img': orador.fotografia.url if orador and os.path.isfile(orador.fotografia.path) else None,
+ 'oradores': list(oradores)
+ }
+
+ return JsonResponse(response)
diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py
index 2174f9c52..9bd8fc79c 100755
--- a/sapl/parlamentares/forms.py
+++ b/sapl/parlamentares/forms.py
@@ -79,6 +79,8 @@ def validar_datas_legislatura(eleicao, inicio, fim, pk=None):
class MandatoForm(ModelForm):
logger = logging.getLogger(__name__)
+ data_fim_mandato = forms.DateField(label=_('Fim do Mandato'))
+
class Meta:
model = Mandato
fields = ['legislatura', 'coligacao', 'votos_recebidos',
@@ -145,8 +147,12 @@ class MandatoForm(ModelForm):
existe_mandato = Mandato.objects.filter(
parlamentar=data['parlamentar'],
- legislatura=data['legislatura']).exists()
- if existe_mandato and data['titular']:
+ legislatura=data['legislatura'])
+
+ if self.instance.pk:
+ existe_mandato = existe_mandato.exclude(id=self.instance.pk)
+
+ if existe_mandato.exists() and data['titular']:
self.logger.error("Mandato nesta legislatura (parlamentar={}, legislatura={}) já existe."
.format(data['parlamentar'], data['legislatura']))
raise ValidationError(_('Mandato nesta legislatura já existe.'))
diff --git a/sapl/parlamentares/tests/test_parlamentares.py b/sapl/parlamentares/tests/test_parlamentares.py
index c29bebd5f..93b6b0f02 100644
--- a/sapl/parlamentares/tests/test_parlamentares.py
+++ b/sapl/parlamentares/tests/test_parlamentares.py
@@ -121,14 +121,18 @@ def test_mandato_submit(admin_client):
admin_client.post(reverse('sapl.parlamentares:mandato_create',
kwargs={'pk': 14}),
- {'parlamentar': 14, # hidden field
- 'legislatura': 5,
- 'data_inicio_mandato': \
- Legislatura.objects.get(id=5).data_inicio,
- 'data_expedicao_diploma': '2016-03-22',
- 'observacao': 'Observação do mandato',
- 'salvar': 'salvar'},
- follow=True)
+ {
+ 'parlamentar': 14, # hidden field
+ 'legislatura': 5,
+ 'data_inicio_mandato': \
+ Legislatura.objects.get(id=5).data_inicio,
+ 'data_fim_mandato': \
+ Legislatura.objects.get(id=5).data_fim,
+ 'data_expedicao_diploma': '2016-03-22',
+ 'observacao': 'Observação do mandato',
+ 'salvar': 'salvar'
+ },
+ follow=True)
mandato = Mandato.objects.first()
assert str(_('Observação do mandato')) == str(_(mandato.observacao))
@@ -166,13 +170,15 @@ def test_mandato_form_duplicado():
Mandato.objects.create(parlamentar=parlamentar,
legislatura=legislatura,
data_expedicao_diploma='2017-07-25',
- data_inicio_mandato=legislatura.data_inicio,)
+ data_inicio_mandato=legislatura.data_inicio,
+ data_fim_mandato=legislatura.data_fim)
form = MandatoForm(data={
'parlamentar': str(parlamentar.pk),
'legislatura': str(legislatura.pk),
'data_expedicao_diploma': '01/07/2015',
'data_inicio_mandato': legislatura.data_inicio,
+ 'data_fim_mandato': legislatura.data_fim,
'titular':True,
})
diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py
index 8c6986418..dfbd4a224 100644
--- a/sapl/parlamentares/views.py
+++ b/sapl/parlamentares/views.py
@@ -447,6 +447,9 @@ class MandatoCrud(MasterDetailCrud):
return {'parlamentar': Parlamentar.objects.get(
pk=self.kwargs['pk'])}
+ class UpdateView(MasterDetailCrud.UpdateView):
+ form_class = MandatoForm
+
class ComposicaoColigacaoCrud(MasterDetailCrud):
model = ComposicaoColigacao
@@ -534,8 +537,7 @@ class ParlamentarCrud(Crud):
list_field_names = [
'nome_parlamentar',
'filiacao_atual',
- 'ativo',
- 'mandato_titular']
+ 'ativo']
class DetailView(Crud.DetailView):
@@ -611,8 +613,7 @@ class ParlamentarCrud(Crud):
username = self.request.user.username
if legislatura_id >= 0:
return queryset.filter(
- mandato__legislatura_id=legislatura_id).annotate(
- mandato_titular=F('mandato__titular')).distinct()
+ mandato__legislatura_id=legislatura_id).distinct()
else:
try:
self.logger.debug(
@@ -628,8 +629,7 @@ class ParlamentarCrud(Crud):
". Objeto encontrado com sucesso.")
if l is None:
return Legislatura.objects.all()
- return queryset.filter(mandato__legislatura_id=l).annotate(
- mandato_titular=F('mandato__titular'))
+ return queryset.filter(mandato__legislatura_id=l)
def get_headers(self):
return [_('Parlamentar'), _('Partido'),
@@ -644,19 +644,38 @@ class ParlamentarCrud(Crud):
context['legislaturas'] = legislaturas
context['legislatura_id'] = self.take_legislatura_id()
+ # Pega a Legislatura
+ legislatura = Legislatura.objects.get(
+ id=context['legislatura_id'])
+
for row in context['rows']:
# Pega o Parlamentar por meio da pk
parlamentar = Parlamentar.objects.get(
id=(row[0][1].split('/')[-1]))
+ # Conserta a issue do github https://github.com/interlegis/sapl/issues/3028
+ # Inicialmente a titularidade era conseguida através do código
+ # queryset.filter(mandato__legislatura_id=legislatura_id).annotate(
+ # mandato_titular=F('mandato__titular')).distinct()
+ # em get_queryset(), MAS não funciona se o parlamentar tem vários
+ # mandatos na mesma legislatura, sendo ao menos um titular e outro não,
+ # pois isso gera entradas repetidas. Este código corrige essa situação.
+ mandato = Mandato.objects.filter(
+ parlamentar=parlamentar,
+ data_inicio_mandato__gte=legislatura.data_inicio,
+ data_fim_mandato__lte=legislatura.data_fim
+ ).order_by('-data_inicio_mandato').first()
+
+ if mandato:
+ titular = 'Sim' if mandato.titular else 'Não'
+ row.append((titular, None))
+ else:
+ row.append(('-', None))
+
for index, value in enumerate(row):
row[index] += (None if index else parlamentar,)
- # Pega a Legislatura
- legislatura = Legislatura.objects.get(
- id=context['legislatura_id'])
-
# Coloca a filiação atual ao invés da última
# As condições para mostrar a filiação são:
# A data de filiacao deve ser menor que a data de fim
diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py
index cae67d2ab..d76c49e09 100644
--- a/sapl/protocoloadm/forms.py
+++ b/sapl/protocoloadm/forms.py
@@ -1,11 +1,11 @@
-
+import django_filters
import logging
from crispy_forms.bootstrap import InlineRadios, Alert, FormActions
-from sapl.crispy_layout_mixin import SaplFormHelper
-from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout, Div, Submit
+from crispy_forms.layout import (Button, Column, Div, Fieldset, HTML,
+ Layout, Submit)
+
from django import forms
-from sapl.settings import MAX_DOC_UPLOAD_SIZE
from django.core.exceptions import (MultipleObjectsReturned,
ObjectDoesNotExist, ValidationError)
from django.db import models, transaction
@@ -13,24 +13,28 @@ from django.db.models import Max
from django.forms import ModelForm
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
-import django_filters
from sapl.base.models import Autor, TipoAutor, AppConfig
-from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
-from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa,
+from sapl.base.signals import post_save_signal
+from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper,
+ SaplFormLayout, to_row)
+from sapl.materia.models import (MateriaLegislativa,
+ TipoMateriaLegislativa,
UnidadeTramitacao)
from sapl.protocoloadm.models import Protocolo
-from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, AnoNumeroOrderingFilter,
- RangeWidgetOverride, autor_label, autor_modal,
- choice_anos_com_protocolo, choice_force_optional,
+from sapl.utils import (AnoNumeroOrderingFilter, autor_label, autor_modal,
choice_anos_com_documentoadministrativo,
- FilterOverridesMetaMixin, choice_anos_com_materias,
- FileFieldCheckMixin, lista_anexados)
+ choice_anos_com_materias,
+ choice_anos_com_protocolo, choice_force_optional,
+ FileFieldCheckMixin, FilterOverridesMetaMixin,
+ lista_anexados, RangeWidgetOverride, RANGE_ANOS,
+ validar_arquivo, YES_NO_CHOICES)
-from .models import (AcompanhamentoDocumento, DocumentoAcessorioAdministrativo,
- DocumentoAdministrativo,
- Protocolo, TipoDocumentoAdministrativo,
- TramitacaoAdministrativo, Anexado)
+from .models import (Anexado, AcompanhamentoDocumento,
+ DocumentoAcessorioAdministrativo,
+ DocumentoAdministrativo, Protocolo,
+ TipoDocumentoAdministrativo,
+ TramitacaoAdministrativo)
TIPOS_PROTOCOLO = [('0', 'Recebido'), ('1', 'Enviado'),
@@ -664,9 +668,8 @@ class DocumentoAcessorioAdministrativoForm(FileFieldCheckMixin, ModelForm):
arquivo = self.cleaned_data.get('arquivo', False)
- if arquivo and arquivo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (arquivo.size/1024)/1024))
+ if arquivo:
+ validar_arquivo(arquivo, "Arquivo")
return self.cleaned_data
@@ -1157,9 +1160,8 @@ class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm):
texto_integral = self.cleaned_data.get('texto_integral', False)
- if texto_integral and texto_integral.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Texto Integral deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (texto_integral.size/1024)/1024))
+ if texto_integral:
+ validar_arquivo(texto_integral, "Texto Integral")
return self.cleaned_data
@@ -1563,7 +1565,6 @@ class TramitacaoEmLoteAdmForm(ModelForm):
)
)
-
def clean(self):
cleaned_data = super(TramitacaoEmLoteAdmForm, self).clean()
@@ -1655,7 +1656,7 @@ class TramitacaoEmLoteAdmForm(ModelForm):
user=tramitacao.user,
ip=tramitacao.ip
))
- TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao)
+ TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao)
return tramitacao
diff --git a/sapl/protocoloadm/migrations/0026_auto_20191120_1440.py b/sapl/protocoloadm/migrations/0026_auto_20191120_1440.py
new file mode 100644
index 000000000..09d1220e9
--- /dev/null
+++ b/sapl/protocoloadm/migrations/0026_auto_20191120_1440.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-11-20 17:40
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('protocoloadm', '0025_auto_20191001_1115'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='documentoacessorioadministrativo',
+ name='arquivo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.utils.texto_upload_path, verbose_name='Arquivo'),
+ ),
+ migrations.AlterField(
+ model_name='documentoacessorioadministrativo',
+ name='autor',
+ field=models.CharField(blank=True, max_length=200, verbose_name='Autor'),
+ ),
+ migrations.AlterField(
+ model_name='documentoadministrativo',
+ name='texto_integral',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.utils.texto_upload_path, verbose_name='Texto Integral'),
+ ),
+ ]
diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py
index e4fa79a55..9145dfdcc 100644
--- a/sapl/protocoloadm/models.py
+++ b/sapl/protocoloadm/models.py
@@ -164,7 +164,7 @@ class DocumentoAdministrativo(models.Model):
observacao = models.TextField(
blank=True, verbose_name=_('Observação'))
texto_integral = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
storage=OverwriteStorage(),
@@ -232,7 +232,7 @@ class DocumentoAcessorioAdministrativo(models.Model):
verbose_name=_('Tipo'))
nome = models.CharField(max_length=30, verbose_name=_('Nome'))
arquivo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=texto_upload_path,
@@ -240,7 +240,7 @@ class DocumentoAcessorioAdministrativo(models.Model):
verbose_name=_('Arquivo'))
data = models.DateField(blank=True, null=True, verbose_name=_('Data'))
autor = models.CharField(
- max_length=50, blank=True, verbose_name=_('Autor'))
+ max_length=200, blank=True, verbose_name=_('Autor'))
assunto = models.TextField(
blank=True, verbose_name=_('Assunto'))
indexacao = models.TextField(blank=True)
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
index 830f6bf76..947089754 100755
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -26,7 +26,7 @@ from django_filters.views import FilterView
import sapl
from sapl.base.email_utils import do_envia_email_confirmacao
from sapl.base.models import Autor, CasaLegislativa, AppConfig
-from sapl.base.signals import tramitacao_signal
+from sapl.base.signals import tramitacao_signal, post_delete_signal
from sapl.comissoes.models import Comissao
from sapl.crud.base import (Crud, CrudAux, MasterDetailCrud, make_pagination,
RP_LIST, RP_DETAIL)
@@ -37,7 +37,7 @@ from sapl.protocoloadm.models import Protocolo
from sapl.relatorios.views import relatorio_doc_administrativos
from sapl.utils import (create_barcode, get_base_url, get_client_ip,
get_mime_type_from_file_extension, lista_anexados,
- show_results_filter_set, mail_service_configured)
+ show_results_filter_set, mail_service_configured, from_date_to_datetime_utc)
from .forms import (AcompanhamentoDocumentoForm, AnularProtocoloAdmForm,
DocumentoAcessorioAdministrativoForm,
@@ -564,12 +564,24 @@ class ProtocoloDocumentoView(PermissionRequiredMixin,
legislatura = Legislatura.objects.filter(
data_inicio__year__lte=timezone.now().year,
data_fim__year__gte=timezone.now().year).first()
+
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
+
+ data_inicio_utc = from_date_to_datetime_utc(data_inicio)
+ data_fim_utc = from_date_to_datetime_utc(data_fim)
+
numero = Protocolo.objects.filter(
- data__gte=data_inicio,
- data__lte=data_fim).aggregate(
- Max('numero'))
+ Q(data__isnull=False,
+ data__gte=data_inicio,
+ data__lte=data_fim) |
+ Q(timestamp__isnull=False,
+ timestamp__gte=data_inicio_utc,
+ timestamp__lte=data_fim_utc) |
+ Q(timestamp_data_hora_manual__isnull=False,
+ timestamp_data_hora_manual__gte=data_inicio_utc,
+ timestamp_data_hora_manual__lte=data_fim_utc,)).\
+ aggregate(Max('numero'))
elif numeracao == 'U':
numero = Protocolo.objects.all().aggregate(Max('numero'))
@@ -760,10 +772,22 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView):
data_fim__year__gte=timezone.now().year).first()
data_inicio = legislatura.data_inicio
data_fim = legislatura.data_fim
+
+ data_inicio_utc = from_date_to_datetime_utc(data_inicio)
+ data_fim_utc = from_date_to_datetime_utc(data_fim)
+
numero = Protocolo.objects.filter(
- data__gte=data_inicio,
- data__lte=data_fim).aggregate(
- Max('numero'))
+ Q(data__isnull=False,
+ data__gte=data_inicio,
+ data__lte=data_fim) |
+ Q(timestamp__isnull=False,
+ timestamp__gte=data_inicio_utc,
+ timestamp__lte=data_fim_utc) |
+ Q(timestamp_data_hora_manual__isnull=False,
+ timestamp_data_hora_manual__gte=data_inicio_utc,
+ timestamp_data_hora_manual__lte=data_fim_utc,)).\
+ aggregate(Max('numero'))
+
elif numeracao == 'U':
numero = Protocolo.objects.all().aggregate(Max('numero'))
@@ -1268,7 +1292,7 @@ class TramitacaoAdmCrud(MasterDetailCrud):
messages.add_message(request, messages.ERROR, msg)
return HttpResponseRedirect(url)
else:
- tramitacoes_deletar = [tramitacao.id]
+ tramitacoes_deletar = [tramitacao]
if documento.tramitacaoadministrativo_set.count() == 0:
documento.tramitacao = False
documento.save()
@@ -1278,12 +1302,19 @@ class TramitacaoAdmCrud(MasterDetailCrud):
for da in docs_anexados:
tram_anexada = da.tramitacaoadministrativo_set.last()
if compara_tramitacoes_doc(tram_anexada, tramitacao):
- tramitacoes_deletar.append(tram_anexada.id)
+ tramitacoes_deletar.append(tram_anexada)
if da.tramitacaoadministrativo_set.count() == 0:
da.tramitacao = False
da.save()
TramitacaoAdministrativo.objects.filter(
- id__in=tramitacoes_deletar).delete()
+ id__in=[t.id for t in tramitacoes_deletar]).delete()
+
+ # TODO: otimizar para passar a lista de matérias
+ for tramitacao in tramitacoes_deletar:
+ post_delete_signal.send(sender=None,
+ instance=tramitacao,
+ operation='C',
+ request=self.request)
return HttpResponseRedirect(url)
diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py
index 4e33d546f..f9a592594 100644
--- a/sapl/rules/map_rules.py
+++ b/sapl/rules/map_rules.py
@@ -188,6 +188,10 @@ rules_group_sessao = {
(sessao.JustificativaAusencia, __base__, __perms_publicas__),
(sessao.RetiradaPauta, __base__, __perms_publicas__),
(sessao.RegistroLeitura, __base__, __perms_publicas__),
+ (sessao.ListaDiscurso, __base__, __perms_publicas__),
+ (sessao.TipoListaDiscurso, __base__, __perms_publicas__),
+ (sessao.CronometroLista, __base__, __perms_publicas__),
+ (sessao.ParlamentarLista, __base__, __perms_publicas__),
]
}
@@ -236,6 +240,7 @@ rules_group_geral = {
(base.TipoAutor, __base__, __perms_publicas__),
(base.Autor, __base__, __perms_publicas__),
(base.AutorUser, __base__, __perms_publicas__),
+ (base.AuditLog, __base__, set()),
(protocoloadm.StatusTramitacaoAdministrativo, __base__, set()),
(protocoloadm.TipoDocumentoAdministrativo, __base__, set()),
diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py
index 3c80acfdc..967cf8729 100644
--- a/sapl/sessao/forms.py
+++ b/sapl/sessao/forms.py
@@ -1,35 +1,44 @@
+import django_filters
+
+from crispy_forms.layout import Button, Fieldset, HTML, Layout
from datetime import datetime
-from crispy_forms.layout import HTML, Button, Fieldset, Layout
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import transaction
from django.db.models import Q
-from django.forms import ModelForm
+from django.forms import ModelForm, widgets
from django.forms.widgets import CheckboxSelectMultiple
from django.utils.translation import ugettext_lazy as _
-import django_filters
-from sapl.settings import MAX_DOC_UPLOAD_SIZE
from sapl.base.models import Autor, TipoAutor
-from sapl.crispy_layout_mixin import SaplFormHelper
-from sapl.crispy_layout_mixin import form_actions, to_row, SaplFormLayout
+from sapl.crispy_layout_mixin import (form_actions, to_row,
+ SaplFormHelper, SaplFormLayout)
from sapl.materia.forms import MateriaLegislativaFilterSet
from sapl.materia.models import (MateriaLegislativa, StatusTramitacao,
TipoMateriaLegislativa)
+from sapl.painel.models import Cronometro
from sapl.parlamentares.models import Parlamentar, Mandato
from sapl.utils import (RANGE_DIAS_MES, RANGE_MESES,
MateriaPesquisaOrderingFilter, autor_label,
autor_modal, timezone, choice_anos_com_sessaoplenaria,
FileFieldCheckMixin, verifica_afastamento_parlamentar)
-
-from .models import (ExpedienteMateria, JustificativaAusencia,
- Orador, OradorExpediente, OrdemDia, PresencaOrdemDia, SessaoPlenaria,
- SessaoPlenariaPresenca, TipoResultadoVotacao,
- OcorrenciaSessao, RetiradaPauta, TipoRetiradaPauta, OradorOrdemDia, ORDENACAO_RESUMO,
- ResumoOrdenacao, RegistroLeitura)
-
+from sapl.parlamentares.models import Mandato, Parlamentar
+from sapl.utils import (autor_label, autor_modal,
+ choice_anos_com_sessaoplenaria,
+ FileFieldCheckMixin,
+ MateriaPesquisaOrderingFilter,
+ RANGE_DIAS_MES, RANGE_MESES,
+ timezone, validar_arquivo)
+from .models import (ExpedienteMateria,
+ JustificativaAusencia, OcorrenciaSessao, Orador,
+ OradorExpediente, OradorOrdemDia, OrdemDia,
+ ORDENACAO_RESUMO, PresencaOrdemDia,
+ RegistroLeitura, ResumoOrdenacao, RetiradaPauta,
+ SessaoPlenaria, SessaoPlenariaPresenca,
+ TipoResultadoVotacao, TipoRetiradaPauta,
+ CronometroLista)
MES_CHOICES = RANGE_MESES
DIA_CHOICES = RANGE_DIAS_MES
@@ -155,18 +164,14 @@ class SessaoPlenariaForm(FileFieldCheckMixin, ModelForm):
upload_ata = self.cleaned_data.get('upload_ata', False)
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_pauta and upload_pauta.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Pauta da Sessão deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_pauta.size/1024)/1024))
-
- if upload_ata and upload_ata.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Ata da Sessão deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_ata.size/1024)/1024))
-
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo da Sessão deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_pauta:
+ validar_arquivo(upload_pauta, "Pauta da Sessão")
+ if upload_ata:
+ validar_arquivo(upload_ata, "Ata da Sessão")
+
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo da Sessão")
return self.cleaned_data
@@ -526,7 +531,7 @@ class AdicionarVariasMateriasFilterSet(MateriaLegislativaFilterSet):
o = MateriaPesquisaOrderingFilter()
tramitacao__status = django_filters.ModelChoiceFilter(
- required=True,
+ required=False,
queryset=StatusTramitacao.objects.all(),
label=_('Status da Matéria'))
@@ -547,7 +552,11 @@ class AdicionarVariasMateriasFilterSet(MateriaLegislativaFilterSet):
]
def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ # Colocar super().__init__(*args, **kwargs) quebra a tela
+ # de adicionar várias matérias em expediente e ordem dia.
+ # pois herda da classe AdicionarVariasMateriasFilterSet em
+ # vez de MateriaLegislativaFilterSet
+ super(MateriaLegislativaFilterSet, self).__init__(*args, **kwargs)
self.filters['tipo'].label = 'Tipo de Matéria'
self.filters['autoria__autor__tipo'].label = 'Tipo de Autor'
@@ -632,9 +641,8 @@ class OradorForm(ModelForm):
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo do Orador deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo do Orador")
return self.cleaned_data
@@ -677,9 +685,8 @@ class OradorExpedienteForm(ModelForm):
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo do Orador deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo do Orador")
return self.cleaned_data
@@ -720,9 +727,8 @@ class OradorOrdemDiaForm(ModelForm):
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo do Orador deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo do Orador")
return self.cleaned_data
@@ -824,9 +830,8 @@ class JustificativaAusenciaForm(ModelForm):
upload_anexo = self.cleaned_data.get('upload_anexo', False)
- if upload_anexo and upload_anexo.size > MAX_DOC_UPLOAD_SIZE:
- raise ValidationError("O arquivo Anexo de Justificativa deve ser menor que {0:.1f} mb, o tamanho atual desse arquivo é {1:.1f} mb" \
- .format((MAX_DOC_UPLOAD_SIZE/1024)/1024, (upload_anexo.size/1024)/1024))
+ if upload_anexo:
+ validar_arquivo(upload_anexo, "Anexo de Justificativa")
if not sessao_plenaria.finalizada or sessao_plenaria.finalizada is None:
raise ValidationError(
@@ -889,4 +894,53 @@ class OrdemExpedienteLeituraForm(forms.ModelForm):
row1,
form_actions(more=actions),
)
- )
\ No newline at end of file
+ )
+
+
+class CronometroListaForm(ModelForm):
+
+ cronometro = forms.ModelChoiceField(
+ queryset=Cronometro.objects.all(),
+ label="Cronômetro"
+ )
+
+ nome_lista = forms.CharField(
+ label='Lista de Discussão',
+ widget=widgets.TextInput(attrs={'readonly': 'readonly'})
+ )
+
+ class Meta:
+ model = CronometroLista
+ exclude = []
+ widgets = {
+ 'tipo_lista': forms.HiddenInput(),
+ }
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ row1 = to_row(
+ [('nome_lista', 6),('cronometro', 6),])
+ row2 = to_row(
+ [('tipo_lista', 6)]
+ )
+
+ actions = [HTML('Cancelar ')]
+
+ self.helper = SaplFormHelper()
+ self.helper.layout = Layout(
+ Fieldset(_('Vincular Cronômetro à Lista de Discussão'),
+ row1, row2,
+ HTML(" "),
+ form_actions(more=actions)
+ )
+ )
+
+ def save(self):
+ cd = self.cleaned_data
+ cronometro = cd['cronometro']
+ tipo_lista = cd['tipo_lista']
+ cronometro_lista = CronometroLista.objects.create(cronometro=cronometro, tipo_lista=tipo_lista)
+
+ return cronometro_lista
diff --git a/sapl/sessao/migrations/0048_auto_20190829_1253.py b/sapl/sessao/migrations/0047_auto_20190829_1253.py
similarity index 89%
rename from sapl/sessao/migrations/0048_auto_20190829_1253.py
rename to sapl/sessao/migrations/0047_auto_20190829_1253.py
index a65cc7b6b..ae484f420 100644
--- a/sapl/sessao/migrations/0048_auto_20190829_1253.py
+++ b/sapl/sessao/migrations/0047_auto_20190829_1253.py
@@ -8,7 +8,8 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('sessao', '0047_merge_20191009_1535'),
+ ('sessao', '0046_auto_20190827_1228'),
+ ('sessao', '0046_auto_20191001_1115'),
]
operations = [
@@ -27,4 +28,4 @@ class Migration(migrations.Migration):
name='data_hora',
field=models.DateTimeField(auto_now=True, null=True, verbose_name='Data/Hora'),
),
- ]
+ ]
\ No newline at end of file
diff --git a/sapl/sessao/migrations/0047_merge_20191009_1535.py b/sapl/sessao/migrations/0047_merge_20191009_1535.py
index 8ecdd8999..303f92600 100644
--- a/sapl/sessao/migrations/0047_merge_20191009_1535.py
+++ b/sapl/sessao/migrations/0047_merge_20191009_1535.py
@@ -2,7 +2,7 @@
# Generated by Django 1.11.20 on 2019-10-09 18:35
from __future__ import unicode_literals
-from django.db import migrations
+from django.db import migrations, models
class Migration(migrations.Migration):
diff --git a/sapl/sessao/migrations/0048_auto_20191029_1418.py b/sapl/sessao/migrations/0048_auto_20191029_1418.py
new file mode 100644
index 000000000..3f7458932
--- /dev/null
+++ b/sapl/sessao/migrations/0048_auto_20191029_1418.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-29 17:18
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.sessao.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sessao', '0047_auto_20190829_1253')
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='sessaoplenaria',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.anexo_upload_path, verbose_name='Anexo da Sessão'),
+ ),
+ migrations.AlterField(
+ model_name='sessaoplenaria',
+ name='upload_ata',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.ata_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Ata da Sessão'),
+ ),
+ migrations.AlterField(
+ model_name='sessaoplenaria',
+ name='upload_pauta',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.pauta_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Pauta da Sessão'),
+ ),
+ ]
diff --git a/sapl/sessao/migrations/0049_auto_20191029_1434.py b/sapl/sessao/migrations/0049_auto_20191029_1434.py
new file mode 100644
index 000000000..ebd5fb3e8
--- /dev/null
+++ b/sapl/sessao/migrations/0049_auto_20191029_1434.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-29 17:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.sessao.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sessao', '0048_auto_20191029_1418'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='orador',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.anexo_upload_path, verbose_name='Anexo do Orador'),
+ ),
+ migrations.AlterField(
+ model_name='oradorexpediente',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.anexo_upload_path, verbose_name='Anexo do Orador'),
+ ),
+ migrations.AlterField(
+ model_name='oradorordemdia',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.anexo_upload_path, verbose_name='Anexo do Orador'),
+ ),
+ ]
diff --git a/sapl/sessao/migrations/0050_auto_20191029_1441.py b/sapl/sessao/migrations/0050_auto_20191029_1441.py
new file mode 100644
index 000000000..6fd2ee4d6
--- /dev/null
+++ b/sapl/sessao/migrations/0050_auto_20191029_1441.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-29 17:41
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import sapl.sessao.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sessao', '0049_auto_20191029_1434'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='justificativaausencia',
+ name='upload_anexo',
+ field=models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.sessao.models.anexo_upload_path, verbose_name='Anexo de Justificativa'),
+ ),
+ ]
diff --git a/sapl/sessao/migrations/0051_merge_20191209_0910.py b/sapl/sessao/migrations/0051_merge_20191209_0910.py
new file mode 100644
index 000000000..395507e33
--- /dev/null
+++ b/sapl/sessao/migrations/0051_merge_20191209_0910.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-10-09 18:35
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sessao', '0047_merge_20191009_1535'),
+ ('sessao', '0050_auto_20191029_1441')
+ ]
\ No newline at end of file
diff --git a/sapl/sessao/migrations/0052_auto_20191209_0828.py b/sapl/sessao/migrations/0052_auto_20191209_0828.py
new file mode 100644
index 000000000..90cd6e933
--- /dev/null
+++ b/sapl/sessao/migrations/0052_auto_20191209_0828.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-12-09 11:28
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('parlamentares', '0035_merge_20190802_0954'),
+ ('painel', '0011_cronometro_last_stop_duration'),
+ ('sessao', '0051_merge_20191209_0910'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='CronometroLista',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cronometro', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='painel.Cronometro')),
+ ],
+ options={
+ 'verbose_name': 'Tipo de Lista de Discurso - Cronômetro',
+ 'verbose_name_plural': 'Tipo de Listas de Discurso - Cronômetros',
+ 'ordering': ['tipo_lista', 'cronometro'],
+ },
+ ),
+ migrations.CreateModel(
+ name='ListaDiscurso',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('orador_atual', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar')),
+ ('sessao_plenaria', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.SessaoPlenaria', verbose_name='Sessão Plenária')),
+ ],
+ options={
+ 'verbose_name': 'Lista de Discurso',
+ 'verbose_name_plural': 'Listas de Discurso',
+ 'ordering': ['tipo', 'sessao_plenaria'],
+ },
+ ),
+ migrations.CreateModel(
+ name='ParlamentarLista',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('ordenacao', models.PositiveIntegerField(blank=True, null=True, verbose_name='Ordenação')),
+ ('lista', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.ListaDiscurso')),
+ ('parlamentar', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar')),
+ ],
+ options={
+ 'verbose_name': 'Lista de Discurso - Parlamentar',
+ 'verbose_name_plural': 'Listas de Discurso - Parlamentares',
+ 'ordering': ['lista', 'parlamentar', 'ordenacao'],
+ },
+ ),
+ migrations.CreateModel(
+ name='TipoListaDiscurso',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('nome', models.CharField(max_length=100, verbose_name='Tipo')),
+ ],
+ options={
+ 'verbose_name': 'Tipo de Lista de Discurso',
+ 'verbose_name_plural': 'Tipos de Lista de Discurso',
+ 'ordering': ['nome'],
+ },
+ ),
+ migrations.AddField(
+ model_name='listadiscurso',
+ name='tipo',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.TipoListaDiscurso', verbose_name='Tipo de Lista de Discurso'),
+ ),
+ migrations.AddField(
+ model_name='cronometrolista',
+ name='tipo_lista',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.TipoListaDiscurso'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='parlamentarlista',
+ unique_together=set([('lista', 'parlamentar')]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='listadiscurso',
+ unique_together=set([('tipo', 'sessao_plenaria')]),
+ ),
+ migrations.AlterUniqueTogether(
+ name='cronometrolista',
+ unique_together=set([('tipo_lista', 'cronometro')]),
+ ),
+ ]
diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py
index eaed724fe..b4c88c9aa 100644
--- a/sapl/sessao/models.py
+++ b/sapl/sessao/models.py
@@ -10,6 +10,7 @@ import reversion
from sapl.base.models import Autor
from sapl.materia.models import MateriaLegislativa
+from sapl.painel.models import Cronometro
from sapl.parlamentares.models import (CargoMesa, Legislatura, Parlamentar,
Partido, SessaoLegislativa)
from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation,
@@ -127,7 +128,7 @@ class SessaoPlenaria(models.Model):
max_length=150, blank=True,
verbose_name=_('URL Arquivo Vídeo (Formatos MP4 / FLV / WebM)'))
upload_pauta = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=pauta_upload_path,
@@ -135,7 +136,7 @@ class SessaoPlenaria(models.Model):
storage=OverwriteStorage(),
validators=[restringe_tipos_de_arquivo_txt])
upload_ata = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
upload_to=ata_upload_path,
@@ -143,7 +144,7 @@ class SessaoPlenaria(models.Model):
verbose_name=_('Ata da Sessão'),
validators=[restringe_tipos_de_arquivo_txt])
upload_anexo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
storage=OverwriteStorage(),
@@ -381,7 +382,7 @@ class AbstractOrador(models.Model): # Oradores
observacao = models.CharField(
max_length=150, blank=True, verbose_name=_('Observação'))
upload_anexo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
storage=OverwriteStorage(),
@@ -733,7 +734,7 @@ class JustificativaAusencia(models.Model):
OrdemDia, blank=True, verbose_name=_('Matérias do Ordem do Dia'))
upload_anexo = models.FileField(
- max_length=200,
+ max_length=300,
blank=True,
null=True,
storage=OverwriteStorage(),
@@ -873,4 +874,70 @@ class RegistroLeitura(models.Model):
raise ValidationError(
'RegistroLeitura deve ter exatamente um dos campos '
'ordem ou expediente preenchido. Ambos estão preenchidos: '
- '{}, {}'. format(self.ordem, self.expediente))
\ No newline at end of file
+ '{}, {}'. format(self.ordem, self.expediente))
+class TipoListaDiscurso(models.Model):
+ nome = models.CharField(max_length=100, verbose_name=_('Tipo'))
+
+ class Meta:
+ verbose_name = _('Tipo de Lista de Discurso')
+ verbose_name_plural = _('Tipos de Lista de Discurso')
+ ordering = ['nome']
+
+ def __str__(self):
+ return self.nome
+
+
+@reversion.register()
+class ListaDiscurso(models.Model):
+ tipo = models.ForeignKey(TipoListaDiscurso,
+ on_delete=models.PROTECT,
+ verbose_name=_('Tipo de Lista de Discurso'))
+ sessao_plenaria = models.ForeignKey(SessaoPlenaria,
+ on_delete=models.PROTECT,
+ verbose_name=_('Sessão Plenária'))
+ orador_atual = models.ForeignKey(Parlamentar,
+ on_delete=models.PROTECT,
+ blank=True,
+ null=True)
+
+ class Meta:
+ verbose_name = _('Lista de Discurso')
+ verbose_name_plural = _('Listas de Discurso')
+ ordering = ['tipo', 'sessao_plenaria']
+ unique_together = (('tipo', 'sessao_plenaria'),)
+
+ def __str__(self):
+ return str(self.tipo) + ' - ' + str(self.sessao_plenaria)
+
+@reversion.register()
+class CronometroLista(models.Model):
+ cronometro = models.ForeignKey(Cronometro, on_delete=models.PROTECT)
+ tipo_lista = models.ForeignKey(TipoListaDiscurso, on_delete=models.PROTECT)
+
+ class Meta:
+ verbose_name = _('Tipo de Lista de Discurso - Cronômetro')
+ verbose_name_plural = _('Tipo de Listas de Discurso - Cronômetros')
+ ordering = ['tipo_lista', 'cronometro']
+ unique_together = (('tipo_lista', 'cronometro'),)
+
+ def __str__(self):
+ return str(self.tipo_lista) + ' - ' + str(self.cronometro)
+
+@reversion.register()
+class ParlamentarLista(models.Model):
+ parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT)
+ lista = models.ForeignKey(ListaDiscurso, on_delete=models.PROTECT)
+ ordenacao = models.PositiveIntegerField(
+ blank=True,
+ null=True,
+ verbose_name=_("Ordenação")
+ )
+
+ class Meta:
+ verbose_name = _('Lista de Discurso - Parlamentar')
+ verbose_name_plural = _('Listas de Discurso - Parlamentares')
+ ordering = ['lista', 'parlamentar', 'ordenacao']
+ unique_together = (('lista', 'parlamentar'),)
+
+ def __str__(self):
+ return str(self.lista) + ' - ' + str(self.parlamentar)
diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py
index 0480c4416..d2415d405 100644
--- a/sapl/sessao/urls.py
+++ b/sapl/sessao/urls.py
@@ -38,7 +38,13 @@ from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
voto_nominal_parlamentar,
ExpedienteLeituraView,
OrdemDiaLeituraView,
- retirar_leitura)
+ retirar_leitura,
+ ListaDiscursoView,
+ TipoListaDiscursoCrud,
+ CronometroListaFormView,
+ salva_listadiscurso_parlamentares,
+ salva_orador_listadiscurso,
+ get_orador_listadiscurso)
from .apps import AppConfig
@@ -102,6 +108,10 @@ urlpatterns = [
include(TipoJustificativaCrud.get_urls())),
url(r'^sistema/sessao-plenaria/tipo-retirada-pauta/',
include(TipoRetiradaPautaCrud.get_urls())),
+ url(r'^sistema/sessao-plenaria/tipo-lista-discurso/',
+ include(TipoListaDiscursoCrud.get_urls())),
+
+
url(r'^sistema/resumo-ordenacao/',
resumo_ordenacao,
name='resumo_ordenacao'),
@@ -202,4 +212,20 @@ urlpatterns = [
url(r'^sessao/(?P\d+)/(?P\d+)/(?P\d+)/retirar-leitura$',
retirar_leitura, name='retirar_leitura'),
+
+ # Lista de Discurso
+ url(r'^sessao/(?P\d+)/lista-discurso/',
+ ListaDiscursoView.as_view(),
+ name='lista_discurso'),
+
+ url(r'^sistema/sessao-plenaria/lista-discurso/(?P\d+)/cronometro/create',
+ CronometroListaFormView.as_view(), name='cronometrolista_form'),
+
+ url(r'^sistema/salva-listadiscurso-parlamentares/$',
+ salva_listadiscurso_parlamentares, name='salva_listadiscurso_parlamentares'),
+ url(r'^sistema/salva-orador-listadiscurso/$',
+ salva_orador_listadiscurso, name='salva_orador_listadiscurso'),
+
+ url(r'^sistema/get-orador-lista/(?P\d+)/(?P\d+)/$',
+ get_orador_listadiscurso, name='get_orador_listadiscurso'),
]
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index a07d56a26..0d1dced60 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -48,14 +48,15 @@ from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm,
PresencaForm, SessaoPlenariaFilterSet,
SessaoPlenariaForm, VotacaoEditForm, VotacaoForm,
VotacaoNominalForm, RetiradaPautaForm, OradorOrdemDiaForm,
- OrdemExpedienteLeituraForm)
+ OrdemExpedienteLeituraForm,
+ CronometroListaForm)
from .models import (CargoMesa, ExpedienteMateria, ExpedienteSessao, OcorrenciaSessao, IntegranteMesa,
MateriaLegislativa, Orador, OradorExpediente, OrdemDia,
PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao,
SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente,
TipoResultadoVotacao, TipoSessaoPlenaria, VotoParlamentar, TipoRetiradaPauta,
- RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia,
- ORDENACAO_RESUMO, RegistroLeitura)
+ RetiradaPauta, TipoJustificativa, JustificativaAusencia, OradorOrdemDia, ORDENACAO_RESUMO,
+ RegistroLeitura, TipoListaDiscurso, ListaDiscurso, CronometroLista, ParlamentarLista)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
@@ -65,6 +66,19 @@ TipoResultadoVotacaoCrud = CrudAux.build(
TipoRetiradaPautaCrud = CrudAux.build(TipoRetiradaPauta, 'tipo_retirada_pauta')
+class TipoListaDiscursoCrud(CrudAux):
+ model = TipoListaDiscurso
+
+ class DetailView(CrudAux.DetailView):
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ tipo_lista = context['object']
+ cronometros_lista = CronometroLista.objects.filter(tipo_lista=tipo_lista)
+ context['cronometros_lista'] = cronometros_lista
+ return context
+
+
def reordernar_materias_expediente(request, pk):
expedientes = ExpedienteMateria.objects.filter(
sessao_plenaria_id=pk
@@ -386,7 +400,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
resultado = obj.registrovotacao_set.filter(
materia_id=obj.materia_id).last()
resultado_descricao = obj.resultado
- resultado_observacao = obj.observacao
+ resultado_observacao = resultado.observacao
if has_permission:
url = ''
@@ -502,18 +516,16 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
def get_presencas_generic(model, sessao, legislatura):
- presencas = model.objects.filter(
- sessao_plenaria=sessao)
-
- presentes = [p.parlamentar for p in presencas]
+ presentes = [p.parlamentar for p in model.objects.filter(sessao_plenaria=sessao)]
- presentes = sorted(
- presentes, key=lambda x: remover_acentos(x.nome_parlamentar))
-
- mandato = Mandato.objects.filter(
- legislatura=legislatura).order_by('parlamentar__nome_parlamentar')
-
- for m in mandato:
+ parlamentares_mandato = Mandato.objects.filter(
+ legislatura=legislatura,
+ data_inicio_mandato__lte=sessao.data_inicio,
+ data_fim_mandato__gte=sessao.data_inicio
+ ).distinct().order_by(
+ 'parlamentar__nome_parlamentar')
+
+ for m in parlamentares_mandato:
parlamentar = m.parlamentar
p_afastado = verifica_afastamento_parlamentar(parlamentar, sessao.data_inicio, sessao.data_fim)
if parlamentar in presentes:
@@ -788,6 +800,7 @@ class OradorExpedienteCrud(OradorCrud):
class ListView(MasterDetailCrud.ListView):
+ ordering = ['numero_ordem']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@@ -1620,11 +1633,11 @@ def get_presenca_sessao(sessao_plenaria):
parlamentares_sessao = [p.parlamentar for p in SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
- ).order_by('parlamentar__nome_parlamentar')]
+ ).order_by('parlamentar__nome_parlamentar').distinct()]
ausentes_sessao = JustificativaAusencia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
- ).order_by('parlamentar__nome_parlamentar')
+ ).distinct().order_by('parlamentar__nome_parlamentar')
return ({'presenca_sessao': parlamentares_sessao,
'justificativa_ausencia': ausentes_sessao})
@@ -1718,7 +1731,7 @@ def get_oradores_expediente(sessao_plenaria):
def get_presenca_ordem_do_dia(sessao_plenaria):
parlamentares_ordem = [p.parlamentar for p in PresencaOrdemDia.objects.filter(
sessao_plenaria_id=sessao_plenaria.id
- ).order_by('parlamentar__nome_parlamentar')]
+ ).distinct().order_by('parlamentar__nome_parlamentar')]
return {'presenca_ordem': parlamentares_ordem}
@@ -4513,3 +4526,92 @@ def retirar_leitura(request, pk, iso, oid):
ordem_expediente.save()
return HttpResponseRedirect(succ_url)
+class ListaDiscursoView(TemplateView):
+ template_name = 'sessao/lista_discurso.html'
+
+ def get(self, request, *args, **kwargs):
+ return TemplateView.get(self, request, *args, **kwargs)
+
+
+ def get_context_data(self, **kwargs):
+ context = TemplateView.get_context_data(self, **kwargs)
+ sessao_pk = kwargs['pk']
+ sessao = SessaoPlenaria.objects.get(id=sessao_pk)
+
+ context.update({
+ 'root_pk': sessao_pk,
+ 'subnav_template_name': 'sessao/subnav.yaml',
+ 'sessaoplenaria': sessao,
+ })
+ return context
+
+
+class CronometroListaFormView(FormView):
+ form_class = CronometroListaForm
+ template_name = 'sessao/cronometrolista_form.html'
+
+ def get_initial(self):
+ initial = super().get_initial()
+ tipo_lista_pk = self.kwargs['pk']
+ tipo_lista = TipoListaDiscurso.objects.get(id=tipo_lista_pk)
+ initial['tipo_lista'] = tipo_lista
+ initial['nome_lista'] = tipo_lista.nome
+ return initial
+
+ def form_valid(self, form):
+ form.save()
+ return super().form_valid(form)
+
+ @property
+ def cancel_url(self):
+ return reverse('sapl.sessao:tipolistadiscurso_detail',
+ kwargs={'pk': self.kwargs['pk']})
+
+ def get_success_url(self):
+ return reverse('sapl.sessao:tipolistadiscurso_detail',
+ kwargs={'pk': self.kwargs['pk']})
+
+
+def salva_listadiscurso_parlamentares(request):
+ parlamentares_selecionados_ids = request.GET.getlist('parlamentares_selecionados[]')
+ tipo_lista_id = request.GET.get('lista_selecionada')
+ sessao_id = request.GET.get('sessao_pk')
+
+ if parlamentares_selecionados_ids:
+ lista = ListaDiscurso.objects.get_or_create(tipo_id=tipo_lista_id, sessao_plenaria_id=sessao_id)[0]
+ ParlamentarLista.objects.filter(lista=lista).delete()
+ parlamentares_lista = []
+ for i,parlamentar_id in enumerate(parlamentares_selecionados_ids):
+ parlamentares_lista.append(ParlamentarLista(lista=lista, parlamentar_id=parlamentar_id, ordenacao=i+1))
+ ParlamentarLista.objects.bulk_create(parlamentares_lista)
+ else:
+ ParlamentarLista.objects.filter(lista__tipo_id=tipo_lista_id, lista__sessao_plenaria_id=sessao_id).delete()
+ ListaDiscurso.objects.filter(tipo_id=tipo_lista_id, sessao_plenaria_id=sessao_id).delete()
+ return JsonResponse({})
+
+
+def salva_orador_listadiscurso(request):
+ tipo_id=request.GET.get('tipo_lista_pk')
+ sessao_id=request.GET.get('sessao_pk')
+ lista = ListaDiscurso.objects.get(tipo_id=tipo_id, sessao_plenaria_id=sessao_id)
+ orador_pk = request.GET.get('orador_pk')
+ if orador_pk != '-1':
+ lista.orador_atual = Parlamentar.objects.get(id=orador_pk)
+ else:
+ lista.orador_atual = None
+ lista.save()
+ return JsonResponse({})
+
+def get_orador_listadiscurso(request, spk, tpk):
+ # Não foi utilizado .get para não quebrar caso não exista registro
+ lista = ListaDiscurso.objects.filter(tipo_id=tpk, sessao_plenaria_id=spk).first()
+ parlamentares = []
+ orador_pk = -1
+ orador_nome = ''
+ if lista:
+ if lista.orador_atual:
+ orador_pk = lista.orador_atual.pk
+ orador_nome = lista.orador_atual.nome_parlamentar
+ parlamentares = ParlamentarLista.objects.filter(lista=lista).order_by('ordenacao').values_list('parlamentar__id', 'parlamentar__nome_parlamentar')
+ return JsonResponse({'orador': (orador_pk, orador_nome),
+ 'parlamentares': list(parlamentares)})
diff --git a/sapl/settings.py b/sapl/settings.py
index e33e5c03a..78ff35d4f 100644
--- a/sapl/settings.py
+++ b/sapl/settings.py
@@ -263,9 +263,9 @@ DEFAULT_FROM_EMAIL = config('DEFAULT_FROM_EMAIL', cast=str, default='')
SERVER_EMAIL = config('SERVER_EMAIL', cast=str, default='')
EMAIL_RUNNING = None
-MAX_DOC_UPLOAD_SIZE = 80 * 1024 * 1024 # 80MB
+MAX_DOC_UPLOAD_SIZE = 150 * 1024 * 1024 # 150MB
MAX_IMAGE_UPLOAD_SIZE = 2 * 1024 * 1024 # 2MB
-DATA_UPLOAD_MAX_MEMORY_SIZE= 10 * 1024 * 1024 # 10MB
+DATA_UPLOAD_MAX_MEMORY_SIZE= 10 * 1024 * 1024 # 10MB
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
diff --git a/sapl/static/sapl/frontend/css/chunk-vendors.f0333cff.css b/sapl/static/sapl/frontend/css/chunk-vendors.c41142f2.css
similarity index 100%
rename from sapl/static/sapl/frontend/css/chunk-vendors.f0333cff.css
rename to sapl/static/sapl/frontend/css/chunk-vendors.c41142f2.css
diff --git a/sapl/static/sapl/frontend/css/chunk-vendors.f0333cff.css.gz b/sapl/static/sapl/frontend/css/chunk-vendors.c41142f2.css.gz
similarity index 100%
rename from sapl/static/sapl/frontend/css/chunk-vendors.f0333cff.css.gz
rename to sapl/static/sapl/frontend/css/chunk-vendors.c41142f2.css.gz
diff --git a/sapl/static/sapl/frontend/css/compilacao.3d691cd9.css b/sapl/static/sapl/frontend/css/compilacao.3d691cd9.css
deleted file mode 100644
index 8544d6cbf..000000000
--- a/sapl/static/sapl/frontend/css/compilacao.3d691cd9.css
+++ /dev/null
@@ -1 +0,0 @@
-a:link:after,a:visited:after{content:""}.test_import:nth-child(2n){background-color:#ccc}#wait_message{display:block;position:fixed;top:0;bottom:0;left:0;right:0;background-color:hsla(0,0%,86.3%,.75);z-index:99}#wait_message #msg{position:relative;margin:20% auto;padding:1.2em 2em;max-width:600px;text-align:center;font-size:1.5em;color:#677;border:1px solid #eee;background-color:#fff!important;-webkit-box-shadow:0 1px 2px #999;box-shadow:0 1px 2px #999}.text-center{text-align:center}.cp-notify{z-index:9999;position:fixed;top:2em;left:50%;min-width:600px;-webkit-transform:translate(-50%);transform:translate(-50%);opacity:.97}.cp-notify,.cp-notify.hide{-webkit-transition:all .4s ease;transition:all .4s ease}.cp-notify.hide{opacity:0;top:-1000px;display:block!important}.cp-notify .message{padding:1em;border:2px solid rgba(0,0,0,.1);border-radius:4px;color:rgba(0,0,0,.6);line-height:1em;font-size:1.3em;text-align:center;-webkit-box-shadow:0 0 100px rgba(0,0,0,.2);box-shadow:0 0 100px rgba(0,0,0,.2)}.cp .vigencia-active{margin-top:30px;display:block}.cp .cp-linha-vigencias{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;list-style:none;margin:4rem 0 3rem;padding:0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.cp .cp-linha-vigencias ul{list-style:none;margin:0;padding:0}.cp .cp-linha-vigencias>li{display:-webkit-box;display:-ms-flexbox;display:flex;position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;line-height:0;background:#000;height:2px;text-align:center;max-width:4rem}.cp .cp-linha-vigencias>li .circle{display:block;width:10px;line-height:0;background:#000;height:10px;margin:-5px auto 0;border-radius:50%}.cp .cp-linha-vigencias>li>a{position:absolute;white-space:nowrap;line-height:1.8rem;text-align:center}.cp .cp-linha-vigencias>li:nth-child(2n)>a{top:100%}.cp .cp-linha-vigencias>li:nth-child(odd)>a{bottom:100%}.cp .cp-linha-vigencias>li ul{z-index:1;position:absolute;display:none;background:#fff;margin:30px 0;border:1px solid #aaa;-webkit-box-shadow:0 0 10px #aaa;box-shadow:0 0 10px #aaa;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.cp .cp-linha-vigencias>li ul:before{content:" ";width:2px;height:30px;position:absolute;display:block;background-color:#aaa;bottom:100%;left:50%;margin-left:-1px}.cp .cp-linha-vigencias>li ul li{text-align:left}.cp .cp-linha-vigencias>li ul a{display:block;white-space:nowrap;line-height:2rem;padding:0 10px;font-size:1rem}.cp .cp-linha-vigencias>li ul a:hover{background:#eee}.cp .cp-linha-vigencias>li.active .circle{display:block;width:20px;line-height:0;background:#aaa;height:20px;margin:-10px auto 0}.cp .cp-linha-vigencias>li.active:not(:last-child)>a{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);margin-bottom:15px}.cp .cp-linha-vigencias>li.active>a{margin-bottom:5px}.cp .cp-linha-vigencias>li.active:nth-child(2n)>a{bottom:100%;top:auto}.cp .cp-linha-vigencias>li.active ul{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cp .cp-linha-vigencias>li.active ul li{text-align:left;width:100%}.cp .cp-vigencias .nav-link{padding:.5rem}.cp .cp-vigencias .dropdown-toggle:after{zoom:.8;margin:0}.cp .cp-vigencias .dropdown-menu{margin-left:.5rem}.cp .cp-vigencias .dropdown-item{padding:0}.cp .cp-vigencias .dropdown-item a{line-height:1;padding:.7rem}.cp .desativado .dpt-link,.cp .desativado .dpt-link *,.cp .desativado .dtxt,.cp .desativado .dtxt *,.cp .dpt .dptt>a.desativado .dpt-link,.cp .dpt .dptt>a.desativado .dpt-link *,.cp .dpt .dptt>a.desativado .dtxt,.cp .dpt .dptt>a.desativado .dtxt *{text-decoration:line-through;color:#999!important}.cp .desativado .dpt-link * table,.cp .desativado .dpt-link * table td,.cp .desativado .dpt-link table,.cp .desativado .dpt-link table td,.cp .desativado .dtxt * table,.cp .desativado .dtxt * table td,.cp .desativado .dtxt table,.cp .desativado .dtxt table td,.cp .dpt .dptt>a.desativado .dpt-link * table,.cp .dpt .dptt>a.desativado .dpt-link * table td,.cp .dpt .dptt>a.desativado .dpt-link table,.cp .dpt .dptt>a.desativado .dpt-link table td,.cp .dpt .dptt>a.desativado .dtxt * table,.cp .dpt .dptt>a.desativado .dtxt * table td,.cp .dpt .dptt>a.desativado .dtxt table,.cp .dpt .dptt>a.desativado .dtxt table td{border:1px dotted #ccc}.cp a{text-decoration:none;cursor:pointer}.cp .diff .desativado,.cp .diff .desativado *,.cp .diff .dpt .dptt>a.desativado,.cp .diff .dpt .dptt>a.desativado *,.cp .dpt .diff .dptt>a.desativado,.cp .dpt .diff .dptt>a.desativado *{text-decoration:line-through;color:#ddd!important;font-size:90%}.cp .diff .added{color:#04de2c}.cp .dpt{font-size:1em;position:relative}.cp .dpt.indent{padding-left:1em}.cp .dpt .ementa{padding:2em 0 2em 35%;font-weight:700}.cp .dpt .anexo,.cp .dpt .capitulo,.cp .dpt .disp_finais,.cp .dpt .disp_gerais,.cp .dpt .disp_preliminares,.cp .dpt .disp_transitorias,.cp .dpt .itemsecao,.cp .dpt .livro,.cp .dpt .parte,.cp .dpt .secao,.cp .dpt .subsecao,.cp .dpt .titulo,.cp .dpt .titulo_generico{text-align:center;margin-bottom:1em;font-size:1.15em;margin-top:3em}.cp .dpt .titulo{margin-top:2em}.cp .dpt .capitulo{margin-top:1.5em;font-size:1.15em}.cp .dpt .secao{margin-top:1.2em;margin-bottom:.7em;font-weight:700;font-size:1.15em}.cp .dpt .itemsecao,.cp .dpt .subsecao{margin-top:1em;margin-bottom:.6em;font-weight:700;font-size:1.15em}.cp .dpt .artigo{font-size:1.15em;float:left}.cp .dpt .artigo .dptt{position:relative}.cp .dpt .caput{margin-top:.3333em;font-size:1.15em}.cp .dpt .paragrafo{font-size:1.1em;margin-top:.2222em}.cp .dpt .inciso{font-size:1.1em;margin-top:.1667em}.cp .dpt .alinea,.cp .dpt .item{font-size:1em;margin-top:2px}.cp .dpt .assinatura,.cp .dpt .fecho_lei{margin-top:.6em;font-size:1.15em}.cp .dpt .page-break{page-break-before:always}.cp .dpt .bloco_alteracao{padding-left:10%;font-style:italic;color:#018}.cp .dpt .bloco_alteracao a{text-decoration:underline}.cp .dpt .bloco_alteracao a,.cp .dpt .bloco_alteracao table,.cp .dpt .bloco_alteracao table td{color:#018!important}.cp .dpt .card-header{font-size:1.7rem}.cp .dpt .dn{font-weight:400;position:relative;font-size:70%}.cp .dpt .dn p,.cp .dpt .dn ul{font-weight:400;margin:0 0 0 0;list-style:none;padding:0}.cp .dpt .dn .dnl{display:block;text-align:left!important}.cp .dpt .dn .dnl *{display:inline}.cp .dpt .dn .dnl .bullet{padding:0 .333em;display:inline-block}.cp .dpt .dn .dnl .dnli{min-height:2.5em}.cp .dpt .dn .dnl .dnli:hover ul{font-size:1rem;clip:auto;opacity:1;background:hsla(0,0%,90.2%,.9)}.cp .dpt .dn .dnl .dnli:hover ul,.cp .dpt .dn .dnl .dnli ul{-webkit-transition:opacity .5s linear,clip 0s .3s;transition:opacity .5s linear,clip 0s .3s}.cp .dpt .dn .dnl .dnli ul{clip:rect(0,0,0,0);opacity:0;position:absolute;background:transparent;right:0;padding:.2em .5em 0 .5em;border:1px solid #c7e3d3;border-top:0;font-size:1.5rem}.cp .dpt .dn .dnl .dnli ul li{display:table-cell;color:#aaa}.cp .dpt .dn .dnl .dnli ul li:hover{color:#787}.cp .dpt .dn .dnl .dnli ul li .nowner,.cp .dpt .dn .dnl .dnli ul li:hover a{color:#27ae60!important}.cp .dpt .dn .dnl .dnli .ntitulo{font-weight:700;color:#03a203;text-decoration:none}.cp .dpt .dn .dnl .dnli .ntitulo a{color:#294!important}.cp .dpt .dn .dnl .dnli .ntexto{color:#06d806}.cp .dpt .dn .dnl .dnli .ntexto a{color:#03a203!important}.cp .dpt .dn .dnl:hover,.cp .dpt .dn .dnl:hover *{display:block}.cp .dpt .dn .dnl:hover>.bullet{display:none}.cp .dpt .dn .dnl:hover .dnli{margin-top:.5em;border-top:1px solid #c7e3d3}.cp .dpt .dptt{clear:left}.cp .dpt .dptt>a{color:#000}.cp .dpt .dptt>a.nota-alteracao{color:#02baf2;font-size:.75em}.cp .dpt .dptt>a.nota-alteracao:hover{text-decoration:underline}.cp .dpt .dptt .dne{position:absolute;display:block;right:0;left:0;top:0;height:0;-webkit-transform:scaleX(0);transform:scaleX(0);-webkit-transform-origin:right;transform-origin:right;-webkit-transition:all .3s ease;transition:all .3s ease;border-top:1px solid #2980b9}.cp .dpt .dptt .dne ul.btns-action{list-style:none;padding:0;position:absolute;right:0;background-color:#2980b9}.cp .dpt .dptt .dne ul.btns-action li{float:left}.cp .dpt .dptt .dne ul.btns-action li:hover{background-color:rgba(0,0,0,.1)}.cp .dpt .dptt .dne ul.btns-action li a{color:#fff;padding:.15em 1em 0;display:inline-block}.cp .dpt .dptt .dne-nota{position:relative;-webkit-transform:scaleX(1);transform:scaleX(1);height:auto;border-top:0}.cp .dpt .dptt .dne-nota ul.btns-action{display:none}.cp .dpt .dptt .dne-nota .dne-form{margin:1em -2em 0;text-align:left;font-size:1rem}.cp .dpt .dptt:hover .dne{height:.1667rem;-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transition-delay:1s;transition-delay:1s}.cp .dpt .dptt:hover .dne-nota{height:auto;-webkit-transition-delay:0s;transition-delay:0s}.cp .tipo-vigencias{margin-bottom:-6px;opacity:.8}.cp .tipo-vigencias div a{color:#fff}.cp .tipo-vigencias:hover,.cp:hover{opacity:1}.cp-print .cp-linha-vigencias{display:none!important}.cp.cpe .desativado,.cp.cpe .dpt .dptt>a.desativado{text-decoration:line-through;color:#999!important}.cp.cpe .desativado table,.cp.cpe .desativado table td,.cp.cpe .dpt .dptt>a.desativado table,.cp.cpe .dpt .dptt>a.desativado table td{border:1px dotted #ccc}.cp.cpe a.nota-alteracao{color:#02baf2!important;font-size:.8rem}.cp.cpe .btn-sm{line-height:1rem}.cp.cpe .btn-outline-primary{background-color:#fff}.cp.cpe .btn-outline-primary:hover{background-color:#02baf2}.cp.cpe .dpt{display:block}.cp.cpe .dpt>.dpt-actions-fixed{position:absolute;right:-1em;top:-.8em;z-index:3;opacity:0}.cp.cpe .dpt>.dpt-actions-fixed .activate{display:none}.cp.cpe .dpt>.dpt-actions-fixed .deactivate{display:inline}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary{color:#333}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary:hover{color:#fff;background-color:#02baf2}.cp.cpe .dpt>.dpt-actions,.cp.cpe .dpt>.dpt-actions-bottom{display:none}.cp.cpe .dpt>.dpt-text{cursor:text;min-height:30px;border:1px solid transparent}.cp.cpe .dpt>.dpt-text.hover-fixed,.cp.cpe .dpt>.dpt-text:hover{background-color:rgba(0,0,0,.01);color:#2980b9;border:1px solid #eee;-webkit-transition:color .3s ease;transition:color .3s ease}.cp.cpe .dpt>.dpt-text.artigo{float:none}.cp.cpe .dpt>.dpt-text a.link-rotulo{color:#000}.cp.cpe .dpt:hover>.dpt-actions-fixed{opacity:1}.cp.cpe .dpt:hover>.dpt-actions-fixed:hover~.dpt-text{background-color:rgba(0,0,0,.01);color:#2980b9;border:1px solid #eee;-webkit-transition:color .3s ease;transition:color .3s ease}.cp.cpe .dpt .semtexto{font-weight:700;color:#9aaed6}.cp.cpe .dpt .semtexto:hover{color:#5f76a4}.cp.cpe .dpt-alts{margin:0;margin-bottom:1em;padding:0;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe .dpt-alts:hover{border-color:#d9ddde}.cp.cpe .dpt-alts:empty{border-color:#ddd}.cp.cpe .dpt-alts.drag{width:100%!important;border-color:#d9ddde}.cp.cpe .dpt-alts.drag .dpt{-webkit-transition-duration:0s!important;transition-duration:0s!important}.cp.cpe .dpt-alts .dpt{width:100%!important;-webkit-box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);padding:0;margin:0;background-color:#edf0f1;height:auto!important;min-height:2em;z-index:1}.cp.cpe .dpt-alts .dpt:not(:first-child){border-top:1px solid #fff}.cp.cpe .dpt-alts .dpt>.dpt-text{padding:.3em 1em;margin-top:0;margin-bottom:0}.cp.cpe .dpt-alts .dpt>.dpt-text a.link-rotulo{text-decoration:underline}.cp.cpe .dpt-alts .dpt-selected.dpt{margin:0 -.5em}.cp.cpe .dpt-selected.dpt{width:auto!important;margin:1em -.5em;border:1px solid #ddd!important;padding:0;background-color:#fafafa;border-radius:3px;z-index:4}.cp.cpe .dpt-selected.dpt>.dpt-text{border:1px solid transparent}.cp.cpe .dpt-selected.dpt>.dpt-text:hover{border:1px solid transparent;background-color:transparent}.cp.cpe .dpt-selected.dpt>.dpt-form{margin:0 1rem}.cp.cpe .dpt-selected.dpt>.dpt-actions,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{display:table;background-color:#e5e5e5;padding:.8rem .6rem .2rem .6rem;margin-bottom:0;width:100%}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom>.btn-action,.cp.cpe .dpt-selected.dpt>.dpt-actions>.btn-action{display:table-cell;float:none}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btns-excluir .btn-danger,.cp.cpe .dpt-selected.dpt>.dpt-actions .btns-excluir .btn-danger{display:inline-block;opacity:.3;color:#fff}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btns-excluir .btn-danger:hover,.cp.cpe .dpt-selected.dpt>.dpt-actions .btns-excluir .btn-danger:hover{opacity:1}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{margin:0;padding-bottom:.8rem}.cp.cpe .dpt-selected .dpt-block{border-top:1px solid #e5e5e5!important;opacity:.6;-webkit-transition:opacity .4s ease;transition:opacity .4s ease}.cp.cpe .dpt-selected .dpt-block:hover{opacity:1}.cp.cpe .dpt-selected .dpt-text{opacity:.7;margin:0;padding:.7em}.cp.cpe .dpt-selected .dpt-text:hover{opacity:1;background-color:#f5f5f5}.cp.cpe .dpt-selected .dpt-alts{margin:1em}.cp.cpe .dpt-selected .dpt-alts .dpt{-webkit-box-shadow:0 0 0;box-shadow:0 0 0}.cp.cpe .dpt-selected>.dpt-actions-fixed{opacity:1;top:-15px;right:.5em}.cp.cpe .dpt-selected>.dpt-actions-fixed .activate{display:inline}.cp.cpe .dpt-selected>.dpt-actions-fixed .deactivate{display:none}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit{padding:0 6px;line-height:1.2rem}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary,.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary:hover{background-color:#fad46b;border:1px solid #444}.cp.cpe .dpt-selected .btns-tipos-editor{padding:0}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left{right:auto!important;left:0;padding:0}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left:before{content:"";position:absolute;background-color:transparent;width:100%;height:3px;top:-3px;display:inline-block}.cp.cpe .dpt-selected .dropdown-menu li{line-height:1}.cp.cpe .dpt-selected .dropdown-menu li a{display:block;line-height:1.5rem;padding:0 .5rem;white-space:nowrap}.cp.cpe .dpt-selected .dropdown-menu li a:hover{background-color:#f0f0f0}.cp.cpe .dpt-selected .dropdown-menu li:not(:last-child){border-bottom:1px solid #f0f0f0}.cp.cpe .dpt-selected .btn-group .radius-right{border-bottom-right-radius:.2rem!important;border-top-right-radius:.2rem!important}.cp.cpe .dpt-selected:hover>.dpt-actions-fixed{opacity:1}.cp.cpe1_old_apagar{margin-bottom:15em}.cp.cpe1_old_apagar .desativado,.cp.cpe1_old_apagar .desativado *,.cp.cpe1_old_apagar .dpt .dptt>a.desativado,.cp.cpe1_old_apagar .dpt .dptt>a.desativado *{text-decoration:line-through;color:#999!important}.cp.cpe1_old_apagar .desativado * table,.cp.cpe1_old_apagar .desativado * table td,.cp.cpe1_old_apagar .desativado table,.cp.cpe1_old_apagar .desativado table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table td{border:1px dotted #ccc}.cp.cpe1_old_apagar a{text-decoration:none;cursor:pointer}.cp.cpe1_old_apagar .dpt{position:relative;display:block}.cp.cpe1_old_apagar .dpt .semtexto{font-weight:700;color:#bfd1f6}.cp.cpe1_old_apagar .dpt .artigo{float:none}.cp.cpe1_old_apagar .dpt .caput{margin-top:0}.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left,.cp.cpe1_old_apagar .dpt>.actions_right{color:#fff;right:0;position:absolute;opacity:0;-webkit-transition:all .4s ease-in-out;transition:all .4s ease-in-out;z-index:1000}.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco,.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco{background-color:#3498db;color:#fff!important;padding:8px 18px 6px;display:inline-block;line-height:1;float:right}.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco:hover,.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco:hover{opacity:1;background-image:-webkit-gradient(linear,left top,left bottom,from(#1c81c4),to(#0b6dad));background-image:linear-gradient(180deg,#1c81c4,#0b6dad)}.cp.cpe1_old_apagar .dpt-selected .csform .dpt:hover>.actions_left,.cp.cpe1_old_apagar .dpt:hover>.actions_right{opacity:1}.cp.cpe1_old_apagar .dpt .bloco{display:block;clear:both}.cp.cpe1_old_apagar .dpt .bloco :hover{color:#27ae60}.cp.cpe1_old_apagar .dpt .bloco .de{cursor:pointer}.cp.cpe1_old_apagar .dpt .articulacao{border-top:2px solid #e5e5e5;margin:2em 0}.cp.cpe1_old_apagar .dpt .bloco_alteracao{margin:1em 0;padding:0;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe1_old_apagar .dpt .bloco_alteracao:hover{border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag{width:100%!important;border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag .dpt{-webkit-transition-duration:0s!important;transition-duration:0s!important}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt{width:100%!important;-webkit-box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);padding:.3em 1em;margin:0;background-color:#edf0f1;z-index:1}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt:not(:first-child){border-top:1px solid #fff}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.ui-draggable div{cursor:pointer}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.dpt-comp-selected{-webkit-transition:all .3s ease;transition:all .3s ease;width:auto!important;margin:2em -3.7em;-webkit-box-shadow:0 0 6px rgba(0,0,0,.16),0 6px 12px rgba(0,0,0,.32);box-shadow:0 0 6px rgba(0,0,0,.16),0 6px 12px rgba(0,0,0,.32)}.cp.cpe1_old_apagar .dpt-selected{font-size:1em;border:0 solid #ccc;margin:1em -1.8em 1em -1.8em;padding:2.2em 2.2em 1.6em 2.2em;-webkit-box-shadow:-4px 15px 15px rgba(0,0,0,.1),0 6px 6px rgba(0,0,0,.23);box-shadow:-4px 15px 15px rgba(0,0,0,.1),0 6px 6px rgba(0,0,0,.23);background-image:-webkit-gradient(linear,left top,left bottom,from(#eaeaee),to(#ddd));background-image:linear-gradient(180deg,#eaeaee,#ddd)}.cp.cpe1_old_apagar .dpt-selected ul{list-style:none;margin:0;padding:0}.cp.cpe1_old_apagar .dpt-selected .semtexto{color:#999}.cp.cpe1_old_apagar .dpt-selected .bloco{opacity:.5}.cp.cpe1_old_apagar .dpt-selected .bloco:hover{opacity:1}.cp.cpe1_old_apagar .dpt-selected .bloco a:hover{background:transparent}.cp.cpe1_old_apagar .dpt-selected>.bloco{opacity:1;margin:1em}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao{margin:0;padding:1em;border:0 transparent;background-image:-webkit-gradient(linear,left top,left bottom,from(#eaeaee),to(#ddd));background-image:linear-gradient(180deg,#eaeaee,#ddd)}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao:hover{border-color:transparent}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag{width:100%!important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag .dpt{-webkit-transition-duration:0s!important;transition-duration:0s!important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt{width:auto!important;-webkit-transition:all .3s ease;transition:all .3s ease;background-color:#fff}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt:not(:first-child){border-top:0 solid #fff}.cp.cpe1_old_apagar .dpt-selected>.dpt{padding:0}.cp.cpe1_old_apagar .dpt-selected>.dpt:last-child{padding-bottom:1em}.cp.cpe1_old_apagar .dpt-selected .csform .dpt-selected>.actions_left a.btn-bloco,.cp.cpe1_old_apagar .dpt-selected>.actions_right a.btn-bloco{display:none}.cp.cpe1_old_apagar .dpt-selected .csform{display:block;clear:both;z-index:9;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action{-webkit-animation:fadeIn 1s ease-in-out;-moz-animation:fadeIn 1s ease-in-out;-o-animation:fadeIn 1s ease-in-out;opacity:1;position:absolute;display:table;-webkit-transition:all .4s ease-in-out;transition:all .4s ease-in-out}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action a{color:#16407c;display:block;background:transparent;vertical-align:middle;text-align:center;font-weight:400;text-shadow:0 0 10px rgba(0,0,0,.3);padding:.33em .4em}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li{position:relative;display:table-cell;vertical-align:top}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover{background-color:hsla(0,0%,100%,.5)}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover>a{text-shadow:0 0 5px #777;color:#0a5}.cp.cpe1_old_apagar .dpt-selected .csform .label_status{position:absolute;bottom:0;right:0;color:#889;padding:.3em;font-size:80%;text-align:right;z-index:15;display:table}.cp.cpe1_old_apagar .dpt-selected .csform .label_status li{display:table-cell;padding:0 .5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents{z-index:11;top:0;left:0}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents a{padding:.62em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div,.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents li{font-size:80%;display:table-cell;vertical-align:middle;border-right:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div{padding:0 .4em;font-stretch:condensed;font-variant:small-caps;font-weight:700;text-shadow:0 0 10px #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents>li:hover a{color:#16407c;font-weight:400}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom,.cp.cpe1_old_apagar .dpt-selected .csform .actions_top{top:0;right:0}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a,.cp.cpe1_old_apagar .dpt-selected .csform .actions_top a{padding-right:1em;padding-left:1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_top li{display:table-cell;vertical-align:middle;border-left:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom{top:auto;left:0;bottom:0;display:inline-block;border-top:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a{padding:0 .4em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li{border:0;border-right:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left,.cp.cpe1_old_apagar .dpt-selected .csform .actions_right{top:2.2em;right:0;bottom:0;display:block}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li{width:2.2em;display:block;border-bottom:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li:first-child,.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li:first-child{border-top:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left{right:auto;left:0}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts{background:transparent;position:relative;z-index:19;display:table;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li{display:table-cell}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:hover>a{background-image:-webkit-gradient(linear,left top,left bottom,from(#1c81c4),to(#0b6dad));background-image:linear-gradient(180deg,#1c81c4,#0b6dad)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a{background-image:-webkit-gradient(linear,left top,left bottom,from(#3498db),to(#2980c9));background-image:linear-gradient(180deg,#3498db,#2980c9);border-right:1px solid #fff;padding:.2em;display:block;color:#fff;text-align:center;white-space:nowrap}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{text-align:left;background:#a70808;color:#c99;padding-left:1.7em;position:relative}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir:hover,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background-color:#c70808;color:#ecc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir:before,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before{z-index:20;position:absolute;background:url(/static/img/icon_delete_white.png) no-repeat 50% 50%;content:"";top:0;left:0;display:block;color:#000;margin-left:.4em;height:100%;width:2em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{background:#1f8b4d;color:#fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background:#2d9c5c;color:#fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before{background:url(/static/img/icon_save_white.png) no-repeat 50% 50%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a span{padding:0 .7em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:last-child>a{border-right:0 solid #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li:nth-child(2n) a{background:#3385ca}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a{border-right:1px solid #fff;display:block;color:#fff;background:#2980c9;font-size:80%;padding:.23em 1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a:hover{background:#0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior{table-layout:fixed}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li a{border-right:0!important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir{display:block;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{border-right:0!important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{right:.5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{background-color:#a70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a:hover{background:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:before{border-color:transparent transparent #a70808;right:10%;left:auto}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover:before{border-color:transparent transparent #c70808}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo{z-index:2000}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li a,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li a{border-right:0!important}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child:before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child:hover:before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul:after,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li:hover>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li.menu_excluir>ul li:first-child:before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li.menu_excluir>ul li:first-child:before{right:auto;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform textarea{margin:0;resize:vertical;min-height:12.6em;border:0;font-size:120%;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:focus{background:#fff}.cp.cpe1_old_apagar .dpt-selected .csform textarea::-webkit-input-placeholder{color:#c70808;opacity:.6;font-size:80%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-moz-placeholder,.cp.cpe1_old_apagar .dpt-selected .csform textarea::-moz-placeholder{color:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-ms-input-placeholder{color:#c70808;opacity:.6}.cp.cpe1_old_apagar .selected{background-color:hsla(0,0%,100%,.5)}.cp.cpe1_old_apagar .selected a:hover{color:#16407c!important;font-weight:400!important}.lista-dispositivo,.result-busca-dispositivo{padding:0 0 1em;min-height:3em}.lista-dispositivo ul,.result-busca-dispositivo ul{list-style:none;margin:0;padding:1em 0 0;-webkit-transition:all 2s linear;transition:all 2s linear;clear:both}.lista-dispositivo ul li,.result-busca-dispositivo ul li{display:table;border-collapse:separate;border-bottom:1px solid #fff;width:100%}.lista-dispositivo ul li.ta_title,.result-busca-dispositivo ul li.ta_title{background-color:rgba(0,0,0,.15);border-radius:4px 4px 0 0;width:100%}.lista-dispositivo ul li:last-child .itemlabel,.result-busca-dispositivo ul li:last-child .itemlabel{border-radius:0 0 4px 0;margin:0}.lista-dispositivo ul li:last-child .iteminput,.result-busca-dispositivo ul li:last-child .iteminput{border-radius:0 0 0 4px}.lista-dispositivo ul li .iteminput,.result-busca-dispositivo ul li .iteminput{background-color:rgba(0,0,0,.1);border-right:1px solid #fff;display:table-cell;padding:.5em;vertical-align:middle;text-align:center}.lista-dispositivo ul li .iteminput input,.result-busca-dispositivo ul li .iteminput input{margin:0}.lista-dispositivo ul li .itemlabel,.result-busca-dispositivo ul li .itemlabel{background-color:rgba(0,0,0,.1);display:table-cell;padding:.5em;vertical-align:middle;width:100%}.lista-dispositivo ul li .itemlabel .artigo,.result-busca-dispositivo ul li .itemlabel .artigo{float:none}.lista-dispositivo .nomenclatura_heranca,.result-busca-dispositivo .nomenclatura_heranca{font-size:90%;color:#057dba;display:inline}.lista-dispositivo.controls-radio-checkbox{border:0}.label_vigencia{border-top:1px solid #fff;display:inline-block;color:#555}.label_vigencia span{color:grey}.cp-nav-parents .dropdown-menu{left:0;right:auto;padding:0}.cp-nav-parents .dropdown-menu:before{content:"";position:absolute;top:-11px;width:100%;height:11px}.cp-nav-parents:hover .dropdown-menu{display:block}.cp-nav-parents a.active small{color:#fff!important}.table-notificacoes tbody tr td{border-top:1px solid #fff;padding:5px;vertical-align:middle}.table-notificacoes tbody tr td ul{margin:0}.table-notificacoes tbody tr td ul li:hover{background-color:rgba(0,0,0,.1)}.btn-modal-open{float:right}.modal .modal-content .alert:only-child{margin:0}.class_color_container{background:#ddd!important}.clear{clear:both}.mce-tinymce.mce-container{border:1px solid #ccc!important;margin-right:2px}.mce-btn button:hover{background-color:rgba(0,0,0,.1)!important;text-shadow:0 0 5px #fff;-webkit-box-shadow:0 0 5px #777;box-shadow:0 0 5px #777}.mce-menu{background:#eee!important}.displaynone{display:none!important}@media only screen and (max-width:800px){.cp .fixed{z-index:98;position:relative}.cp.cpe1 .dpt-selected{margin:1em 0}.cp.cpe1 .dpt-selected .csform .actions_parents,.cp.cpe1 .dpt-selected .csform .label_status{font-size:80%;position:static!important;display:block!important;padding:0;height:auto!important;left:0;right:auto;text-align:left}.cp.cpe1 .dpt-selected .csform .actions_parents div,.cp.cpe1 .dpt-selected .csform .actions_parents li,.cp.cpe1 .dpt-selected .csform .label_status div,.cp.cpe1 .dpt-selected .csform .label_status li{display:inline-block!important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li a{border-right:0!important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a span{display:none}.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar{padding-left:0;min-width:1em}.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir:before,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before{width:100%;margin:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior{position:static}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul{left:1em!important;right:1em!important;margin-left:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul li:first-child:before{left:37%}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next>ul{left:0!important;right:1em!important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul{left:1em!important;right:0!important;margin-left:0;margin-right:.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:before{right:42%;left:auto}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{left:10%!important;right:0!important;margin-left:0;margin-right:.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:before{right:0;left:auto}}@media print{.button,.cp-linha-vigencias,.cp .vigencias,.dne,.menu-icon,.tipo-vigencias,.toggle-topbar{display:none!important}#btn_font_mais,#btn_font_menos{display:none}.container{width:100%}}
\ No newline at end of file
diff --git a/sapl/static/sapl/frontend/css/compilacao.3d691cd9.css.gz b/sapl/static/sapl/frontend/css/compilacao.3d691cd9.css.gz
deleted file mode 100644
index ca1c5c876..000000000
Binary files a/sapl/static/sapl/frontend/css/compilacao.3d691cd9.css.gz and /dev/null differ
diff --git a/sapl/static/sapl/frontend/css/compilacao.eff62463.css b/sapl/static/sapl/frontend/css/compilacao.eff62463.css
new file mode 100644
index 000000000..96be5dad7
--- /dev/null
+++ b/sapl/static/sapl/frontend/css/compilacao.eff62463.css
@@ -0,0 +1 @@
+a:link:after,a:visited:after{content:""}.test_import:nth-child(2n){background-color:#ccc}#wait_message{display:block;position:fixed;top:0;bottom:0;left:0;right:0;background-color:hsla(0,0%,86.3%,.75);z-index:99}#wait_message #msg{position:relative;margin:20% auto;padding:1.2em 2em;max-width:600px;text-align:center;font-size:1.5em;color:#677;border:1px solid #eee;background-color:#fff!important;-webkit-box-shadow:0 1px 2px #999;box-shadow:0 1px 2px #999}.text-center{text-align:center}.cp-notify{z-index:10000;position:fixed;top:2em;left:50%;min-width:600px;-webkit-transform:translate(-50%);transform:translate(-50%);opacity:.97}.cp-notify,.cp-notify.hide{-webkit-transition:all .4s ease;transition:all .4s ease}.cp-notify.hide{opacity:0;top:-1000px;display:block!important}.cp-notify .message{padding:1em;border:2px solid rgba(0,0,0,.1);border-radius:4px;color:rgba(0,0,0,.6);line-height:1em;font-size:1.3em;text-align:center;-webkit-box-shadow:0 0 100px rgba(0,0,0,.2);box-shadow:0 0 100px rgba(0,0,0,.2)}.cp .vigencia-active{margin-top:30px;display:block}.cp .cp-linha-vigencias{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;list-style:none;margin:4rem 0 3rem;padding:0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.cp .cp-linha-vigencias ul{list-style:none;margin:0;padding:0}.cp .cp-linha-vigencias>li{display:-webkit-box;display:-ms-flexbox;display:flex;position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;line-height:0;background:#000;height:2px;text-align:center;max-width:4rem}.cp .cp-linha-vigencias>li .circle{display:block;width:10px;line-height:0;background:#000;height:10px;margin:-5px auto 0;border-radius:50%}.cp .cp-linha-vigencias>li>a{position:absolute;white-space:nowrap;line-height:1rem;text-align:center}.cp .cp-linha-vigencias>li:nth-child(2n)>a{top:100%;margin-top:5px}.cp .cp-linha-vigencias>li:nth-child(odd)>a{bottom:100%;margin-bottom:5px}.cp .cp-linha-vigencias>li ul{z-index:1;position:absolute;display:none;background:#fff;margin:30px 0;border:1px solid #aaa;-webkit-box-shadow:0 0 10px #aaa;box-shadow:0 0 10px #aaa;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.cp .cp-linha-vigencias>li ul:before{content:" ";width:2px;height:30px;position:absolute;display:block;background-color:#aaa;bottom:100%;left:50%;margin-left:-1px}.cp .cp-linha-vigencias>li ul li{text-align:left}.cp .cp-linha-vigencias>li ul a{display:block;white-space:nowrap;line-height:2rem;padding:0 10px;font-size:1rem}.cp .cp-linha-vigencias>li ul a:hover{background:#eee}.cp .cp-linha-vigencias>li.active .circle{display:block;width:20px;line-height:0;background:#aaa;height:20px;margin:-10px auto 0}.cp .cp-linha-vigencias>li.active:not(:last-child)>a{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);margin-bottom:25px;font-weight:700}.cp .cp-linha-vigencias>li.active:first-child>a,.cp .cp-linha-vigencias>li.active:last-child>a{-webkit-transform:rotate(0deg);transform:rotate(0deg);margin-bottom:15px;font-weight:700}.cp .cp-linha-vigencias>li.active>a{margin-bottom:5px}.cp .cp-linha-vigencias>li.active:nth-child(2n)>a{bottom:100%;top:auto}.cp .cp-linha-vigencias>li.active ul{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cp .cp-linha-vigencias>li.active ul li{text-align:left;width:100%}.cp .cp-vigencias .nav-link{padding:.5rem}.cp .cp-vigencias .dropdown-toggle:after{zoom:.8;margin:0}.cp .cp-vigencias .dropdown-menu{margin-left:.5rem}.cp .cp-vigencias .dropdown-item{padding:0}.cp .cp-vigencias .dropdown-item a{line-height:1;padding:.7rem}.cp .desativado .dpt-link,.cp .desativado .dpt-link *,.cp .desativado .dtxt,.cp .desativado .dtxt *,.cp .dpt .dptt>a.desativado .dpt-link,.cp .dpt .dptt>a.desativado .dpt-link *,.cp .dpt .dptt>a.desativado .dtxt,.cp .dpt .dptt>a.desativado .dtxt *{text-decoration:line-through;color:#999!important}.cp .desativado .dpt-link * table,.cp .desativado .dpt-link * table td,.cp .desativado .dpt-link table,.cp .desativado .dpt-link table td,.cp .desativado .dtxt * table,.cp .desativado .dtxt * table td,.cp .desativado .dtxt table,.cp .desativado .dtxt table td,.cp .dpt .dptt>a.desativado .dpt-link * table,.cp .dpt .dptt>a.desativado .dpt-link * table td,.cp .dpt .dptt>a.desativado .dpt-link table,.cp .dpt .dptt>a.desativado .dpt-link table td,.cp .dpt .dptt>a.desativado .dtxt * table,.cp .dpt .dptt>a.desativado .dtxt * table td,.cp .dpt .dptt>a.desativado .dtxt table,.cp .dpt .dptt>a.desativado .dtxt table td{border:1px dotted #ccc}.cp a{text-decoration:none;cursor:pointer}.cp .diff .desativado,.cp .diff .desativado *,.cp .diff .dpt .dptt>a.desativado,.cp .diff .dpt .dptt>a.desativado *,.cp .dpt .diff .dptt>a.desativado,.cp .dpt .diff .dptt>a.desativado *{text-decoration:line-through;color:#ddd!important;font-size:90%}.cp .diff .added{color:#04de2c}.cp .dpt{font-size:1em;position:relative}.cp .dpt.indent{padding-left:1em}.cp .dpt .ementa{padding:2em 0 2em 35%;font-weight:700}.cp .dpt .anexo,.cp .dpt .capitulo,.cp .dpt .disp_finais,.cp .dpt .disp_gerais,.cp .dpt .disp_preliminares,.cp .dpt .disp_transitorias,.cp .dpt .itemsecao,.cp .dpt .livro,.cp .dpt .parte,.cp .dpt .secao,.cp .dpt .subsecao,.cp .dpt .titulo,.cp .dpt .titulo_generico{text-align:center;margin-bottom:1em;font-size:1.5em;margin-top:3em;font-weight:700;font-variant:small-caps}.cp .dpt .titulo{margin-top:2em}.cp .dpt .capitulo{margin-top:1.5em;font-size:1.15em}.cp .dpt .secao{margin-top:1.2em;margin-bottom:.7em;font-weight:700;font-size:1.15em}.cp .dpt .itemsecao,.cp .dpt .subsecao{margin-top:1em;margin-bottom:.6em;font-weight:700;font-size:1.15em}.cp .dpt .artigo{font-size:1.15em;float:left}.cp .dpt .artigo .dptt{position:relative}.cp .dpt .caput{margin-top:.3333em;font-size:1.15em}.cp .dpt .paragrafo{font-size:1.1em;margin-top:.2222em}.cp .dpt .inciso{font-size:1.1em;margin-top:.1667em}.cp .dpt .alinea,.cp .dpt .item{font-size:1em;margin-top:2px}.cp .dpt .assinatura,.cp .dpt .fecho_lei{margin-top:.6em;font-size:1.15em}.cp .dpt .page-break{page-break-before:always}.cp .dpt .bloco_alteracao{padding-left:10%;font-style:italic;color:#018}.cp .dpt .bloco_alteracao a{text-decoration:underline}.cp .dpt .bloco_alteracao a,.cp .dpt .bloco_alteracao table,.cp .dpt .bloco_alteracao table td{color:#018!important}.cp .dpt .bloco_alteracao .desativado,.cp .dpt .bloco_alteracao .desativado a,.cp .dpt .bloco_alteracao .desativado table,.cp .dpt .bloco_alteracao .desativado table td,.cp .dpt .bloco_alteracao .dptt>a.desativado{text-decoration:line-through;color:#999!important}.cp .dpt .card-header{font-size:1.7rem}.cp .dpt .dn{font-weight:400;position:relative;font-size:80%}.cp .dpt .dn p,.cp .dpt .dn ul{font-weight:400;margin:0 0 0 0;list-style:none;padding:0}.cp .dpt .dn .dnl{display:block;text-align:left!important}.cp .dpt .dn .dnl *{display:inline}.cp .dpt .dn .dnl .bullet{padding:0 .333em;display:inline-block}.cp .dpt .dn .dnl .dnli{min-height:2.5em}.cp .dpt .dn .dnl .dnli:hover ul{font-size:1rem;clip:auto;opacity:1;background:hsla(0,0%,90.2%,.9)}.cp .dpt .dn .dnl .dnli:hover ul,.cp .dpt .dn .dnl .dnli ul{-webkit-transition:opacity .5s linear,clip 0s .3s;transition:opacity .5s linear,clip 0s .3s}.cp .dpt .dn .dnl .dnli ul{clip:rect(0,0,0,0);opacity:0;position:absolute;background:transparent;right:0;padding:.2em .5em 0 .5em;border:1px solid #c7e3d3;border-top:0;font-size:1.5rem}.cp .dpt .dn .dnl .dnli ul li{display:table-cell;color:#aaa}.cp .dpt .dn .dnl .dnli ul li:hover{color:#787}.cp .dpt .dn .dnl .dnli ul li .nowner,.cp .dpt .dn .dnl .dnli ul li:hover a{color:#27ae60!important}.cp .dpt .dn .dnl .dnli .ntitulo{font-size:.8rem;font-weight:700;color:#03a203;text-decoration:none}.cp .dpt .dn .dnl .dnli .ntitulo a{color:#294!important}.cp .dpt .dn .dnl .dnli .ntexto{font-variant:normal;font-size:.8rem;color:#018801}.cp .dpt .dn .dnl .dnli .ntexto a{color:#03a203!important}.cp .dpt .dn .dnl:hover,.cp .dpt .dn .dnl:hover *{display:block}.cp .dpt .dn .dnl:hover>.bullet{display:none}.cp .dpt .dn .dnl:hover .dnli{margin-top:.5em;border-top:1px solid #c7e3d3}.cp .dpt .dptt{clear:left}.cp .dpt .dptt>a{color:#000}.cp .dpt .dptt>a.nota-alteracao{color:#02baf2;font-size:.75em}.cp .dpt .dptt>a.nota-alteracao:hover{text-decoration:underline}.cp .dpt .dptt .dne{position:absolute;display:block;right:0;left:0;top:0;height:0;-webkit-transform:scaleX(0);transform:scaleX(0);-webkit-transform-origin:right;transform-origin:right;-webkit-transition:all .3s ease;transition:all .3s ease;border-top:1px solid #2980b9}.cp .dpt .dptt .dne ul.btns-action{list-style:none;padding:0;position:absolute;right:0;background-color:#2980b9}.cp .dpt .dptt .dne ul.btns-action li{float:left}.cp .dpt .dptt .dne ul.btns-action li:hover{background-color:rgba(0,0,0,.1)}.cp .dpt .dptt .dne ul.btns-action li a{color:#fff;padding:.15em 1em 0;display:inline-block}.cp .dpt .dptt .dne-nota{position:relative;-webkit-transform:scaleX(1);transform:scaleX(1);height:auto;border-top:0}.cp .dpt .dptt .dne-nota ul.btns-action{display:none}.cp .dpt .dptt .dne-nota .dne-form{margin:1em -2em 0;text-align:left;font-size:1rem}.cp .dpt .dptt:hover .dne{height:.1667rem;-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transition-delay:1s;transition-delay:1s}.cp .dpt .dptt:hover .dne-nota{height:auto;-webkit-transition-delay:0s;transition-delay:0s}.cp .tipo-vigencias{margin-bottom:-6px;opacity:.8;list-style:none;position:fixed;bottom:0;left:50%;-webkit-transform:translate(-50%);transform:translate(-50%);margin:0;padding:0;z-index:1000;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.cp .tipo-vigencias div a{color:#fff}.cp .tipo-vigencias:hover,.cp:hover{opacity:1}.cp .revogado{color:#800}.cp .revogado .dpt-link{color:#999!important}.cp .omissis a{text-decoration:none!important}.cp-print .cp-linha-vigencias{display:none!important}.cp.cpe .desativado,.cp.cpe .dpt .dptt>a.desativado{text-decoration:line-through;color:#999!important}.cp.cpe .desativado table,.cp.cpe .desativado table td,.cp.cpe .dpt .dptt>a.desativado table,.cp.cpe .dpt .dptt>a.desativado table td{border:1px dotted #ccc}.cp.cpe a.nota-alteracao{color:#02baf2!important;font-size:.8rem}.cp.cpe .btn-sm{line-height:1rem}.cp.cpe .btn-outline-primary{background-color:#fff}.cp.cpe .btn-outline-primary:hover{background-color:#02baf2}.cp.cpe .dpt{display:block}.cp.cpe .dpt>.dpt-actions-fixed{position:absolute;right:-1em;top:-.8em;z-index:3;opacity:0}.cp.cpe .dpt>.dpt-actions-fixed.bottom{top:auto;bottom:3px;right:2px}.cp.cpe .dpt>.dpt-actions-fixed .activate{display:none}.cp.cpe .dpt>.dpt-actions-fixed .deactivate{display:inline}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary{color:#333}.cp.cpe .dpt>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary:hover{color:#fff;background-color:#02baf2}.cp.cpe .dpt>.dpt-actions,.cp.cpe .dpt>.dpt-actions-bottom{display:none}.cp.cpe .dpt>.dpt-text{cursor:text;min-height:30px;border:1px solid transparent}.cp.cpe .dpt>.dpt-text.hover-fixed,.cp.cpe .dpt>.dpt-text:hover{background-color:rgba(0,0,0,.01);color:#2980b9;border:1px solid #eee;-webkit-transition:color .3s ease;transition:color .3s ease}.cp.cpe .dpt>.dpt-text.artigo{float:none}.cp.cpe .dpt>.dpt-text a.link-rotulo{color:#000}.cp.cpe .dpt:hover>.dpt-actions-fixed{opacity:1}.cp.cpe .dpt:hover>.dpt-actions-fixed:hover~.dpt-text{background-color:rgba(0,0,0,.01);color:#2980b9;border:1px solid #eee;-webkit-transition:color .3s ease;transition:color .3s ease}.cp.cpe .dpt .semtexto{font-weight:700;color:#9aaed6}.cp.cpe .dpt .semtexto:hover{color:#5f76a4}.cp.cpe .dpt-alts{margin:0;margin-bottom:1em;padding:0;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe .dpt-alts:hover{border-color:#d9ddde}.cp.cpe .dpt-alts:empty{border-color:#ddd}.cp.cpe .dpt-alts.drag{width:100%!important;border-color:#d9ddde}.cp.cpe .dpt-alts.drag .dpt{-webkit-transition-duration:0s!important;transition-duration:0s!important}.cp.cpe .dpt-alts .dpt{width:100%!important;-webkit-box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);padding:0;margin:0;background-color:#edf0f1;height:auto!important;min-height:2em;z-index:1}.cp.cpe .dpt-alts .dpt:not(:first-child){border-top:1px solid #fff}.cp.cpe .dpt-alts .dpt>.dpt-text{padding:.3em 1em;margin-top:0;margin-bottom:0}.cp.cpe .dpt-alts .dpt>.dpt-text a.link-rotulo{text-decoration:underline}.cp.cpe .dpt-alts .dpt-selected.dpt{margin:0 -.5em}.cp.cpe .dpt-selected.dpt{width:auto!important;margin:1em -.5em;border:1px solid #ddd!important;padding:0;background-color:#fafafa;border-radius:3px;z-index:4}.cp.cpe .dpt-selected.dpt>.dpt-text{border:1px solid transparent}.cp.cpe .dpt-selected.dpt>.dpt-text:hover{border:1px solid transparent;background-color:transparent}.cp.cpe .dpt-selected.dpt>.dpt-form{margin:0 1rem}.cp.cpe .dpt-selected.dpt>.dpt-actions,.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{display:table;background-color:#e5e5e5;padding:.8rem .6rem .2rem .6rem;margin-bottom:0;width:100%}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom>.btn-action,.cp.cpe .dpt-selected.dpt>.dpt-actions>.btn-action{display:table-cell;float:none}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btns-excluir .btn-danger,.cp.cpe .dpt-selected.dpt>.dpt-actions .btns-excluir .btn-danger{display:inline-block;opacity:.3;color:#fff}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom .btns-excluir .btn-danger:hover,.cp.cpe .dpt-selected.dpt>.dpt-actions .btns-excluir .btn-danger:hover{opacity:1}.cp.cpe .dpt-selected.dpt>.dpt-actions-bottom{margin:0;padding-bottom:.8rem}.cp.cpe .dpt-selected .dpt-block{border-top:1px solid #e5e5e5!important;opacity:.6;-webkit-transition:opacity .4s ease;transition:opacity .4s ease}.cp.cpe .dpt-selected .dpt-block:hover{opacity:1}.cp.cpe .dpt-selected .dpt-text{opacity:.7;margin:0;padding:.7em}.cp.cpe .dpt-selected .dpt-text:hover{opacity:1;background-color:#f5f5f5}.cp.cpe .dpt-selected .dpt-alts{margin:1em}.cp.cpe .dpt-selected .dpt-alts .dpt{-webkit-box-shadow:0 0 0;box-shadow:0 0 0}.cp.cpe .dpt-selected>.dpt-actions-fixed{opacity:1;top:-15px;right:.5em}.cp.cpe .dpt-selected>.dpt-actions-fixed .activate{display:inline}.cp.cpe .dpt-selected>.dpt-actions-fixed .deactivate{display:none}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit{padding:0 6px;line-height:1.2rem}.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary,.cp.cpe .dpt-selected>.dpt-actions-fixed .btn-dpt-edit.btn-outline-primary:hover{background-color:#fad46b;border:1px solid #444}.cp.cpe .dpt-selected .btns-tipos-editor{padding:0}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left{right:auto!important;left:0;padding:0}.cp.cpe .dpt-selected .dropdown-menu.dropdown-menu-left:before{content:"";position:absolute;background-color:transparent;width:100%;height:3px;top:-3px;display:inline-block}.cp.cpe .dpt-selected .dropdown-menu li{line-height:1}.cp.cpe .dpt-selected .dropdown-menu li a{display:block;line-height:1.5rem;padding:0 .5rem;white-space:nowrap}.cp.cpe .dpt-selected .dropdown-menu li a:hover{background-color:#f0f0f0}.cp.cpe .dpt-selected .dropdown-menu li:not(:last-child){border-bottom:1px solid #f0f0f0}.cp.cpe .dpt-selected .btn-group .radius-right{border-bottom-right-radius:.2rem!important;border-top-right-radius:.2rem!important}.cp.cpe .dpt-selected:hover>.dpt-actions-fixed{opacity:1}.cp.cpe1_old_apagar{margin-bottom:15em}.cp.cpe1_old_apagar .desativado,.cp.cpe1_old_apagar .desativado *,.cp.cpe1_old_apagar .dpt .dptt>a.desativado,.cp.cpe1_old_apagar .dpt .dptt>a.desativado *{text-decoration:line-through;color:#999!important}.cp.cpe1_old_apagar .desativado * table,.cp.cpe1_old_apagar .desativado * table td,.cp.cpe1_old_apagar .desativado table,.cp.cpe1_old_apagar .desativado table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado * table td,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table,.cp.cpe1_old_apagar .dpt .dptt>a.desativado table td{border:1px dotted #ccc}.cp.cpe1_old_apagar a{text-decoration:none;cursor:pointer}.cp.cpe1_old_apagar .dpt{position:relative;display:block}.cp.cpe1_old_apagar .dpt .semtexto{font-weight:700;color:#bfd1f6}.cp.cpe1_old_apagar .dpt .artigo{float:none}.cp.cpe1_old_apagar .dpt .caput{margin-top:0}.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left,.cp.cpe1_old_apagar .dpt>.actions_right{color:#fff;right:0;position:absolute;opacity:0;-webkit-transition:all .4s ease-in-out;transition:all .4s ease-in-out;z-index:1000}.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco,.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco{background-color:#3498db;color:#fff!important;padding:8px 18px 6px;display:inline-block;line-height:1;float:right}.cp.cpe1_old_apagar .dpt-selected .csform .dpt>.actions_left a.btn-bloco:hover,.cp.cpe1_old_apagar .dpt>.actions_right a.btn-bloco:hover{opacity:1;background-image:-webkit-gradient(linear,left top,left bottom,from(#1c81c4),to(#0b6dad));background-image:linear-gradient(180deg,#1c81c4,#0b6dad)}.cp.cpe1_old_apagar .dpt-selected .csform .dpt:hover>.actions_left,.cp.cpe1_old_apagar .dpt:hover>.actions_right{opacity:1}.cp.cpe1_old_apagar .dpt .bloco{display:block;clear:both}.cp.cpe1_old_apagar .dpt .bloco :hover{color:#27ae60}.cp.cpe1_old_apagar .dpt .bloco .de{cursor:pointer}.cp.cpe1_old_apagar .dpt .articulacao{border-top:2px solid #e5e5e5;margin:2em 0}.cp.cpe1_old_apagar .dpt .bloco_alteracao{margin:1em 0;padding:0;background-color:transparent;min-height:100px;border:2px dashed #fff}.cp.cpe1_old_apagar .dpt .bloco_alteracao:hover{border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag{width:100%!important;border-color:#d9ddde}.cp.cpe1_old_apagar .dpt .bloco_alteracao.drag .dpt{-webkit-transition-duration:0s!important;transition-duration:0s!important}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt{width:100%!important;-webkit-box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);box-shadow:0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);padding:.3em 1em;margin:0;background-color:#edf0f1;z-index:1}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt:not(:first-child){border-top:1px solid #fff}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.ui-draggable div{cursor:pointer}.cp.cpe1_old_apagar .dpt .bloco_alteracao .dpt.dpt-comp-selected{-webkit-transition:all .3s ease;transition:all .3s ease;width:auto!important;margin:2em -3.7em;-webkit-box-shadow:0 0 6px rgba(0,0,0,.16),0 6px 12px rgba(0,0,0,.32);box-shadow:0 0 6px rgba(0,0,0,.16),0 6px 12px rgba(0,0,0,.32)}.cp.cpe1_old_apagar .dpt-selected{font-size:1em;border:0 solid #ccc;margin:1em -1.8em 1em -1.8em;padding:2.2em 2.2em 1.6em 2.2em;-webkit-box-shadow:-4px 15px 15px rgba(0,0,0,.1),0 6px 6px rgba(0,0,0,.23);box-shadow:-4px 15px 15px rgba(0,0,0,.1),0 6px 6px rgba(0,0,0,.23);background-image:-webkit-gradient(linear,left top,left bottom,from(#eaeaee),to(#ddd));background-image:linear-gradient(180deg,#eaeaee,#ddd)}.cp.cpe1_old_apagar .dpt-selected ul{list-style:none;margin:0;padding:0}.cp.cpe1_old_apagar .dpt-selected .semtexto{color:#999}.cp.cpe1_old_apagar .dpt-selected .bloco{opacity:.5}.cp.cpe1_old_apagar .dpt-selected .bloco:hover{opacity:1}.cp.cpe1_old_apagar .dpt-selected .bloco a:hover{background:transparent}.cp.cpe1_old_apagar .dpt-selected>.bloco{opacity:1;margin:1em}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao{margin:0;padding:1em;border:0 transparent;background-image:-webkit-gradient(linear,left top,left bottom,from(#eaeaee),to(#ddd));background-image:linear-gradient(180deg,#eaeaee,#ddd)}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao:hover{border-color:transparent}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag{width:100%!important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao.drag .dpt{-webkit-transition-duration:0s!important;transition-duration:0s!important}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt{width:auto!important;-webkit-transition:all .3s ease;transition:all .3s ease;background-color:#fff}.cp.cpe1_old_apagar .dpt-selected .bloco_alteracao .dpt:not(:first-child){border-top:0 solid #fff}.cp.cpe1_old_apagar .dpt-selected>.dpt{padding:0}.cp.cpe1_old_apagar .dpt-selected>.dpt:last-child{padding-bottom:1em}.cp.cpe1_old_apagar .dpt-selected .csform .dpt-selected>.actions_left a.btn-bloco,.cp.cpe1_old_apagar .dpt-selected>.actions_right a.btn-bloco{display:none}.cp.cpe1_old_apagar .dpt-selected .csform{display:block;clear:both;z-index:9;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action{-webkit-animation:fadeIn 1s ease-in-out;-moz-animation:fadeIn 1s ease-in-out;-o-animation:fadeIn 1s ease-in-out;opacity:1;position:absolute;display:table;-webkit-transition:all .4s ease-in-out;transition:all .4s ease-in-out}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action a{color:#16407c;display:block;background:transparent;vertical-align:middle;text-align:center;font-weight:400;text-shadow:0 0 10px rgba(0,0,0,.3);padding:.33em .4em}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li{position:relative;display:table-cell;vertical-align:top}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover{background-color:hsla(0,0%,100%,.5)}.cp.cpe1_old_apagar .dpt-selected .csform .btns-action>li:hover>a{text-shadow:0 0 5px #777;color:#0a5}.cp.cpe1_old_apagar .dpt-selected .csform .label_status{position:absolute;bottom:0;right:0;color:#889;padding:.3em;font-size:80%;text-align:right;z-index:15;display:table}.cp.cpe1_old_apagar .dpt-selected .csform .label_status li{display:table-cell;padding:0 .5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents{z-index:11;top:0;left:0}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents a{padding:.62em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div,.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents li{font-size:80%;display:table-cell;vertical-align:middle;border-right:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents div{padding:0 .4em;font-stretch:condensed;font-variant:small-caps;font-weight:700;text-shadow:0 0 10px #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_parents>li:hover a{color:#16407c;font-weight:400}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom,.cp.cpe1_old_apagar .dpt-selected .csform .actions_top{top:0;right:0}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a,.cp.cpe1_old_apagar .dpt-selected .csform .actions_top a{padding-right:1em;padding-left:1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_top li{display:table-cell;vertical-align:middle;border-left:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom{top:auto;left:0;bottom:0;display:inline-block;border-top:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom a{padding:0 .4em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_bottom li{border:0;border-right:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left,.cp.cpe1_old_apagar .dpt-selected .csform .actions_right{top:2.2em;right:0;bottom:0;display:block}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li,.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li{width:2.2em;display:block;border-bottom:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left li:first-child,.cp.cpe1_old_apagar .dpt-selected .csform .actions_right li:first-child{border-top:1px solid #ccc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_left{right:auto;left:0}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts{background:transparent;position:relative;z-index:19;display:table;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li{display:table-cell}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:hover>a{background-image:-webkit-gradient(linear,left top,left bottom,from(#1c81c4),to(#0b6dad));background-image:linear-gradient(180deg,#1c81c4,#0b6dad)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a{background-image:-webkit-gradient(linear,left top,left bottom,from(#3498db),to(#2980c9));background-image:linear-gradient(180deg,#3498db,#2980c9);border-right:1px solid #fff;padding:.2em;display:block;color:#fff;text-align:center;white-space:nowrap}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{text-align:left;background:#a70808;color:#c99;padding-left:1.7em;position:relative}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir:hover,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background-color:#c70808;color:#ecc}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-excluir:before,.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before{z-index:20;position:absolute;background:url(/static/img/icon_delete_white.png) no-repeat 50% 50%;content:"";top:0;left:0;display:block;color:#000;margin-left:.4em;height:100%;width:2em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar{background:#1f8b4d;color:#fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:hover{background:#2d9c5c;color:#fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before{background:url(/static/img/icon_save_white.png) no-repeat 50% 50%}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a span{padding:0 .7em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li:last-child>a{border-right:0 solid #fff}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li:nth-child(2n) a{background:#3385ca}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a{border-right:1px solid #fff;display:block;color:#fff;background:#2980c9;font-size:80%;padding:.23em 1em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>ul li a:hover{background:#0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior{table-layout:fixed}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li a{border-right:0!important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.add_prior:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir{display:block;position:static}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{border-right:0!important}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{right:.5em}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a{background-color:#a70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li a:hover{background:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:before{border-color:transparent transparent #a70808;right:10%;left:auto}.cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:hover:before{border-color:transparent transparent #c70808}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo{z-index:2000}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li a,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li a{border-right:0!important}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child:before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul li:first-child:hover:before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li>ul:after,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li:hover>ul,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante>li.menu_excluir>ul li:first-child:before,.cp.cpe1_old_apagar .dpt-selected .csform .menu_flutuante_fixo>li.menu_excluir>ul li:first-child:before{right:auto;left:.9375rem}.cp.cpe1_old_apagar .dpt-selected .csform textarea{margin:0;resize:vertical;min-height:12.6em;border:0;font-size:120%;width:100%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:focus{background:#fff}.cp.cpe1_old_apagar .dpt-selected .csform textarea::-webkit-input-placeholder{color:#c70808;opacity:.6;font-size:80%}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-moz-placeholder,.cp.cpe1_old_apagar .dpt-selected .csform textarea::-moz-placeholder{color:#c70808}.cp.cpe1_old_apagar .dpt-selected .csform textarea:-ms-input-placeholder{color:#c70808;opacity:.6}.cp.cpe1_old_apagar .selected{background-color:hsla(0,0%,100%,.5)}.cp.cpe1_old_apagar .selected a:hover{color:#16407c!important;font-weight:400!important}.lista-dispositivo,.result-busca-dispositivo{padding:0 0 1em;min-height:3em}.lista-dispositivo ul,.result-busca-dispositivo ul{list-style:none;margin:0;padding:1em 0 0;-webkit-transition:all 2s linear;transition:all 2s linear;clear:both;position:relative}.lista-dispositivo ul li,.result-busca-dispositivo ul li{display:table;border-collapse:separate;border-bottom:1px solid #fff;width:100%}.lista-dispositivo ul li.ta_title,.result-busca-dispositivo ul li.ta_title{background-color:rgba(0,0,0,.15);width:100%}.lista-dispositivo ul li:last-child .itemlabel,.result-busca-dispositivo ul li:last-child .itemlabel{margin:0}.lista-dispositivo ul li .iteminput,.result-busca-dispositivo ul li .iteminput{background-color:rgba(0,0,0,.1);border-right:1px solid #fff;display:table-cell;padding:.5em;vertical-align:middle;text-align:center;position:relative}.lista-dispositivo ul li .iteminput input,.result-busca-dispositivo ul li .iteminput input{margin:0}.lista-dispositivo ul li .iteminput .flag,.result-busca-dispositivo ul li .iteminput .flag{position:absolute;top:0;left:0;right:0;line-height:1;background-color:#ccc;color:#fff;cursor:default;font-size:80%}.lista-dispositivo ul li .itemlabel,.result-busca-dispositivo ul li .itemlabel{margin:0;background-color:rgba(0,0,0,.1);display:table-cell;padding:.5em;vertical-align:middle;width:100%}.lista-dispositivo ul li .itemlabel .artigo,.result-busca-dispositivo ul li .itemlabel .artigo{float:none}.lista-dispositivo .label-tip-results,.result-busca-dispositivo .label-tip-results{background-color:rgba(0,0,0,.1);padding:0 5px;top:0;z-index:1;line-height:1.3;color:#00f;font-size:.9em}.lista-dispositivo .nomenclatura_heranca,.result-busca-dispositivo .nomenclatura_heranca{font-size:90%;color:#057dba;display:inline}.lista-dispositivo.controls-radio-checkbox{border:0}.label_vigencia{border-top:1px solid #fff;display:inline-block;color:#555}.label_vigencia span{color:grey}.cp-nav-parents .dropdown-menu{left:0;right:auto;padding:0}.cp-nav-parents .dropdown-menu:before{content:"";position:absolute;top:-11px;width:100%;height:11px}.cp-nav-parents:hover .dropdown-menu{display:block}.cp-nav-parents a.active small{color:#fff!important}.table-notificacoes tbody tr td{border-top:1px solid #fff;padding:5px;vertical-align:middle}.table-notificacoes tbody tr td ul{margin:0}.table-notificacoes tbody tr td ul li:hover{background-color:rgba(0,0,0,.1)}.btn-modal-open{float:right}.modal .modal-content .alert:only-child{margin:0}.class_color_container{background:#ddd!important}.clear{clear:both}.mce-tinymce.mce-container{border:1px solid #ccc!important;margin-right:2px}.mce-btn button:hover{background-color:rgba(0,0,0,.1)!important;text-shadow:0 0 5px #fff;-webkit-box-shadow:0 0 5px #777;box-shadow:0 0 5px #777}.mce-menu{background:#eee!important}.displaynone{display:none!important}@media only screen and (max-width:991.98px){.cp .table,.cp table{width:auto!important;white-space:normal;overflow-x:auto!important}}@media only screen and (max-width:800px){.cp .fixed{z-index:98;position:relative}.cp.cpe1 .dpt-selected{margin:1em 0}.cp.cpe1 .dpt-selected .csform .actions_parents,.cp.cpe1 .dpt-selected .csform .label_status{font-size:80%;position:static!important;display:block!important;padding:0;height:auto!important;left:0;right:auto;text-align:left}.cp.cpe1 .dpt-selected .csform .actions_parents div,.cp.cpe1 .dpt-selected .csform .actions_parents li,.cp.cpe1 .dpt-selected .csform .label_status div,.cp.cpe1 .dpt-selected .csform .label_status li{display:inline-block!important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul{-webkit-transform:translateY(30px);transform:translateY(30px);-webkit-transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear,clip 0s .3s;transition:transform .1s linear,opacity .1s linear,clip 0s .3s,-webkit-transform .1s linear;clip:rect(0,0,0,0);opacity:0;position:absolute;margin-left:.5em;-webkit-box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);box-shadow:0 6px 18px rgba(0,0,0,.19),0 2px 6px rgba(0,0,0,.23);-webkit-transition-delay:.4s;transition-delay:.4s}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li a{border-right:0!important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child:before{border-width:.375rem;border-style:inset inset solid;content:"";display:block;height:0;width:0;border-color:transparent transparent #3385ca;position:absolute;top:-.71rem;left:.9375rem}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul li:first-child:hover:before{border-color:transparent transparent #0a5ea4}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>ul:after{content:"";position:absolute;z-index:-1;left:0;top:-25px;height:25px;width:100%;-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li:hover>ul{-webkit-transform:translateY(7px);transform:translateY(7px);-webkit-transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;transition:transform .4s linear,opacity .4s linear,clip 0s .2s;transition:transform .4s linear,opacity .4s linear,clip 0s .2s,-webkit-transform .4s linear;opacity:1;clip:rect(-100px,2000px,2000px,-100px)}.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a span{display:none}.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar{padding-left:0;min-width:1em}.cp.cpe1 .cp.cpe1_old_apagar .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-excluir:before,.cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before,.cp.cpe1_old_apagar .cp.cpe1 .dpt-selected .csform .actions_inserts>li>a.btn-salvar:before{width:100%;margin:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next,.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior{position:static}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul{left:1em!important;right:1em!important;margin-left:0}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_in>ul li:first-child:before{left:37%}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_next>ul{left:0!important;right:1em!important}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul{left:1em!important;right:0!important;margin-left:0;margin-right:.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.add_prior>ul li:first-child:before{right:42%;left:auto}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul{left:10%!important;right:0!important;margin-left:0;margin-right:.5em}.cp.cpe1 .dpt-selected .csform .actions_inserts>li.menu_excluir>ul li:first-child:before{right:0;left:auto}}@media only screen and (max-width:575.98px){.cp .cp-linha-vigencias>li{height:1px}.cp .cp-linha-vigencias>li .circle{width:8px;height:8px;margin:-4px auto 0}.cp .cp-linha-vigencias>li>a{font-size:.75rem}.cp .cp-linha-vigencias>li:nth-child(2n)>a{margin-top:4px}.cp .cp-linha-vigencias>li:nth-child(odd)>a{margin-bottom:4px}.cp .cp-linha-vigencias>li ul a{line-height:1.3rem;font-size:.7rem;background:#fff}.cp .cp-linha-vigencias>li.active .circle{width:14px;height:14px;margin:-7px auto 0}.cp .cp-linha-vigencias>li.active:not(:last-child)>a{margin-bottom:15px}.cp .cp-linha-vigencias>li.active:first-child>a,.cp .cp-linha-vigencias>li.active:last-child>a{margin-bottom:10px}}@media print{.button,.cp-linha-vigencias,.cp .vigencias,.dne,.menu-icon,.tipo-vigencias,.toggle-topbar{display:none!important}#btn_font_mais,#btn_font_menos{display:none}.container{width:100%}}
\ No newline at end of file
diff --git a/sapl/static/sapl/frontend/css/compilacao.eff62463.css.gz b/sapl/static/sapl/frontend/css/compilacao.eff62463.css.gz
new file mode 100644
index 000000000..b251d5e36
Binary files /dev/null and b/sapl/static/sapl/frontend/css/compilacao.eff62463.css.gz differ
diff --git a/sapl/static/sapl/frontend/css/painel.5d957a9b.css.gz b/sapl/static/sapl/frontend/css/painel.5d957a9b.css.gz
deleted file mode 100644
index 419528089..000000000
Binary files a/sapl/static/sapl/frontend/css/painel.5d957a9b.css.gz and /dev/null differ
diff --git a/sapl/static/sapl/frontend/css/painel.5d957a9b.css b/sapl/static/sapl/frontend/css/painel.fd494bea.css
similarity index 77%
rename from sapl/static/sapl/frontend/css/painel.5d957a9b.css
rename to sapl/static/sapl/frontend/css/painel.fd494bea.css
index 765164703..31b25d2cb 100644
--- a/sapl/static/sapl/frontend/css/painel.5d957a9b.css
+++ b/sapl/static/sapl/frontend/css/painel.fd494bea.css
@@ -1 +1 @@
-.painel-principal{background:#1c1b1b;font-family:Verdana;font-size:x-large}.painel-principal .text-title{color:#4fa64d;margin:.5rem;font-weight:700}.painel-principal .text-subtitle{color:#459170;font-weight:700}.painel-principal .data-hora{font-size:180%}.painel-principal .text-value{color:#fff}.painel-principal .logo-painel{max-width:100%}.painel-principal .painels{-ms-flex-wrap:wrap;flex-wrap:wrap}.painel-principal .painel{margin-top:1rem}.painel-principal .painel table{width:100%}.painel-principal .painel h2{margin-bottom:.5rem}.painel-principal .painel #oradores_list,.painel-principal .painel #votacao{text-align:left;display:inline-block;margin-bottom:1rem}
\ No newline at end of file
+.painel-principal{background:#1c1b1b;font-family:Verdana;font-size:x-large}.painel-principal .text-title{color:#4fa64d;margin:.5rem;font-weight:700}.painel-principal .text-subtitle{color:#459170;font-weight:700}.painel-principal .data-hora{font-size:180%}.painel-principal .text-value{color:#fff}.painel-principal .logo-painel{max-width:100%}.painel-principal .painels{-ms-flex-wrap:wrap;flex-wrap:wrap}.painel-principal .painel{margin-top:1rem}.painel-principal .painel table{width:100%}.painel-principal .painel h2{margin-bottom:.5rem}.painel-principal .painel #oradores_list,.painel-principal .painel #votacao{text-align:left;display:inline-block;margin-bottom:1rem}.painel-principal body,.painel-principal html{max-width:100%;overflow-x:hidden}@media screen{.painel-principal li,.painel-principal ul{list-style-type:none}}
\ No newline at end of file
diff --git a/sapl/static/sapl/frontend/css/painel.fd494bea.css.gz b/sapl/static/sapl/frontend/css/painel.fd494bea.css.gz
new file mode 100644
index 000000000..485e8d516
Binary files /dev/null and b/sapl/static/sapl/frontend/css/painel.fd494bea.css.gz differ
diff --git a/sapl/static/sapl/frontend/css/sessao.559521f7.css b/sapl/static/sapl/frontend/css/sessao.559521f7.css
new file mode 100644
index 000000000..95f462d6e
--- /dev/null
+++ b/sapl/static/sapl/frontend/css/sessao.559521f7.css
@@ -0,0 +1 @@
+.current{background:#38b883;background-color:#ff0}.btSelecionado{background-color:#00aeff}
\ No newline at end of file
diff --git a/sapl/static/sapl/frontend/js/chunk-09995afe.a6f4abba.js b/sapl/static/sapl/frontend/js/chunk-09995afe.98f3367d.js
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-09995afe.a6f4abba.js
rename to sapl/static/sapl/frontend/js/chunk-09995afe.98f3367d.js
diff --git a/sapl/static/sapl/frontend/js/chunk-09995afe.a6f4abba.js.gz b/sapl/static/sapl/frontend/js/chunk-09995afe.98f3367d.js.gz
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-09995afe.a6f4abba.js.gz
rename to sapl/static/sapl/frontend/js/chunk-09995afe.98f3367d.js.gz
diff --git a/sapl/static/sapl/frontend/js/chunk-2d0c4a82.75cb4df5.js b/sapl/static/sapl/frontend/js/chunk-2d0c4a82.624674a7.js
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-2d0c4a82.75cb4df5.js
rename to sapl/static/sapl/frontend/js/chunk-2d0c4a82.624674a7.js
diff --git a/sapl/static/sapl/frontend/js/chunk-2d0c4a82.75cb4df5.js.gz b/sapl/static/sapl/frontend/js/chunk-2d0c4a82.624674a7.js.gz
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-2d0c4a82.75cb4df5.js.gz
rename to sapl/static/sapl/frontend/js/chunk-2d0c4a82.624674a7.js.gz
diff --git a/sapl/static/sapl/frontend/js/chunk-2d0e8be2.d53f5a24.js b/sapl/static/sapl/frontend/js/chunk-2d0e8be2.67905a03.js
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-2d0e8be2.d53f5a24.js
rename to sapl/static/sapl/frontend/js/chunk-2d0e8be2.67905a03.js
diff --git a/sapl/static/sapl/frontend/js/chunk-2d0e8be2.d53f5a24.js.gz b/sapl/static/sapl/frontend/js/chunk-2d0e8be2.67905a03.js.gz
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-2d0e8be2.d53f5a24.js.gz
rename to sapl/static/sapl/frontend/js/chunk-2d0e8be2.67905a03.js.gz
diff --git a/sapl/static/sapl/frontend/js/chunk-31d76f93.fb085f5d.js b/sapl/static/sapl/frontend/js/chunk-31d76f93.968a637a.js
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-31d76f93.fb085f5d.js
rename to sapl/static/sapl/frontend/js/chunk-31d76f93.968a637a.js
diff --git a/sapl/static/sapl/frontend/js/chunk-31d76f93.fb085f5d.js.gz b/sapl/static/sapl/frontend/js/chunk-31d76f93.968a637a.js.gz
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-31d76f93.fb085f5d.js.gz
rename to sapl/static/sapl/frontend/js/chunk-31d76f93.968a637a.js.gz
diff --git a/sapl/static/sapl/frontend/js/chunk-681dd124.b923be8d.js b/sapl/static/sapl/frontend/js/chunk-681dd124.08a628b0.js
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-681dd124.b923be8d.js
rename to sapl/static/sapl/frontend/js/chunk-681dd124.08a628b0.js
diff --git a/sapl/static/sapl/frontend/js/chunk-681dd124.b923be8d.js.gz b/sapl/static/sapl/frontend/js/chunk-681dd124.08a628b0.js.gz
similarity index 100%
rename from sapl/static/sapl/frontend/js/chunk-681dd124.b923be8d.js.gz
rename to sapl/static/sapl/frontend/js/chunk-681dd124.08a628b0.js.gz
diff --git a/sapl/static/sapl/frontend/js/chunk-vendors.3ef59900.js.gz b/sapl/static/sapl/frontend/js/chunk-vendors.3ef59900.js.gz
deleted file mode 100644
index 6b00e41fa..000000000
Binary files a/sapl/static/sapl/frontend/js/chunk-vendors.3ef59900.js.gz and /dev/null differ
diff --git a/sapl/static/sapl/frontend/js/chunk-vendors.3ef59900.js b/sapl/static/sapl/frontend/js/chunk-vendors.dfcd310b.js
similarity index 59%
rename from sapl/static/sapl/frontend/js/chunk-vendors.3ef59900.js
rename to sapl/static/sapl/frontend/js/chunk-vendors.dfcd310b.js
index cbe7b3668..3814bd7bb 100644
--- a/sapl/static/sapl/frontend/js/chunk-vendors.3ef59900.js
+++ b/sapl/static/sapl/frontend/js/chunk-vendors.dfcd310b.js
@@ -1,4 +1,4 @@
-(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-vendors"],{"014b":function(t,e,n){"use strict";var r=n("e53d"),i=n("07e3"),o=n("8e60"),a=n("63b6"),s=n("9138"),c=n("ebfd").KEY,l=n("294c"),u=n("dbdb"),f=n("45f2"),d=n("62a0"),h=n("5168"),p=n("ccb9"),m=n("6718"),g=n("47ee"),v=n("9003"),b=n("e4ae"),A=n("f772"),y=n("241e"),w=n("36c3"),x=n("1bc3"),_=n("aebd"),C=n("a159"),E=n("0395"),S=n("bf0b"),O=n("9aa9"),k=n("d9f6"),T=n("c3a1"),D=S.f,B=k.f,P=E.f,I=r.Symbol,j=r.JSON,N=j&&j.stringify,R=h("_hidden"),M=h("toPrimitive"),F={}.propertyIsEnumerable,L=u("symbol-registry"),H=u("symbols"),z=u("op-symbols"),U=Object.prototype,$="function"==typeof I&&!!O.f,Q=r.QObject,V=!Q||!Q.prototype||!Q.prototype.findChild,W=o&&l((function(){return 7!=C(B({},"a",{get:function(){return B(this,"a",{value:7}).a}})).a}))?function(t,e,n){var r=D(U,e);r&&delete U[e],B(t,e,n),r&&t!==U&&B(U,e,r)}:B,Y=function(t){var e=H[t]=C(I.prototype);return e._k=t,e},G=$&&"symbol"==typeof I.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof I},q=function(t,e,n){return t===U&&q(z,e,n),b(t),e=x(e,!0),b(n),i(H,e)?(n.enumerable?(i(t,R)&&t[R][e]&&(t[R][e]=!1),n=C(n,{enumerable:_(0,!1)})):(i(t,R)||B(t,R,_(1,{})),t[R][e]=!0),W(t,e,n)):B(t,e,n)},J=function(t,e){b(t);for(var n,r=g(e=w(e)),i=0,o=r.length;o>i;)q(t,n=r[i++],e[n]);return t},K=function(t){var e=F.call(this,t=x(t,!0));return!(this===U&&i(H,t)&&!i(z,t))&&(!(e||!i(this,t)||!i(H,t)||i(this,R)&&this[R][t])||e)},X=function(t,e){if(t=w(t),e=x(e,!0),t!==U||!i(H,e)||i(z,e)){var n=D(t,e);return!n||!i(H,e)||i(t,R)&&t[R][e]||(n.enumerable=!0),n}},Z=function(t){for(var e,n=P(w(t)),r=[],o=0;n.length>o;)i(H,e=n[o++])||e==R||e==c||r.push(e);return r},tt=function(t){for(var e,n=t===U,r=P(n?z:w(t)),o=[],a=0;r.length>a;)!i(H,e=r[a++])||n&&!i(U,e)||o.push(H[e]);return o};$||(s((I=function(){if(this instanceof I)throw TypeError("Symbol is not a constructor!");var t=d(arguments.length>0?arguments[0]:void 0),e=function(n){this===U&&e.call(z,n),i(this,R)&&i(this[R],t)&&(this[R][t]=!1),W(this,t,_(1,n))};return o&&V&&W(U,t,{configurable:!0,set:e}),Y(t)}).prototype,"toString",(function(){return this._k})),S.f=X,k.f=q,n("6abf").f=E.f=Z,n("355d").f=K,O.f=tt,o&&!n("b8e3")&&s(U,"propertyIsEnumerable",K,!0),p.f=function(t){return Y(h(t))}),a(a.G+a.W+a.F*!$,{Symbol:I});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)h(et[nt++]);for(var rt=T(h.store),it=0;rt.length>it;)m(rt[it++]);a(a.S+a.F*!$,"Symbol",{for:function(t){return i(L,t+="")?L[t]:L[t]=I(t)},keyFor:function(t){if(!G(t))throw TypeError(t+" is not a symbol!");for(var e in L)if(L[e]===t)return e},useSetter:function(){V=!0},useSimple:function(){V=!1}}),a(a.S+a.F*!$,"Object",{create:function(t,e){return void 0===e?C(t):J(C(t),e)},defineProperty:q,defineProperties:J,getOwnPropertyDescriptor:X,getOwnPropertyNames:Z,getOwnPropertySymbols:tt});var ot=l((function(){O.f(1)}));a(a.S+a.F*ot,"Object",{getOwnPropertySymbols:function(t){return O.f(y(t))}}),j&&a(a.S+a.F*(!$||l((function(){var t=I();return"[null]"!=N([t])||"{}"!=N({a:t})||"{}"!=N(Object(t))}))),"JSON",{stringify:function(t){for(var e,n,r=[t],i=1;arguments.length>i;)r.push(arguments[i++]);if(n=e=r[1],(A(e)||void 0!==t)&&!G(t))return v(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!G(e))return e}),r[1]=e,N.apply(j,r)}}),I.prototype[M]||n("35e8")(I.prototype,M,I.prototype.valueOf),f(I,"Symbol"),f(Math,"Math",!0),f(r.JSON,"JSON",!0)},"01f9":function(t,e,n){"use strict";var r=n("2d00"),i=n("5ca1"),o=n("2aba"),a=n("32e9"),s=n("84f2"),c=n("41a0"),l=n("7f20"),u=n("38fd"),f=n("2b4c")("iterator"),d=!([].keys&&"next"in[].keys()),h=function(){return this};t.exports=function(t,e,n,p,m,g,v){c(n,e,p);var b,A,y,w=function(t){if(!d&&t in E)return E[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},x=e+" Iterator",_="values"==m,C=!1,E=t.prototype,S=E[f]||E["@@iterator"]||m&&E[m],O=S||w(m),k=m?_?w("entries"):O:void 0,T="Array"==e&&E.entries||S;if(T&&(y=u(T.call(new t)))!==Object.prototype&&y.next&&(l(y,x,!0),r||"function"==typeof y[f]||a(y,f,h)),_&&S&&"values"!==S.name&&(C=!0,O=function(){return S.call(this)}),r&&!v||!d&&!C&&E[f]||a(E,f,O),s[e]=O,s[x]=h,m)if(b={values:_?O:w("values"),keys:g?O:w("keys"),entries:k},v)for(A in b)A in E||o(E,A,b[A]);else i(i.P+i.F*(d||C),e,b);return b}},"02f4":function(t,e,n){var r=n("4588"),i=n("be13");t.exports=function(t){return function(e,n){var o,a,s=String(i(e)),c=r(n),l=s.length;return c<0||c>=l?t?"":void 0:(o=s.charCodeAt(c))<55296||o>56319||c+1===l||(a=s.charCodeAt(c+1))<56320||a>57343?t?s.charAt(c):o:t?s.slice(c,c+2):a-56320+(o-55296<<10)+65536}}},"0390":function(t,e,n){"use strict";var r=n("02f4")(!0);t.exports=function(t,e,n){return e+(n?r(t,e).length:1)}},"0395":function(t,e,n){var r=n("36c3"),i=n("6abf").f,o={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return a&&"[object Window]"==o.call(t)?function(t){try{return i(t)}catch(t){return a.slice()}}(t):i(r(t))}},"0773":function(t,e,n){},"07d1":function(t,e,n){n("94ce")},"07e3":function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},"097d":function(t,e,n){"use strict";var r=n("5ca1"),i=n("8378"),o=n("7726"),a=n("ebd6"),s=n("bcaa");r(r.P+r.R,"Promise",{finally:function(t){var e=a(this,i.Promise||o.Promise),n="function"==typeof t;return this.then(n?function(n){return s(e,t()).then((function(){return n}))}:t,n?function(n){return s(e,t()).then((function(){throw n}))}:t)}})},"0a06":function(t,e,n){"use strict";var r=n("c532"),i=n("30b5"),o=n("f6b4"),a=n("5270"),s=n("4a7b");function c(t){this.defaults=t,this.interceptors={request:new o,response:new o}}c.prototype.request=function(t){"string"==typeof t?(t=arguments[1]||{}).url=arguments[0]:t=t||{},(t=s(this.defaults,t)).method=t.method?t.method.toLowerCase():"get";var e=[a,void 0],n=Promise.resolve(t);for(this.interceptors.request.forEach((function(t){e.unshift(t.fulfilled,t.rejected)})),this.interceptors.response.forEach((function(t){e.push(t.fulfilled,t.rejected)}));e.length;)n=n.then(e.shift(),e.shift());return n},c.prototype.getUri=function(t){return t=s(this.defaults,t),i(t.url,t.params,t.paramsSerializer).replace(/^\?/,"")},r.forEach(["delete","get","head","options"],(function(t){c.prototype[t]=function(e,n){return this.request(r.merge(n||{},{method:t,url:e}))}})),r.forEach(["post","put","patch"],(function(t){c.prototype[t]=function(e,n,i){return this.request(r.merge(i||{},{method:t,url:e,data:n}))}})),t.exports=c},"0a49":function(t,e,n){var r=n("9b43"),i=n("626a"),o=n("4bf8"),a=n("9def"),s=n("cd1c");t.exports=function(t,e){var n=1==t,c=2==t,l=3==t,u=4==t,f=6==t,d=5==t||f,h=e||s;return function(e,s,p){for(var m,g,v=o(e),b=i(v),A=r(s,p,3),y=a(b.length),w=0,x=n?h(e,y):c?h(e,0):void 0;y>w;w++)if((d||w in b)&&(g=A(m=b[w],w,v),t))if(n)x[w]=g;else if(g)switch(t){case 3:return!0;case 5:return m;case 6:return w;case 2:x.push(m)}else if(u)return!1;return f?-1:l||u?u:x}}},"0ae9":function(t,e,n){var r,i,o;
+(window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-vendors"],{"014b":function(t,e,n){"use strict";var r=n("e53d"),i=n("07e3"),o=n("8e60"),a=n("63b6"),s=n("9138"),c=n("ebfd").KEY,l=n("294c"),u=n("dbdb"),f=n("45f2"),d=n("62a0"),h=n("5168"),p=n("ccb9"),m=n("6718"),g=n("47ee"),v=n("9003"),b=n("e4ae"),y=n("f772"),A=n("241e"),w=n("36c3"),_=n("1bc3"),x=n("aebd"),C=n("a159"),E=n("0395"),S=n("bf0b"),O=n("9aa9"),k=n("d9f6"),T=n("c3a1"),D=S.f,B=k.f,P=E.f,I=r.Symbol,j=r.JSON,N=j&&j.stringify,M=h("_hidden"),R=h("toPrimitive"),F={}.propertyIsEnumerable,L=u("symbol-registry"),H=u("symbols"),z=u("op-symbols"),U=Object.prototype,$="function"==typeof I&&!!O.f,Q=r.QObject,V=!Q||!Q.prototype||!Q.prototype.findChild,W=o&&l((function(){return 7!=C(B({},"a",{get:function(){return B(this,"a",{value:7}).a}})).a}))?function(t,e,n){var r=D(U,e);r&&delete U[e],B(t,e,n),r&&t!==U&&B(U,e,r)}:B,Y=function(t){var e=H[t]=C(I.prototype);return e._k=t,e},G=$&&"symbol"==typeof I.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof I},q=function(t,e,n){return t===U&&q(z,e,n),b(t),e=_(e,!0),b(n),i(H,e)?(n.enumerable?(i(t,M)&&t[M][e]&&(t[M][e]=!1),n=C(n,{enumerable:x(0,!1)})):(i(t,M)||B(t,M,x(1,{})),t[M][e]=!0),W(t,e,n)):B(t,e,n)},J=function(t,e){b(t);for(var n,r=g(e=w(e)),i=0,o=r.length;o>i;)q(t,n=r[i++],e[n]);return t},K=function(t){var e=F.call(this,t=_(t,!0));return!(this===U&&i(H,t)&&!i(z,t))&&(!(e||!i(this,t)||!i(H,t)||i(this,M)&&this[M][t])||e)},X=function(t,e){if(t=w(t),e=_(e,!0),t!==U||!i(H,e)||i(z,e)){var n=D(t,e);return!n||!i(H,e)||i(t,M)&&t[M][e]||(n.enumerable=!0),n}},Z=function(t){for(var e,n=P(w(t)),r=[],o=0;n.length>o;)i(H,e=n[o++])||e==M||e==c||r.push(e);return r},tt=function(t){for(var e,n=t===U,r=P(n?z:w(t)),o=[],a=0;r.length>a;)!i(H,e=r[a++])||n&&!i(U,e)||o.push(H[e]);return o};$||(s((I=function(){if(this instanceof I)throw TypeError("Symbol is not a constructor!");var t=d(arguments.length>0?arguments[0]:void 0),e=function(n){this===U&&e.call(z,n),i(this,M)&&i(this[M],t)&&(this[M][t]=!1),W(this,t,x(1,n))};return o&&V&&W(U,t,{configurable:!0,set:e}),Y(t)}).prototype,"toString",(function(){return this._k})),S.f=X,k.f=q,n("6abf").f=E.f=Z,n("355d").f=K,O.f=tt,o&&!n("b8e3")&&s(U,"propertyIsEnumerable",K,!0),p.f=function(t){return Y(h(t))}),a(a.G+a.W+a.F*!$,{Symbol:I});for(var et="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),nt=0;et.length>nt;)h(et[nt++]);for(var rt=T(h.store),it=0;rt.length>it;)m(rt[it++]);a(a.S+a.F*!$,"Symbol",{for:function(t){return i(L,t+="")?L[t]:L[t]=I(t)},keyFor:function(t){if(!G(t))throw TypeError(t+" is not a symbol!");for(var e in L)if(L[e]===t)return e},useSetter:function(){V=!0},useSimple:function(){V=!1}}),a(a.S+a.F*!$,"Object",{create:function(t,e){return void 0===e?C(t):J(C(t),e)},defineProperty:q,defineProperties:J,getOwnPropertyDescriptor:X,getOwnPropertyNames:Z,getOwnPropertySymbols:tt});var ot=l((function(){O.f(1)}));a(a.S+a.F*ot,"Object",{getOwnPropertySymbols:function(t){return O.f(A(t))}}),j&&a(a.S+a.F*(!$||l((function(){var t=I();return"[null]"!=N([t])||"{}"!=N({a:t})||"{}"!=N(Object(t))}))),"JSON",{stringify:function(t){for(var e,n,r=[t],i=1;arguments.length>i;)r.push(arguments[i++]);if(n=e=r[1],(y(e)||void 0!==t)&&!G(t))return v(e)||(e=function(t,e){if("function"==typeof n&&(e=n.call(this,t,e)),!G(e))return e}),r[1]=e,N.apply(j,r)}}),I.prototype[R]||n("35e8")(I.prototype,R,I.prototype.valueOf),f(I,"Symbol"),f(Math,"Math",!0),f(r.JSON,"JSON",!0)},"01f9":function(t,e,n){"use strict";var r=n("2d00"),i=n("5ca1"),o=n("2aba"),a=n("32e9"),s=n("84f2"),c=n("41a0"),l=n("7f20"),u=n("38fd"),f=n("2b4c")("iterator"),d=!([].keys&&"next"in[].keys()),h=function(){return this};t.exports=function(t,e,n,p,m,g,v){c(n,e,p);var b,y,A,w=function(t){if(!d&&t in E)return E[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},_=e+" Iterator",x="values"==m,C=!1,E=t.prototype,S=E[f]||E["@@iterator"]||m&&E[m],O=S||w(m),k=m?x?w("entries"):O:void 0,T="Array"==e&&E.entries||S;if(T&&(A=u(T.call(new t)))!==Object.prototype&&A.next&&(l(A,_,!0),r||"function"==typeof A[f]||a(A,f,h)),x&&S&&"values"!==S.name&&(C=!0,O=function(){return S.call(this)}),r&&!v||!d&&!C&&E[f]||a(E,f,O),s[e]=O,s[_]=h,m)if(b={values:x?O:w("values"),keys:g?O:w("keys"),entries:k},v)for(y in b)y in E||o(E,y,b[y]);else i(i.P+i.F*(d||C),e,b);return b}},"02f4":function(t,e,n){var r=n("4588"),i=n("be13");t.exports=function(t){return function(e,n){var o,a,s=String(i(e)),c=r(n),l=s.length;return c<0||c>=l?t?"":void 0:(o=s.charCodeAt(c))<55296||o>56319||c+1===l||(a=s.charCodeAt(c+1))<56320||a>57343?t?s.charAt(c):o:t?s.slice(c,c+2):a-56320+(o-55296<<10)+65536}}},"0390":function(t,e,n){"use strict";var r=n("02f4")(!0);t.exports=function(t,e,n){return e+(n?r(t,e).length:1)}},"0395":function(t,e,n){var r=n("36c3"),i=n("6abf").f,o={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];t.exports.f=function(t){return a&&"[object Window]"==o.call(t)?function(t){try{return i(t)}catch(t){return a.slice()}}(t):i(r(t))}},"0773":function(t,e,n){},"07d1":function(t,e,n){n("94ce")},"07e3":function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},"097d":function(t,e,n){"use strict";var r=n("5ca1"),i=n("8378"),o=n("7726"),a=n("ebd6"),s=n("bcaa");r(r.P+r.R,"Promise",{finally:function(t){var e=a(this,i.Promise||o.Promise),n="function"==typeof t;return this.then(n?function(n){return s(e,t()).then((function(){return n}))}:t,n?function(n){return s(e,t()).then((function(){throw n}))}:t)}})},"0a06":function(t,e,n){"use strict";var r=n("c532"),i=n("30b5"),o=n("f6b4"),a=n("5270"),s=n("4a7b");function c(t){this.defaults=t,this.interceptors={request:new o,response:new o}}c.prototype.request=function(t){"string"==typeof t?(t=arguments[1]||{}).url=arguments[0]:t=t||{},(t=s(this.defaults,t)).method=t.method?t.method.toLowerCase():"get";var e=[a,void 0],n=Promise.resolve(t);for(this.interceptors.request.forEach((function(t){e.unshift(t.fulfilled,t.rejected)})),this.interceptors.response.forEach((function(t){e.push(t.fulfilled,t.rejected)}));e.length;)n=n.then(e.shift(),e.shift());return n},c.prototype.getUri=function(t){return t=s(this.defaults,t),i(t.url,t.params,t.paramsSerializer).replace(/^\?/,"")},r.forEach(["delete","get","head","options"],(function(t){c.prototype[t]=function(e,n){return this.request(r.merge(n||{},{method:t,url:e}))}})),r.forEach(["post","put","patch"],(function(t){c.prototype[t]=function(e,n,i){return this.request(r.merge(i||{},{method:t,url:e,data:n}))}})),t.exports=c},"0a49":function(t,e,n){var r=n("9b43"),i=n("626a"),o=n("4bf8"),a=n("9def"),s=n("cd1c");t.exports=function(t,e){var n=1==t,c=2==t,l=3==t,u=4==t,f=6==t,d=5==t||f,h=e||s;return function(e,s,p){for(var m,g,v=o(e),b=i(v),y=r(s,p,3),A=a(b.length),w=0,_=n?h(e,A):c?h(e,0):void 0;A>w;w++)if((d||w in b)&&(g=y(m=b[w],w,v),t))if(n)_[w]=g;else if(g)switch(t){case 3:return!0;case 5:return m;case 6:return w;case 2:_.push(m)}else if(u)return!1;return f?-1:l||u?u:_}}},"0ae9":function(t,e,n){var r,i,o;
/*!
* jQuery UI :data 1.12.1
* http://jqueryui.com
@@ -19,7 +19,7 @@
* https://jquery.org/license
*
* Date: 2019-05-01T21:04Z
- */!function(e,n){"use strict";"object"==typeof t.exports?t.exports=e.document?n(e,!0):function(t){if(!t.document)throw new Error("jQuery requires a window with a document");return n(t)}:n(e)}("undefined"!=typeof window?window:this,(function(n,i){"use strict";var o=[],a=n.document,s=Object.getPrototypeOf,c=o.slice,l=o.concat,u=o.push,f=o.indexOf,d={},h=d.toString,p=d.hasOwnProperty,m=p.toString,g=m.call(Object),v={},b=function(t){return"function"==typeof t&&"number"!=typeof t.nodeType},A=function(t){return null!=t&&t===t.window},y={type:!0,src:!0,nonce:!0,noModule:!0};function w(t,e,n){var r,i,o=(n=n||a).createElement("script");if(o.text=t,e)for(r in y)(i=e[r]||e.getAttribute&&e.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(t){return null==t?t+"":"object"==typeof t||"function"==typeof t?d[h.call(t)]||"object":typeof t}var _=function(t,e){return new _.fn.init(t,e)},C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function E(t){var e=!!t&&"length"in t&&t.length,n=x(t);return!b(t)&&!A(t)&&("array"===n||0===e||"number"==typeof e&&e>0&&e-1 in t)}_.fn=_.prototype={jquery:"3.4.1",constructor:_,length:0,toArray:function(){return c.call(this)},get:function(t){return null==t?c.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=_.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return _.each(this,t)},map:function(t){return this.pushStack(_.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n0&&e-1 in t)}x.fn=x.prototype={jquery:"3.4.1",constructor:x,length:0,toArray:function(){return c.call(this)},get:function(t){return null==t?c.call(this):t<0?this[t+this.length]:this[t]},pushStack:function(t){var e=x.merge(this.constructor(),t);return e.prevObject=this,e},each:function(t){return x.each(this,t)},map:function(t){return this.pushStack(x.map(this,(function(e,n){return t.call(e,n,e)})))},slice:function(){return this.pushStack(c.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(t){var e=this.length,n=+t+(t<0?e:0);return this.pushStack(n>=0&&n+~]|"+M+")"+M+"*"),V=new RegExp(M+"|>"),W=new RegExp(H),Y=new RegExp("^"+F+"$"),G={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),TAG:new RegExp("^("+F+"|[*])"),ATTR:new RegExp("^"+L),PSEUDO:new RegExp("^"+H),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},q=/HTML$/i,J=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,X=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,tt=/[+~]/,et=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),nt=function(t,e,n){var r="0x"+e-65536;return r!=r||n?e:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},rt=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,it=function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t},ot=function(){d()},at=yt((function(t){return!0===t.disabled&&"fieldset"===t.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{I.apply(D=j.call(w.childNodes),w.childNodes),D[w.childNodes.length].nodeType}catch(t){I={apply:D.length?function(t,e){P.apply(t,j.call(e))}:function(t,e){for(var n=t.length,r=0;t[n++]=e[r++];);t.length=n-1}}}function st(t,e,r,i){var o,s,l,u,f,p,v,b=e&&e.ownerDocument,x=e?e.nodeType:9;if(r=r||[],"string"!=typeof t||!t||1!==x&&9!==x&&11!==x)return r;if(!i&&((e?e.ownerDocument||e:w)!==h&&d(e),e=e||h,m)){if(11!==x&&(f=Z.exec(t)))if(o=f[1]){if(9===x){if(!(l=e.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(b&&(l=b.getElementById(o))&&A(e,l)&&l.id===o)return r.push(l),r}else{if(f[2])return I.apply(r,e.getElementsByTagName(t)),r;if((o=f[3])&&n.getElementsByClassName&&e.getElementsByClassName)return I.apply(r,e.getElementsByClassName(o)),r}if(n.qsa&&!O[t+" "]&&(!g||!g.test(t))&&(1!==x||"object"!==e.nodeName.toLowerCase())){if(v=t,b=e,1===x&&V.test(t)){for((u=e.getAttribute("id"))?u=u.replace(rt,it):e.setAttribute("id",u=y),s=(p=a(t)).length;s--;)p[s]="#"+u+" "+At(p[s]);v=p.join(","),b=tt.test(t)&&vt(e.parentNode)||e}try{return I.apply(r,b.querySelectorAll(v)),r}catch(e){O(t,!0)}finally{u===y&&e.removeAttribute("id")}}}return c(t.replace(U,"$1"),e,r,i)}function ct(){var t=[];return function e(n,i){return t.push(n+" ")>r.cacheLength&&delete e[t.shift()],e[n+" "]=i}}function lt(t){return t[y]=!0,t}function ut(t){var e=h.createElement("fieldset");try{return!!t(e)}catch(t){return!1}finally{e.parentNode&&e.parentNode.removeChild(e),e=null}}function ft(t,e){for(var n=t.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=e}function dt(t,e){var n=e&&t,r=n&&1===t.nodeType&&1===e.nodeType&&t.sourceIndex-e.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===e)return-1;return t?1:-1}function ht(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function pt(t){return function(e){var n=e.nodeName.toLowerCase();return("input"===n||"button"===n)&&e.type===t}}function mt(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&at(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function gt(t){return lt((function(e){return e=+e,lt((function(n,r){for(var i,o=t([],n.length,e),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))}))}))}function vt(t){return t&&void 0!==t.getElementsByTagName&&t}for(e in n=st.support={},o=st.isXML=function(t){var e=t.namespaceURI,n=(t.ownerDocument||t).documentElement;return!q.test(e||n&&n.nodeName||"HTML")},d=st.setDocument=function(t){var e,i,a=t?t.ownerDocument||t:w;return a!==h&&9===a.nodeType&&a.documentElement?(p=(h=a).documentElement,m=!o(h),w!==h&&(i=h.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",ot,!1):i.attachEvent&&i.attachEvent("onunload",ot)),n.attributes=ut((function(t){return t.className="i",!t.getAttribute("className")})),n.getElementsByTagName=ut((function(t){return t.appendChild(h.createComment("")),!t.getElementsByTagName("*").length})),n.getElementsByClassName=X.test(h.getElementsByClassName),n.getById=ut((function(t){return p.appendChild(t).id=y,!h.getElementsByName||!h.getElementsByName(y).length})),n.getById?(r.filter.ID=function(t){var e=t.replace(et,nt);return function(t){return t.getAttribute("id")===e}},r.find.ID=function(t,e){if(void 0!==e.getElementById&&m){var n=e.getElementById(t);return n?[n]:[]}}):(r.filter.ID=function(t){var e=t.replace(et,nt);return function(t){var n=void 0!==t.getAttributeNode&&t.getAttributeNode("id");return n&&n.value===e}},r.find.ID=function(t,e){if(void 0!==e.getElementById&&m){var n,r,i,o=e.getElementById(t);if(o){if((n=o.getAttributeNode("id"))&&n.value===t)return[o];for(i=e.getElementsByName(t),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===t)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(t,e){return void 0!==e.getElementsByTagName?e.getElementsByTagName(t):n.qsa?e.querySelectorAll(t):void 0}:function(t,e){var n,r=[],i=0,o=e.getElementsByTagName(t);if("*"===t){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(t,e){if(void 0!==e.getElementsByClassName&&m)return e.getElementsByClassName(t)},v=[],g=[],(n.qsa=X.test(h.querySelectorAll))&&(ut((function(t){p.appendChild(t).innerHTML=" ",t.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+M+"*(?:''|\"\")"),t.querySelectorAll("[selected]").length||g.push("\\["+M+"*(?:value|"+R+")"),t.querySelectorAll("[id~="+y+"-]").length||g.push("~="),t.querySelectorAll(":checked").length||g.push(":checked"),t.querySelectorAll("a#"+y+"+*").length||g.push(".#.+[+~]")})),ut((function(t){t.innerHTML=" ";var e=h.createElement("input");e.setAttribute("type","hidden"),t.appendChild(e).setAttribute("name","D"),t.querySelectorAll("[name=d]").length&&g.push("name"+M+"*[*^$|!~]?="),2!==t.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),p.appendChild(t).disabled=!0,2!==t.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),t.querySelectorAll("*,:x"),g.push(",.*:")}))),(n.matchesSelector=X.test(b=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.oMatchesSelector||p.msMatchesSelector))&&ut((function(t){n.disconnectedMatch=b.call(t,"*"),b.call(t,"[s!='']:x"),v.push("!=",H)})),g=g.length&&new RegExp(g.join("|")),v=v.length&&new RegExp(v.join("|")),e=X.test(p.compareDocumentPosition),A=e||X.test(p.contains)?function(t,e){var n=9===t.nodeType?t.documentElement:t,r=e&&e.parentNode;return t===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):t.compareDocumentPosition&&16&t.compareDocumentPosition(r)))}:function(t,e){if(e)for(;e=e.parentNode;)if(e===t)return!0;return!1},k=e?function(t,e){if(t===e)return f=!0,0;var r=!t.compareDocumentPosition-!e.compareDocumentPosition;return r||(1&(r=(t.ownerDocument||t)===(e.ownerDocument||e)?t.compareDocumentPosition(e):1)||!n.sortDetached&&e.compareDocumentPosition(t)===r?t===h||t.ownerDocument===w&&A(w,t)?-1:e===h||e.ownerDocument===w&&A(w,e)?1:u?N(u,t)-N(u,e):0:4&r?-1:1)}:function(t,e){if(t===e)return f=!0,0;var n,r=0,i=t.parentNode,o=e.parentNode,a=[t],s=[e];if(!i||!o)return t===h?-1:e===h?1:i?-1:o?1:u?N(u,t)-N(u,e):0;if(i===o)return dt(t,e);for(n=t;n=n.parentNode;)a.unshift(n);for(n=e;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?dt(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},h):h},st.matches=function(t,e){return st(t,null,null,e)},st.matchesSelector=function(t,e){if((t.ownerDocument||t)!==h&&d(t),n.matchesSelector&&m&&!O[e+" "]&&(!v||!v.test(e))&&(!g||!g.test(e)))try{var r=b.call(t,e);if(r||n.disconnectedMatch||t.document&&11!==t.document.nodeType)return r}catch(t){O(e,!0)}return st(e,h,null,[t]).length>0},st.contains=function(t,e){return(t.ownerDocument||t)!==h&&d(t),A(t,e)},st.attr=function(t,e){(t.ownerDocument||t)!==h&&d(t);var i=r.attrHandle[e.toLowerCase()],o=i&&T.call(r.attrHandle,e.toLowerCase())?i(t,e,!m):void 0;return void 0!==o?o:n.attributes||!m?t.getAttribute(e):(o=t.getAttributeNode(e))&&o.specified?o.value:null},st.escape=function(t){return(t+"").replace(rt,it)},st.error=function(t){throw new Error("Syntax error, unrecognized expression: "+t)},st.uniqueSort=function(t){var e,r=[],i=0,o=0;if(f=!n.detectDuplicates,u=!n.sortStable&&t.slice(0),t.sort(k),f){for(;e=t[o++];)e===t[o]&&(i=r.push(o));for(;i--;)t.splice(r[i],1)}return u=null,t},i=st.getText=function(t){var e,n="",r=0,o=t.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof t.textContent)return t.textContent;for(t=t.firstChild;t;t=t.nextSibling)n+=i(t)}else if(3===o||4===o)return t.nodeValue}else for(;e=t[r++];)n+=i(e);return n},(r=st.selectors={cacheLength:50,createPseudo:lt,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(t){return t[1]=t[1].replace(et,nt),t[3]=(t[3]||t[4]||t[5]||"").replace(et,nt),"~="===t[2]&&(t[3]=" "+t[3]+" "),t.slice(0,4)},CHILD:function(t){return t[1]=t[1].toLowerCase(),"nth"===t[1].slice(0,3)?(t[3]||st.error(t[0]),t[4]=+(t[4]?t[5]+(t[6]||1):2*("even"===t[3]||"odd"===t[3])),t[5]=+(t[7]+t[8]||"odd"===t[3])):t[3]&&st.error(t[0]),t},PSEUDO:function(t){var e,n=!t[6]&&t[2];return G.CHILD.test(t[0])?null:(t[3]?t[2]=t[4]||t[5]||"":n&&W.test(n)&&(e=a(n,!0))&&(e=n.indexOf(")",n.length-e)-n.length)&&(t[0]=t[0].slice(0,e),t[2]=n.slice(0,e)),t.slice(0,3))}},filter:{TAG:function(t){var e=t.replace(et,nt).toLowerCase();return"*"===t?function(){return!0}:function(t){return t.nodeName&&t.nodeName.toLowerCase()===e}},CLASS:function(t){var e=C[t+" "];return e||(e=new RegExp("(^|"+M+")"+t+"("+M+"|$)"))&&C(t,(function(t){return e.test("string"==typeof t.className&&t.className||void 0!==t.getAttribute&&t.getAttribute("class")||"")}))},ATTR:function(t,e,n){return function(r){var i=st.attr(r,t);return null==i?"!="===e:!e||(i+="","="===e?i===n:"!="===e?i!==n:"^="===e?n&&0===i.indexOf(n):"*="===e?n&&i.indexOf(n)>-1:"$="===e?n&&i.slice(-n.length)===n:"~="===e?(" "+i.replace(z," ")+" ").indexOf(n)>-1:"|="===e&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(t,e,n,r,i){var o="nth"!==t.slice(0,3),a="last"!==t.slice(-4),s="of-type"===e;return 1===r&&0===i?function(t){return!!t.parentNode}:function(e,n,c){var l,u,f,d,h,p,m=o!==a?"nextSibling":"previousSibling",g=e.parentNode,v=s&&e.nodeName.toLowerCase(),b=!c&&!s,A=!1;if(g){if(o){for(;m;){for(d=e;d=d[m];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;p=m="only"===t&&!p&&"nextSibling"}return!0}if(p=[a?g.firstChild:g.lastChild],a&&b){for(A=(h=(l=(u=(f=(d=g)[y]||(d[y]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]||[])[0]===x&&l[1])&&l[2],d=h&&g.childNodes[h];d=++h&&d&&d[m]||(A=h=0)||p.pop();)if(1===d.nodeType&&++A&&d===e){u[t]=[x,h,A];break}}else if(b&&(A=h=(l=(u=(f=(d=e)[y]||(d[y]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]||[])[0]===x&&l[1]),!1===A)for(;(d=++h&&d&&d[m]||(A=h=0)||p.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++A||(b&&((u=(f=d[y]||(d[y]={}))[d.uniqueID]||(f[d.uniqueID]={}))[t]=[x,A]),d!==e)););return(A-=i)===r||A%r==0&&A/r>=0}}},PSEUDO:function(t,e){var n,i=r.pseudos[t]||r.setFilters[t.toLowerCase()]||st.error("unsupported pseudo: "+t);return i[y]?i(e):i.length>1?(n=[t,t,"",e],r.setFilters.hasOwnProperty(t.toLowerCase())?lt((function(t,n){for(var r,o=i(t,e),a=o.length;a--;)t[r=N(t,o[a])]=!(n[r]=o[a])})):function(t){return i(t,0,n)}):i}},pseudos:{not:lt((function(t){var e=[],n=[],r=s(t.replace(U,"$1"));return r[y]?lt((function(t,e,n,i){for(var o,a=r(t,null,i,[]),s=t.length;s--;)(o=a[s])&&(t[s]=!(e[s]=o))})):function(t,i,o){return e[0]=t,r(e,null,o,n),e[0]=null,!n.pop()}})),has:lt((function(t){return function(e){return st(t,e).length>0}})),contains:lt((function(t){return t=t.replace(et,nt),function(e){return(e.textContent||i(e)).indexOf(t)>-1}})),lang:lt((function(t){return Y.test(t||"")||st.error("unsupported lang: "+t),t=t.replace(et,nt).toLowerCase(),function(e){var n;do{if(n=m?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(n=n.toLowerCase())===t||0===n.indexOf(t+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}})),target:function(e){var n=t.location&&t.location.hash;return n&&n.slice(1)===e.id},root:function(t){return t===p},focus:function(t){return t===h.activeElement&&(!h.hasFocus||h.hasFocus())&&!!(t.type||t.href||~t.tabIndex)},enabled:mt(!1),disabled:mt(!0),checked:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&!!t.checked||"option"===e&&!!t.selected},selected:function(t){return t.parentNode&&t.parentNode.selectedIndex,!0===t.selected},empty:function(t){for(t=t.firstChild;t;t=t.nextSibling)if(t.nodeType<6)return!1;return!0},parent:function(t){return!r.pseudos.empty(t)},header:function(t){return K.test(t.nodeName)},input:function(t){return J.test(t.nodeName)},button:function(t){var e=t.nodeName.toLowerCase();return"input"===e&&"button"===t.type||"button"===e},text:function(t){var e;return"input"===t.nodeName.toLowerCase()&&"text"===t.type&&(null==(e=t.getAttribute("type"))||"text"===e.toLowerCase())},first:gt((function(){return[0]})),last:gt((function(t,e){return[e-1]})),eq:gt((function(t,e,n){return[n<0?n+e:n]})),even:gt((function(t,e){for(var n=0;ne?e:n;--r>=0;)t.push(r);return t})),gt:gt((function(t,e,n){for(var r=n<0?n+e:n;++r1?function(e,n,r){for(var i=t.length;i--;)if(!t[i](e,n,r))return!1;return!0}:t[0]}function xt(t,e,n,r,i){for(var o,a=[],s=0,c=t.length,l=null!=e;s-1&&(o[l]=!(a[l]=f))}}else v=xt(v===a?v.splice(p,v.length):v),i?i(null,a,v,c):I.apply(a,v)}))}function Ct(t){for(var e,n,i,o=t.length,a=r.relative[t[0].type],s=a||r.relative[" "],c=a?1:0,u=yt((function(t){return t===e}),s,!0),f=yt((function(t){return N(e,t)>-1}),s,!0),d=[function(t,n,r){var i=!a&&(r||n!==l)||((e=n).nodeType?u(t,n,r):f(t,n,r));return e=null,i}];c1&&wt(d),c>1&&At(t.slice(0,c-1).concat({value:" "===t[c-2].type?"*":""})).replace(U,"$1"),n,c0,i=t.length>0,o=function(o,a,s,c,u){var f,p,g,v=0,b="0",A=o&&[],y=[],w=l,_=o||i&&r.find.TAG("*",u),C=x+=null==w?1:Math.random()||.1,E=_.length;for(u&&(l=a===h||a||u);b!==E&&null!=(f=_[b]);b++){if(i&&f){for(p=0,a||f.ownerDocument===h||(d(f),s=!m);g=t[p++];)if(g(f,a||h,s)){c.push(f);break}u&&(x=C)}n&&((f=!g&&f)&&v--,o&&A.push(f))}if(v+=b,n&&b!==v){for(p=0;g=e[p++];)g(A,y,a,s);if(o){if(v>0)for(;b--;)A[b]||y[b]||(y[b]=B.call(c));y=xt(y)}I.apply(c,y),u&&!o&&y.length>0&&v+e.length>1&&st.uniqueSort(c)}return u&&(x=C,l=w),A};return n?lt(o):o}(o,i))).selector=t}return s},c=st.select=function(t,e,n,i){var o,c,l,u,f,d="function"==typeof t&&t,h=!i&&a(t=d.selector||t);if(n=n||[],1===h.length){if((c=h[0]=h[0].slice(0)).length>2&&"ID"===(l=c[0]).type&&9===e.nodeType&&m&&r.relative[c[1].type]){if(!(e=(r.find.ID(l.matches[0].replace(et,nt),e)||[])[0]))return n;d&&(e=e.parentNode),t=t.slice(c.shift().value.length)}for(o=G.needsContext.test(t)?0:c.length;o--&&(l=c[o],!r.relative[u=l.type]);)if((f=r.find[u])&&(i=f(l.matches[0].replace(et,nt),tt.test(c[0].type)&&vt(e.parentNode)||e))){if(c.splice(o,1),!(t=i.length&&At(c)))return I.apply(n,i),n;break}}return(d||s(t,h))(i,e,!m,n,!e||tt.test(t)&&vt(e.parentNode)||e),n},n.sortStable=y.split("").sort(k).join("")===y,n.detectDuplicates=!!f,d(),n.sortDetached=ut((function(t){return 1&t.compareDocumentPosition(h.createElement("fieldset"))})),ut((function(t){return t.innerHTML=" ","#"===t.firstChild.getAttribute("href")}))||ft("type|href|height|width",(function(t,e,n){if(!n)return t.getAttribute(e,"type"===e.toLowerCase()?1:2)})),n.attributes&&ut((function(t){return t.innerHTML=" ",t.firstChild.setAttribute("value",""),""===t.firstChild.getAttribute("value")}))||ft("value",(function(t,e,n){if(!n&&"input"===t.nodeName.toLowerCase())return t.defaultValue})),ut((function(t){return null==t.getAttribute("disabled")}))||ft(R,(function(t,e,n){var r;if(!n)return!0===t[e]?e.toLowerCase():(r=t.getAttributeNode(e))&&r.specified?r.value:null})),st}(n);_.find=S,_.expr=S.selectors,_.expr[":"]=_.expr.pseudos,_.uniqueSort=_.unique=S.uniqueSort,_.text=S.getText,_.isXMLDoc=S.isXML,_.contains=S.contains,_.escapeSelector=S.escape;var O=function(t,e,n){for(var r=[],i=void 0!==n;(t=t[e])&&9!==t.nodeType;)if(1===t.nodeType){if(i&&_(t).is(n))break;r.push(t)}return r},k=function(t,e){for(var n=[];t;t=t.nextSibling)1===t.nodeType&&t!==e&&n.push(t);return n},T=_.expr.match.needsContext;function D(t,e){return t.nodeName&&t.nodeName.toLowerCase()===e.toLowerCase()}var B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function P(t,e,n){return b(e)?_.grep(t,(function(t,r){return!!e.call(t,r,t)!==n})):e.nodeType?_.grep(t,(function(t){return t===e!==n})):"string"!=typeof e?_.grep(t,(function(t){return f.call(e,t)>-1!==n})):_.filter(e,t,n)}_.filter=function(t,e,n){var r=e[0];return n&&(t=":not("+t+")"),1===e.length&&1===r.nodeType?_.find.matchesSelector(r,t)?[r]:[]:_.find.matches(t,_.grep(e,(function(t){return 1===t.nodeType})))},_.fn.extend({find:function(t){var e,n,r=this.length,i=this;if("string"!=typeof t)return this.pushStack(_(t).filter((function(){for(e=0;e1?_.uniqueSort(n):n},filter:function(t){return this.pushStack(P(this,t||[],!1))},not:function(t){return this.pushStack(P(this,t||[],!0))},is:function(t){return!!P(this,"string"==typeof t&&T.test(t)?_(t):t||[],!1).length}});var I,j=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(_.fn.init=function(t,e,n){var r,i;if(!t)return this;if(n=n||I,"string"==typeof t){if(!(r="<"===t[0]&&">"===t[t.length-1]&&t.length>=3?[null,t,null]:j.exec(t))||!r[1]&&e)return!e||e.jquery?(e||n).find(t):this.constructor(e).find(t);if(r[1]){if(e=e instanceof _?e[0]:e,_.merge(this,_.parseHTML(r[1],e&&e.nodeType?e.ownerDocument||e:a,!0)),B.test(r[1])&&_.isPlainObject(e))for(r in e)b(this[r])?this[r](e[r]):this.attr(r,e[r]);return this}return(i=a.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return t.nodeType?(this[0]=t,this.length=1,this):b(t)?void 0!==n.ready?n.ready(t):t(_):_.makeArray(t,this)}).prototype=_.fn,I=_(a);var N=/^(?:parents|prev(?:Until|All))/,R={children:!0,contents:!0,next:!0,prev:!0};function M(t,e){for(;(t=t[e])&&1!==t.nodeType;);return t}_.fn.extend({has:function(t){var e=_(t,this),n=e.length;return this.filter((function(){for(var t=0;t-1:1===n.nodeType&&_.find.matchesSelector(n,t))){o.push(n);break}return this.pushStack(o.length>1?_.uniqueSort(o):o)},index:function(t){return t?"string"==typeof t?f.call(_(t),this[0]):f.call(this,t.jquery?t[0]:t):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(t,e){return this.pushStack(_.uniqueSort(_.merge(this.get(),_(t,e))))},addBack:function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}}),_.each({parent:function(t){var e=t.parentNode;return e&&11!==e.nodeType?e:null},parents:function(t){return O(t,"parentNode")},parentsUntil:function(t,e,n){return O(t,"parentNode",n)},next:function(t){return M(t,"nextSibling")},prev:function(t){return M(t,"previousSibling")},nextAll:function(t){return O(t,"nextSibling")},prevAll:function(t){return O(t,"previousSibling")},nextUntil:function(t,e,n){return O(t,"nextSibling",n)},prevUntil:function(t,e,n){return O(t,"previousSibling",n)},siblings:function(t){return k((t.parentNode||{}).firstChild,t)},children:function(t){return k(t.firstChild)},contents:function(t){return void 0!==t.contentDocument?t.contentDocument:(D(t,"template")&&(t=t.content||t),_.merge([],t.childNodes))}},(function(t,e){_.fn[t]=function(n,r){var i=_.map(this,e,n);return"Until"!==t.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=_.filter(r,i)),this.length>1&&(R[t]||_.uniqueSort(i),N.test(t)&&i.reverse()),this.pushStack(i)}}));var F=/[^\x20\t\r\n\f]+/g;function L(t){return t}function H(t){throw t}function z(t,e,n,r){var i;try{t&&b(i=t.promise)?i.call(t).done(e).fail(n):t&&b(i=t.then)?i.call(t,e,n):e.apply(void 0,[t].slice(r))}catch(t){n.apply(void 0,[t])}}_.Callbacks=function(t){t="string"==typeof t?function(t){var e={};return _.each(t.match(F)||[],(function(t,n){e[n]=!0})),e}(t):_.extend({},t);var e,n,r,i,o=[],a=[],s=-1,c=function(){for(i=i||t.once,r=e=!0;a.length;s=-1)for(n=a.shift();++s-1;)o.splice(n,1),n<=s&&s--})),this},has:function(t){return t?_.inArray(t,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||e||(o=n=""),this},locked:function(){return!!i},fireWith:function(t,n){return i||(n=[t,(n=n||[]).slice?n.slice():n],a.push(n),e||c()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},_.extend({Deferred:function(t){var e=[["notify","progress",_.Callbacks("memory"),_.Callbacks("memory"),2],["resolve","done",_.Callbacks("once memory"),_.Callbacks("once memory"),0,"resolved"],["reject","fail",_.Callbacks("once memory"),_.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(t){return i.then(null,t)},pipe:function(){var t=arguments;return _.Deferred((function(n){_.each(e,(function(e,r){var i=b(t[r[4]])&&t[r[4]];o[r[1]]((function(){var t=i&&i.apply(this,arguments);t&&b(t.promise)?t.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,i?[t]:arguments)}))})),t=null})).promise()},then:function(t,r,i){var o=0;function a(t,e,r,i){return function(){var s=this,c=arguments,l=function(){var n,l;if(!(t=o&&(r!==H&&(s=void 0,c=[n]),e.rejectWith(s,c))}};t?u():(_.Deferred.getStackHook&&(u.stackTrace=_.Deferred.getStackHook()),n.setTimeout(u))}}return _.Deferred((function(n){e[0][3].add(a(0,n,b(i)?i:L,n.notifyWith)),e[1][3].add(a(0,n,b(t)?t:L)),e[2][3].add(a(0,n,b(r)?r:H))})).promise()},promise:function(t){return null!=t?_.extend(t,i):i}},o={};return _.each(e,(function(t,n){var a=n[2],s=n[5];i[n[1]]=a.add,s&&a.add((function(){r=s}),e[3-t][2].disable,e[3-t][3].disable,e[0][2].lock,e[0][3].lock),a.add(n[3].fire),o[n[0]]=function(){return o[n[0]+"With"](this===o?void 0:this,arguments),this},o[n[0]+"With"]=a.fireWith})),i.promise(o),t&&t.call(o,o),o},when:function(t){var e=arguments.length,n=e,r=Array(n),i=c.call(arguments),o=_.Deferred(),a=function(t){return function(n){r[t]=this,i[t]=arguments.length>1?c.call(arguments):n,--e||o.resolveWith(r,i)}};if(e<=1&&(z(t,o.done(a(n)).resolve,o.reject,!e),"pending"===o.state()||b(i[n]&&i[n].then)))return o.then();for(;n--;)z(i[n],a(n),o.reject);return o.promise()}});var U=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;_.Deferred.exceptionHook=function(t,e){n.console&&n.console.warn&&t&&U.test(t.name)&&n.console.warn("jQuery.Deferred exception: "+t.message,t.stack,e)},_.readyException=function(t){n.setTimeout((function(){throw t}))};var $=_.Deferred();function Q(){a.removeEventListener("DOMContentLoaded",Q),n.removeEventListener("load",Q),_.ready()}_.fn.ready=function(t){return $.then(t).catch((function(t){_.readyException(t)})),this},_.extend({isReady:!1,readyWait:1,ready:function(t){(!0===t?--_.readyWait:_.isReady)||(_.isReady=!0,!0!==t&&--_.readyWait>0||$.resolveWith(a,[_]))}}),_.ready.then=$.then,"complete"===a.readyState||"loading"!==a.readyState&&!a.documentElement.doScroll?n.setTimeout(_.ready):(a.addEventListener("DOMContentLoaded",Q),n.addEventListener("load",Q));var V=function(t,e,n,r,i,o,a){var s=0,c=t.length,l=null==n;if("object"===x(n))for(s in i=!0,n)V(t,e,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,b(r)||(a=!0),l&&(a?(e.call(t,r),e=null):(l=e,e=function(t,e,n){return l.call(_(t),n)})),e))for(;s1,null,!0)},removeData:function(t){return this.each((function(){Z.remove(this,t)}))}}),_.extend({queue:function(t,e,n){var r;if(t)return e=(e||"fx")+"queue",r=X.get(t,e),n&&(!r||Array.isArray(n)?r=X.access(t,e,_.makeArray(n)):r.push(n)),r||[]},dequeue:function(t,e){e=e||"fx";var n=_.queue(t,e),r=n.length,i=n.shift(),o=_._queueHooks(t,e);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===e&&n.unshift("inprogress"),delete o.stop,i.call(t,(function(){_.dequeue(t,e)}),o)),!r&&o&&o.empty.fire()},_queueHooks:function(t,e){var n=e+"queueHooks";return X.get(t,n)||X.access(t,n,{empty:_.Callbacks("once memory").add((function(){X.remove(t,[e+"queue",n])}))})}}),_.fn.extend({queue:function(t,e){var n=2;return"string"!=typeof t&&(e=t,t="fx",n--),arguments.length\x20\t\r\n\f]*)/i,vt=/^$|^module$|\/(?:java|ecma)script/i,bt={option:[1,""," "],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function At(t,e){var n;return n=void 0!==t.getElementsByTagName?t.getElementsByTagName(e||"*"):void 0!==t.querySelectorAll?t.querySelectorAll(e||"*"):[],void 0===e||e&&D(t,e)?_.merge([t],n):n}function yt(t,e){for(var n=0,r=t.length;n-1)i&&i.push(o);else if(l=st(o),a=At(f.appendChild(o),"script"),l&&yt(a),n)for(u=0;o=a[u++];)vt.test(o.type||"")&&n.push(o);return f}wt=a.createDocumentFragment().appendChild(a.createElement("div")),(xt=a.createElement("input")).setAttribute("type","radio"),xt.setAttribute("checked","checked"),xt.setAttribute("name","t"),wt.appendChild(xt),v.checkClone=wt.cloneNode(!0).cloneNode(!0).lastChild.checked,wt.innerHTML="",v.noCloneChecked=!!wt.cloneNode(!0).lastChild.defaultValue;var Et=/^key/,St=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ot=/^([^.]*)(?:\.(.+)|)/;function kt(){return!0}function Tt(){return!1}function Dt(t,e){return t===function(){try{return a.activeElement}catch(t){}}()==("focus"===e)}function Bt(t,e,n,r,i,o){var a,s;if("object"==typeof e){for(s in"string"!=typeof n&&(r=r||n,n=void 0),e)Bt(t,s,n,r,e[s],o);return t}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Tt;else if(!i)return t;return 1===o&&(a=i,(i=function(t){return _().off(t),a.apply(this,arguments)}).guid=a.guid||(a.guid=_.guid++)),t.each((function(){_.event.add(this,e,i,r,n)}))}function Pt(t,e,n){n?(X.set(t,e,!1),_.event.add(t,e,{namespace:!1,handler:function(t){var r,i,o=X.get(this,e);if(1&t.isTrigger&&this[e]){if(o.length)(_.event.special[e]||{}).delegateType&&t.stopPropagation();else if(o=c.call(arguments),X.set(this,e,o),r=n(this,e),this[e](),o!==(i=X.get(this,e))||r?X.set(this,e,!1):i={},o!==i)return t.stopImmediatePropagation(),t.preventDefault(),i.value}else o.length&&(X.set(this,e,{value:_.event.trigger(_.extend(o[0],_.Event.prototype),o.slice(1),this)}),t.stopImmediatePropagation())}})):void 0===X.get(t,e)&&_.event.add(t,e,kt)}_.event={global:{},add:function(t,e,n,r,i){var o,a,s,c,l,u,f,d,h,p,m,g=X.get(t);if(g)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&_.find.matchesSelector(at,i),n.guid||(n.guid=_.guid++),(c=g.events)||(c=g.events={}),(a=g.handle)||(a=g.handle=function(e){return void 0!==_&&_.event.triggered!==e.type?_.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(F)||[""]).length;l--;)h=m=(s=Ot.exec(e[l])||[])[1],p=(s[2]||"").split(".").sort(),h&&(f=_.event.special[h]||{},h=(i?f.delegateType:f.bindType)||h,f=_.event.special[h]||{},u=_.extend({type:h,origType:m,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&_.expr.match.needsContext.test(i),namespace:p.join(".")},o),(d=c[h])||((d=c[h]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,p,a)||t.addEventListener&&t.addEventListener(h,a)),f.add&&(f.add.call(t,u),u.handler.guid||(u.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,u):d.push(u),_.event.global[h]=!0)},remove:function(t,e,n,r,i){var o,a,s,c,l,u,f,d,h,p,m,g=X.hasData(t)&&X.get(t);if(g&&(c=g.events)){for(l=(e=(e||"").match(F)||[""]).length;l--;)if(h=m=(s=Ot.exec(e[l])||[])[1],p=(s[2]||"").split(".").sort(),h){for(f=_.event.special[h]||{},d=c[h=(r?f.delegateType:f.bindType)||h]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=d.length;o--;)u=d[o],!i&&m!==u.origType||n&&n.guid!==u.guid||s&&!s.test(u.namespace)||r&&r!==u.selector&&("**"!==r||!u.selector)||(d.splice(o,1),u.selector&&d.delegateCount--,f.remove&&f.remove.call(t,u));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(t,p,g.handle)||_.removeEvent(t,h,g.handle),delete c[h])}else for(h in c)_.event.remove(t,h+e[l],n,r,!0);_.isEmptyObject(c)&&X.remove(t,"handle events")}},dispatch:function(t){var e,n,r,i,o,a,s=_.event.fix(t),c=new Array(arguments.length),l=(X.get(this,"events")||{})[s.type]||[],u=_.event.special[s.type]||{};for(c[0]=s,e=1;e=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==t.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:_.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,c\x20\t\r\n\f]*)[^>]*)\/>/gi,jt=/
diff --git a/sapl/templates/painel/index.html b/sapl/templates/painel/index.html
index 198dd3e8d..e9f8d53f7 100644
--- a/sapl/templates/painel/index.html
+++ b/sapl/templates/painel/index.html
@@ -15,23 +15,12 @@
{% block head_title %}{% trans 'SAPL - Sistema de Apoio ao Processo Legislativo' %}{% endblock %}
- {% block webpack_loader_css %}
- {% render_chunk_vendors 'css' %}
- {% render_bundle 'global' 'css' %}
- {% render_bundle 'painel' 'css' %}
- {% endblock webpack_loader_css %}
-
-
+ {% block webpack_loader_css %}
+ {% render_chunk_vendors 'css' %}
+ {% render_bundle 'global' 'css' %}
+ {% render_bundle 'painel' 'css' %}
+ {% endblock webpack_loader_css %}
+
@@ -72,12 +61,12 @@
{% if exibicao.parlamentares %}
-
-
{% endif %}
@@ -135,37 +124,90 @@
{% endblock webpack_loader_chunks_js %}
+
+
diff --git a/sapl/templates/protocoloadm/documentoadministrativo_filter.html b/sapl/templates/protocoloadm/documentoadministrativo_filter.html
index bd8c3a9f4..49234e5a6 100644
--- a/sapl/templates/protocoloadm/documentoadministrativo_filter.html
+++ b/sapl/templates/protocoloadm/documentoadministrativo_filter.html
@@ -52,11 +52,11 @@
Status: {{tram.status}}
{% endif %}
- {% define d.documentoacessorioadministrativo_set.all as acess %}
- {% if d.documentoacessorioadministrativo_set.all.exists %}
+ {% define d.documentoacessorioadministrativo_set.all as access %}
+ {% if access.exists %}
Documentos Acessórios:
- {{ d.documentoacessorioadministrativo_set.all.count }}
+ {{ access.count }}
{% endif %}
diff --git a/sapl/templates/relatorios/relatorio_ata.html b/sapl/templates/relatorios/relatorio_ata.html
index b71cc480d..c78e471d7 100644
--- a/sapl/templates/relatorios/relatorio_ata.html
+++ b/sapl/templates/relatorios/relatorio_ata.html
@@ -1,10 +1,7 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load common_tags %}
{% load static %}
-
-
-
-
-
+{% block content %}
Ata Eletrônica da {{sessaoplenaria}}
{% include 'sessao/blocos_ata/identificacao_basica.html' %}
{% include 'sessao/blocos_ata/mesa_diretora.html' %}
@@ -68,5 +65,6 @@
{% endif%}
-
-
\ No newline at end of file
+
+
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_atas.html b/sapl/templates/relatorios/relatorio_atas.html
index b4bd07da8..3e2873b97 100644
--- a/sapl/templates/relatorios/relatorio_atas.html
+++ b/sapl/templates/relatorios/relatorio_atas.html
@@ -1,13 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
-
-
-
-
+{% block content %}
Relatório de Atas das Sessões Plenárias
PERÍODO: {{ periodo }}
@@ -33,4 +29,4 @@
{% else %}
Nenhum sessão com ata foi encontrada!
{% endif %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_audiencia.html b/sapl/templates/relatorios/relatorio_audiencia.html
index 15f374a6b..56178ae7e 100644
--- a/sapl/templates/relatorios/relatorio_audiencia.html
+++ b/sapl/templates/relatorios/relatorio_audiencia.html
@@ -1,14 +1,10 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
-
-
-
-
-
Audiência Pública
+{% block content %}
+
Audiência Pública
{% if object_list|length > 0 %}
@@ -32,4 +28,4 @@
{% else %}
Nenhuma Audiência Pública foi encontrada!
{% endif %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_doc_administrativos.html b/sapl/templates/relatorios/relatorio_doc_administrativos.html
index 7a2b04da1..5ba5b5a80 100644
--- a/sapl/templates/relatorios/relatorio_doc_administrativos.html
+++ b/sapl/templates/relatorios/relatorio_doc_administrativos.html
@@ -1,12 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load crispy_forms_tags staticfiles %}
-
-
-
-
-
+{% block content %}
Documentos Administrativos
{% if documentoadministrativo_list|length %}
Número de documentos: {{numero_res}}
@@ -28,11 +25,11 @@
Status: {{tram.status}}
{% endif %}
- {% define d.documentoacessorioadministrativo_set.all as acess %}
- {% if d.documentoacessorioadministrativo_set.all.exists %}
+ {% define d.documentoacessorioadministrativo_set.all as access %}
+ {% if access.exists %}
Documentos Acessórios:
- {{ d.documentoacessorioadministrativo_set.all.count }}
+ {{ access.count }}
{% endif %}
@@ -46,4 +43,4 @@
{% else %}
Nenhum documento encontrado com essas especificações
{% endif %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_documento_acessorio.html b/sapl/templates/relatorios/relatorio_documento_acessorio.html
index 28c482008..4deb0b513 100644
--- a/sapl/templates/relatorios/relatorio_documento_acessorio.html
+++ b/sapl/templates/relatorios/relatorio_documento_acessorio.html
@@ -1,11 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
-
-
+{% block content %}
Documento Acessorio
@@ -38,4 +36,4 @@
{% else %}
Nenhuma documento encontrado com esses parâmetros.
{% endif %}
-
+{% block content %}
Estatísticas de acesso de normas
PARÂMETROS DE PESQUISA:
@@ -51,4 +47,4 @@
{% endfor %}
{% endif %}
-
- Fim de Prazo de Tramitações
+{% block content %}
+Fim de Prazo de Tramitações
PARÂMETROS DE PESQUISA:
Período: {{ data_tramitacao }}
@@ -43,4 +39,4 @@
{% else %}
Nenhuma matéria encontrada com esses parâmetros.
{% endif %}
-
- Histórico de Tramitações de Matérias Legislativas
+{% block content %}
+Histórico de Tramitações de Matérias Legislativas
PARÂMETROS DE PESQUISA:
@@ -45,4 +41,4 @@
{% else %}
Nenhuma matéria encontrada com esses parâmetros.
{% endif %}
-
- Histórico de Tramitações de Documento Administrativo
+{% block content %}
+Histórico de Tramitações de Documento Administrativo
PARÂMETROS DE PESQUISA:
Período: {{ data_tramitacao }}
@@ -43,4 +39,4 @@
{% else %}
Nenhum documento encontrado com esses parâmetros.
{% endif %}
-
+{% block content %}
Matérias em Tramitação
-
PARÂMETROS DE PESQUISA:
Ano: {{ ano }}
Tipo de matéria: {{ tipo }}
Status atual: {{ tramitacao__status }}
Local atual: {{ tramitacao__unidade_tramitacao_destino }}
-
- {% if object_list|length %}
-
-
-
- QUADRO GERAL
-
- Tipo Matéria
- Quantidade
-
-
-
- {% for key, value in qtdes.items %}
-
- {{key.sigla}} - {{key}}
- {{value}}
+ {% if object_list|length %}
+
+
+
+ QUADRO GERAL
- {% endfor %}
-
-
-
-
-
- {% for materia in object_list %}
-
-
- {% endfor %}
- {% else %}
- Nenhum documento encontrado com essas especificações
- {% endif %}
-
+{% block content %}
Normas por mês
PARÂMETROS DE PESQUISA:
@@ -61,4 +58,4 @@
{% endfor %}
-
+{% block content %}
Normas por vigência
PARÂMETROS DE PESQUISA:
@@ -51,4 +47,4 @@
Estatísticas das normas do ano:
{{quant_vigente}} vigente(s) / {{quant_nao_vigente}} não vigente(s)
-
+{% block content %}
Presença dos parlamentares nas sessões
PARÂMETROS DE PESQUISA:
@@ -57,4 +53,4 @@
{% endif %}
-
+{% block content %}
Reunião de Comissão
{% if object_list|length > 0 %}
@@ -32,4 +28,4 @@
{% else %}
Nenhum reunião foi encontrada!
{% endif %}
-
-
+{% block content %}
+
Informações Básicas
Tipo da Sessão: {{inf_basicas_dic.nom_sessao}}
Abertura: {{inf_basicas_dic.dat_inicio_sessao}} - {{inf_basicas_dic.hr_inicio_sessao}}
@@ -142,7 +135,5 @@
{% endfor %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_estatisticas_acesso_normas.html b/sapl/templates/relatorios/relatorio_estatisticas_acesso_normas.html
index 18abbfde7..06788f4d7 100644
--- a/sapl/templates/relatorios/relatorio_estatisticas_acesso_normas.html
+++ b/sapl/templates/relatorios/relatorio_estatisticas_acesso_normas.html
@@ -1,13 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_fim_prazo_tramitacao.html b/sapl/templates/relatorios/relatorio_fim_prazo_tramitacao.html
index 6120c4290..421e6a745 100644
--- a/sapl/templates/relatorios/relatorio_fim_prazo_tramitacao.html
+++ b/sapl/templates/relatorios/relatorio_fim_prazo_tramitacao.html
@@ -1,14 +1,10 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_historico_tramitacao.html b/sapl/templates/relatorios/relatorio_historico_tramitacao.html
index 0ba42b8fd..a377fc421 100644
--- a/sapl/templates/relatorios/relatorio_historico_tramitacao.html
+++ b/sapl/templates/relatorios/relatorio_historico_tramitacao.html
@@ -1,14 +1,10 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_historico_tramitacao_adm.html b/sapl/templates/relatorios/relatorio_historico_tramitacao_adm.html
index c999f9cf3..4ffde7fb0 100644
--- a/sapl/templates/relatorios/relatorio_historico_tramitacao_adm.html
+++ b/sapl/templates/relatorios/relatorio_historico_tramitacao_adm.html
@@ -1,14 +1,10 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_materias_em_tramitacao.html b/sapl/templates/relatorios/relatorio_materias_em_tramitacao.html
index 3304df5d6..a5fd21521 100644
--- a/sapl/templates/relatorios/relatorio_materias_em_tramitacao.html
+++ b/sapl/templates/relatorios/relatorio_materias_em_tramitacao.html
@@ -1,78 +1,51 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
+
+
+
+ {% for materia_em_tramitacao in object_list %}
+
+ {% endif %}
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_materias_por_ano_autor.html b/sapl/templates/relatorios/relatorio_materias_por_ano_autor.html
index 77749fc95..ab615e38f 100644
--- a/sapl/templates/relatorios/relatorio_materias_por_ano_autor.html
+++ b/sapl/templates/relatorios/relatorio_materias_por_ano_autor.html
@@ -1,12 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
{% endif %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_materias_por_autor.html b/sapl/templates/relatorios/relatorio_materias_por_autor.html
index 2fcfce982..d3e7a9659 100644
--- a/sapl/templates/relatorios/relatorio_materias_por_autor.html
+++ b/sapl/templates/relatorios/relatorio_materias_por_autor.html
@@ -1,12 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
{% endif %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_normas_mes.html b/sapl/templates/relatorios/relatorio_normas_mes.html
index f880370a7..268fc54b0 100644
--- a/sapl/templates/relatorios/relatorio_normas_mes.html
+++ b/sapl/templates/relatorios/relatorio_normas_mes.html
@@ -1,13 +1,10 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_normas_por_autor.html b/sapl/templates/relatorios/relatorio_normas_por_autor.html
index 3a4045003..c2c5f52b6 100644
--- a/sapl/templates/relatorios/relatorio_normas_por_autor.html
+++ b/sapl/templates/relatorios/relatorio_normas_por_autor.html
@@ -1,11 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
{% endif %}
-
\ No newline at end of file
+{% endblock content %}
\ No newline at end of file
diff --git a/sapl/templates/relatorios/relatorio_normas_vigencia.html b/sapl/templates/relatorios/relatorio_normas_vigencia.html
index c470cd970..452f566b7 100644
--- a/sapl/templates/relatorios/relatorio_normas_vigencia.html
+++ b/sapl/templates/relatorios/relatorio_normas_vigencia.html
@@ -1,13 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_presenca_sessao.html b/sapl/templates/relatorios/relatorio_presenca_sessao.html
index 2ccbd4a14..3a40cd801 100644
--- a/sapl/templates/relatorios/relatorio_presenca_sessao.html
+++ b/sapl/templates/relatorios/relatorio_presenca_sessao.html
@@ -1,13 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_reuniao.html b/sapl/templates/relatorios/relatorio_reuniao.html
index 5d665c9fe..6a7cc30dc 100644
--- a/sapl/templates/relatorios/relatorio_reuniao.html
+++ b/sapl/templates/relatorios/relatorio_reuniao.html
@@ -1,13 +1,9 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load i18n %}
{% load common_tags %}
{% load static %}
-
-
\ No newline at end of file
+{% endblock content %}
diff --git a/sapl/templates/relatorios/relatorio_sessao_plenaria.html b/sapl/templates/relatorios/relatorio_sessao_plenaria.html
index 93b593206..fff1b22ce 100644
--- a/sapl/templates/relatorios/relatorio_sessao_plenaria.html
+++ b/sapl/templates/relatorios/relatorio_sessao_plenaria.html
@@ -1,15 +1,8 @@
+{% extends "relatorios/base_relatorio.html" %}
{% load static %}
-
-
-
-
-