Browse Source

Problema links gigantes em ementas pdf e html (#2566)

* Propõe solução para TextFields com sequências longas

* aponta solução para pdf com sequencias longas de texto

* add files frontend - update class force wrap text
pull/2573/head
Leandro Roberto Silva 6 years ago
committed by Edward
parent
commit
dff38f7859
  1. 13
      sapl/base/templatetags/common_tags.py
  2. 1
      sapl/crispy_layout_mixin.py
  3. 29
      sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py
  4. 1
      sapl/static/sapl/css/global.e4ae5421.css
  5. BIN
      sapl/static/sapl/css/global.e4ae5421.css.gz
  6. 1
      sapl/static/sapl/js/compilacao.68b9eb03.js
  7. BIN
      sapl/static/sapl/js/compilacao.68b9eb03.js.gz
  8. 7
      sapl/static/sapl/js/global.eb461386.js
  9. BIN
      sapl/static/sapl/js/global.eb461386.js.gz
  10. 4
      sapl/templates/materia/materialegislativa_filter.html
  11. 7
      sapl/templates/sessao/blocos_resumo/materias_expediente.html
  12. 4
      sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html
  13. 41
      sapl/utils.py
  14. 2
      sapl/webpack-stats.json

13
sapl/base/templatetags/common_tags.py

@ -1,3 +1,6 @@
from _functools import reduce
import re
from django import template from django import template
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -9,7 +12,6 @@ from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import Filiacao from sapl.parlamentares.models import Filiacao
from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO
register = template.Library() register = template.Library()
@ -286,3 +288,12 @@ def render_chunk_vendors(extension=None):
return mark_safe('\n'.join(tags)) return mark_safe('\n'.join(tags))
except: except:
return '' return ''
@register.filter(is_safe=True)
@stringfilter
def dont_break_out(value):
_safe = '<div class="dont-break-out">{}</div>'.format(value)
_safe = mark_safe(_safe)
return _safe

1
sapl/crispy_layout_mixin.py

@ -166,6 +166,7 @@ def get_field_display(obj, fieldname):
value) value)
elif 'TextField' in str_type_from_field: elif 'TextField' in str_type_from_field:
display = value.replace('\n', '<br/>') display = value.replace('\n', '<br/>')
display = '<div class="dont-break-out">{}</div>'.format(display)
else: else:
display = str(value) display = str(value)
return verbose_name, display return verbose_name, display

29
sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py

@ -1,19 +1,18 @@
##parameters=rodape_dic, sessao='', imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores # #parameters=rodape_dic, sessao='', imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores
"""Script para geração do PDF das sessoes plenarias """Script para geração do PDF das sessoes plenarias
Autor: Gustavo Lepri Autor: Gustavo Lepri
Atualizado por Luciano De Fázio - 22/03/2012 Atualizado por Luciano De Fázio - 22/03/2012
versão: 1.0 versão: 1.0
""" """
import time
import os import os
import time
from django.template.defaultfilters import safe from django.template.defaultfilters import safe
from django.utils.html import strip_tags from django.utils.html import strip_tags
from trml2pdf import parseString
from sapl.sessao.models import ResumoOrdenacao from sapl.sessao.models import ResumoOrdenacao
from trml2pdf import parseString
def cabecalho(inf_basicas_dic, imagem): def cabecalho(inf_basicas_dic, imagem):
""" """
@ -124,7 +123,7 @@ def inf_basicas(inf_basicas_dic):
dat_inicio_sessao + ' <b>- </b> ' + hr_inicio_sessao + '</para>\n' dat_inicio_sessao + ' <b>- </b> ' + hr_inicio_sessao + '</para>\n'
tmp += '\t\t<para style="P2" spaceAfter="5"><b>Encerramento: </b> ' + \ tmp += '\t\t<para style="P2" spaceAfter="5"><b>Encerramento: </b> ' + \
dat_fim_sessao + ' <b>- </b> ' + hr_fim_sessao + '</para>\n' dat_fim_sessao + ' <b>- </b> ' + hr_fim_sessao + '</para>\n'
return tmp return tmp
@ -145,7 +144,7 @@ def mesa(lst_mesa):
return tmp return tmp
def presenca(lst_presenca_sessao,lst_ausencia_sessao): def presenca(lst_presenca_sessao, lst_ausencia_sessao):
""" """
""" """
@ -202,14 +201,18 @@ def expediente_materia(lst_expediente_materia):
tmp += '\t\t<para style="P2">\n' tmp += '\t\t<para style="P2">\n'
tmp += '\t\t\t<font color="white"> <br/></font>\n' tmp += '\t\t\t<font color="white"> <br/></font>\n'
tmp += '\t\t</para>\n' tmp += '\t\t</para>\n'
tmp += '<blockTable style="repeater" repeatRows="1">\n' tmp += '<blockTable style="repeater" repeatRows="1" colWidths="3.5cm,11.5cm,3.5cm">>\n'
tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n' tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n'
for expediente_materia in lst_expediente_materia: for expediente_materia in lst_expediente_materia:
tmp += '<tr><td><para style="P3"><b>' + str(expediente_materia['num_ordem']) + '</b> - ' + expediente_materia['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno: </b>' + expediente_materia[ tmp += '<tr><td><para style="P3"><b>' + str(expediente_materia['num_ordem']) + '</b> - ' + expediente_materia['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno: </b>' + expediente_materia[
'des_turno'] + '</para>\n' + '<para style="P3"><b>'+ expediente_materia['num_autores'] + ': </b>' + str(expediente_materia['nom_autor']) + '</para></td>\n' 'des_turno'] + '</para>\n' + '<para style="P3"><b>' + expediente_materia['num_autores'] + ': </b>' + str(expediente_materia['nom_autor']) + '</para></td>\n'
txt_ementa = expediente_materia['txt_ementa'].replace('&', '&amp;') txt_ementa = expediente_materia['txt_ementa'].replace('&', '&amp;')
if len(txt_ementa) > 1000:
txt_ementa = txt_ementa[:1000] + "..." # txt_ementa = dont_break_out(expediente_materia['txt_ementa'])
# if len(txt_ementa) > 800:
# txt_ementa = txt_ementa[:800] + "..."
tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + expediente_materia['ordem_observacao'] + '</para></td>\n' tmp += '<td><para style="P4">' + txt_ementa + '</para>' + '<para style="P4">' + expediente_materia['ordem_observacao'] + '</para></td>\n'
tmp += '<td><para style="P3"><b>' + \ tmp += '<td><para style="P3"><b>' + \
str(expediente_materia['nom_resultado']) + \ str(expediente_materia['nom_resultado']) + \
@ -271,7 +274,7 @@ def votacao(lst_votacao):
tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n' tmp += '<tr><td >Matéria</td><td>Ementa</td><td>Resultado da Votação</td></tr>\n'
for votacao in lst_votacao: for votacao in lst_votacao:
tmp += '<tr><td><para style="P3"><b>' + str(votacao['num_ordem']) + '</b> - ' + votacao['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno:</b> ' + votacao[ tmp += '<tr><td><para style="P3"><b>' + str(votacao['num_ordem']) + '</b> - ' + votacao['id_materia'] + '</para>\n' + '<para style="P3"><b>Turno:</b> ' + votacao[
'des_turno'] + '</para>\n' + '<para style="P3"><b>'+ votacao['num_autores'] +': </b>' + str(votacao['nom_autor']) + '</para></td>\n' 'des_turno'] + '</para>\n' + '<para style="P3"><b>' + votacao['num_autores'] + ': </b>' + str(votacao['nom_autor']) + '</para></td>\n'
txt_ementa = votacao['txt_ementa'].replace('&', '&amp;') txt_ementa = votacao['txt_ementa'].replace('&', '&amp;')
if len(txt_ementa) > 1000: if len(txt_ementa) > 1000:
txt_ementa = txt_ementa[:1000] + "..." txt_ementa = txt_ementa[:1000] + "..."
@ -349,7 +352,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
'cont_mult': '', 'cont_mult': '',
'exp': expedientes(lst_expedientes), 'exp': expedientes(lst_expedientes),
'id_basica': inf_basicas(inf_basicas_dic), 'id_basica': inf_basicas(inf_basicas_dic),
'lista_p': presenca(lst_presenca_sessao,lst_ausencia_sessao), 'lista_p': presenca(lst_presenca_sessao, lst_ausencia_sessao),
'lista_p_o_d': presenca_ordem_dia(lst_presenca_ordem_dia), 'lista_p_o_d': presenca_ordem_dia(lst_presenca_ordem_dia),
'mat_exp': expediente_materia(lst_expediente_materia), 'mat_exp': expediente_materia(lst_expediente_materia),
'mat_o_d': votacao(lst_votacao), 'mat_o_d': votacao(lst_votacao),
@ -375,7 +378,7 @@ def principal(rodape_dic, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao
else: else:
tmp += inf_basicas(inf_basicas_dic) tmp += inf_basicas(inf_basicas_dic)
tmp += mesa(lst_mesa) tmp += mesa(lst_mesa)
tmp += presenca(lst_presenca_sessao,lst_ausencia_sessao) tmp += presenca(lst_presenca_sessao, lst_ausencia_sessao)
tmp += expedientes(lst_expedientes) tmp += expedientes(lst_expedientes)
tmp += expediente_materia(lst_expediente_materia) tmp += expediente_materia(lst_expediente_materia)
tmp += oradores_expediente(lst_oradores_expediente) tmp += oradores_expediente(lst_oradores_expediente)

1
sapl/static/sapl/css/global.e4ae5421.css

File diff suppressed because one or more lines are too long

BIN
sapl/static/sapl/css/global.e4ae5421.css.gz

Binary file not shown.

1
sapl/static/sapl/js/compilacao.68b9eb03.js

File diff suppressed because one or more lines are too long

BIN
sapl/static/sapl/js/compilacao.68b9eb03.js.gz

Binary file not shown.

7
sapl/static/sapl/js/global.eb461386.js

File diff suppressed because one or more lines are too long

BIN
sapl/static/sapl/js/global.eb461386.js.gz

Binary file not shown.

4
sapl/templates/materia/materialegislativa_filter.html

@ -1,6 +1,6 @@
{% extends "crud/detail.html" %} {% extends "crud/detail.html" %}
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags common_tags%}
{% block actions %} {% block actions %}
@ -48,7 +48,7 @@
<td> <td>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}}</strong></a> <strong><a href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}}</strong></a>
</br> </br>
<strong>Ementa:</strong>&nbsp;{{ m.ementa|safe }} <strong>Ementa:</strong>&nbsp;{{ m.ementa|dont_break_out }}
</br> </br>
{% if m.data_apresentacao %} {% if m.data_apresentacao %}
<strong>Apresentação: </strong>{{ m.data_apresentacao }} <strong>Apresentação: </strong>{{ m.data_apresentacao }}

7
sapl/templates/sessao/blocos_resumo/materias_expediente.html

@ -1,3 +1,5 @@
{% load common_tags %}
<fieldset> <fieldset>
<legend>Matérias do Expediente</legend> <legend>Matérias do Expediente</legend>
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
@ -33,7 +35,10 @@
<b>Processo:</b> {{ m.numero_processo }} <b>Processo:</b> {{ m.numero_processo }}
{% endif %} {% endif %}
</td> </td>
<td>{{m.ementa|safe}}<br/>{{m.observacao}}</td> <td>
{{m.ementa|dont_break_out}}<br/>
{{m.observacao|dont_break_out}}
</td>
<td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td> <td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

4
sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html

@ -1,3 +1,5 @@
{% load common_tags %}
<fieldset> <fieldset>
<legend>Matérias da Ordem do Dia</legend> <legend>Matérias da Ordem do Dia</legend>
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
@ -33,7 +35,7 @@
<b>Processo:</b> {{ m.numero_processo }} <b>Processo:</b> {{ m.numero_processo }}
{% endif %} {% endif %}
</td> </td>
<td>{{m.ementa|safe}}</b><br/>{{m.ementa_observacao}}</td> <td>{{m.ementa|dont_break_out}}</b><br/>{{m.observacao|dont_break_out}}</td>
<td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td> <td><b>{{m.resultado}}</b><br/>{{m.resultado_observacao}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

41
sapl/utils.py

@ -6,10 +6,6 @@ import re
from unicodedata import normalize as unicodedata_normalize from unicodedata import normalize as unicodedata_normalize
import unicodedata import unicodedata
from django.core.files.uploadedfile import UploadedFile
from django.forms import BaseForm
from sapl.crispy_layout_mixin import SaplFormHelper
from crispy_forms.layout import HTML, Button from crispy_forms.layout import HTML, Button
from django import forms from django import forms
from django.apps import apps from django.apps import apps
@ -18,11 +14,14 @@ from django.contrib import admin
from django.contrib.contenttypes.fields import (GenericForeignKey, GenericRel, from django.contrib.contenttypes.fields import (GenericForeignKey, GenericRel,
GenericRelation) GenericRelation)
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import UploadedFile
from django.core.mail import get_connection from django.core.mail import get_connection
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.forms import BaseForm
from django.forms.widgets import SplitDateTimeWidget from django.forms.widgets import SplitDateTimeWidget
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import django_filters import django_filters
from easy_thumbnails import source_generators from easy_thumbnails import source_generators
@ -31,9 +30,9 @@ import magic
from reversion_compare.admin import CompareVersionAdmin from reversion_compare.admin import CompareVersionAdmin
from unipath.path import Path from unipath.path import Path
from sapl.crispy_layout_mixin import SaplFormHelper
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
# (26/10/2018): O separador foi mudador de '/' para 'K' # (26/10/2018): O separador foi mudador de '/' para 'K'
# por conta dos leitores de códigos de barra, que trocavam # por conta dos leitores de códigos de barra, que trocavam
# a '/' por '&' ou ';' # a '/' por '&' ou ';'
@ -44,6 +43,24 @@ def pil_image(source, exif_orientation=False, **options):
return source_generators.pil_image(source, exif_orientation, **options) return source_generators.pil_image(source, exif_orientation, **options)
def dont_break_out(value, max_part=50):
_safe = value.split()
def chunkstring(string):
return re.findall('.{%d}' % max_part, string)
def __map(a):
if len(a) <= max_part:
return a
return '<br>' + '<br>'.join(chunkstring(a))
_safe = map(__map, _safe)
_safe = ' '.join(_safe)
_safe = mark_safe(_safe)
return value
def clear_thumbnails_cache(queryset, field): def clear_thumbnails_cache(queryset, field):
for r in queryset: for r in queryset:
@ -84,7 +101,6 @@ autor_label = '''
</div> </div>
''' '''
autor_modal = ''' autor_modal = '''
<div id="modal_autor" title="Selecione o Autor" align="center"> <div id="modal_autor" title="Selecione o Autor" align="center">
<form> <form>
@ -239,6 +255,7 @@ class RangeWidgetOverride(forms.MultiWidget):
class CustomSplitDateTimeWidget(SplitDateTimeWidget): class CustomSplitDateTimeWidget(SplitDateTimeWidget):
def render(self, name, value, attrs=None, renderer=None): def render(self, name, value, attrs=None, renderer=None):
rendered_widgets = [] rendered_widgets = []
for i, x in enumerate(self.widgets): for i, x in enumerate(self.widgets):
@ -260,6 +277,7 @@ def register_all_models_in_admin(module_name, exclude_list=[]):
appname = appname[1] if appname[0] == 'sapl' else appname[0] appname = appname[1] if appname[0] == 'sapl' else appname[0]
app = apps.get_app_config(appname) app = apps.get_app_config(appname)
for model in app.get_models(): for model in app.get_models():
class CustomModelAdmin(CompareVersionAdmin): class CustomModelAdmin(CompareVersionAdmin):
list_display = [f.name for f in model._meta.fields list_display = [f.name for f in model._meta.fields
if f.name != 'id' and f.name not in exclude_list] if f.name != 'id' and f.name not in exclude_list]
@ -311,9 +329,11 @@ YES_NO_CHOICES = [(True, _('Sim')), (False, _('Não'))]
def listify(function): def listify(function):
@wraps(function) @wraps(function)
def f(*args, **kwargs): def f(*args, **kwargs):
return list(function(*args, **kwargs)) return list(function(*args, **kwargs))
return f return f
@ -351,7 +371,6 @@ LISTA_DE_UFS = [
RANGE_ANOS = [(year, year) for year in range(timezone.now().year + 1, RANGE_ANOS = [(year, year) for year in range(timezone.now().year + 1,
1889, -1)] 1889, -1)]
RANGE_MESES = [ RANGE_MESES = [
(1, 'Janeiro'), (1, 'Janeiro'),
(2, 'Fevereiro'), (2, 'Fevereiro'),
@ -431,8 +450,10 @@ def choice_force_optional(callable):
o item opcional '---------' que ChoiceFilter o adiciona, como dito o item opcional '---------' que ChoiceFilter o adiciona, como dito
anteriormente. anteriormente.
""" """
def _func(): def _func():
return [('', '---------')] + callable() return [('', '---------')] + callable()
return _func return _func
@ -508,6 +529,7 @@ def fabrica_validador_de_tipos_de_arquivo(lista, nome):
raise ValidationError(_('Tipo de arquivo não suportado')) raise ValidationError(_('Tipo de arquivo não suportado'))
except FileNotFoundError: except FileNotFoundError:
raise ValidationError(_('Arquivo não encontrado')) raise ValidationError(_('Arquivo não encontrado'))
# o nome é importante para as migrations # o nome é importante para as migrations
restringe_tipos_de_arquivo.__name__ = nome restringe_tipos_de_arquivo.__name__ = nome
return restringe_tipos_de_arquivo return restringe_tipos_de_arquivo
@ -578,6 +600,7 @@ class NormaPesquisaOrderingFilter(django_filters.OrderingFilter):
class FileFieldCheckMixin(BaseForm): class FileFieldCheckMixin(BaseForm):
def _check(self): def _check(self):
cleaned_data = super(FileFieldCheckMixin, self).clean() cleaned_data = super(FileFieldCheckMixin, self).clean()
errors = [] errors = []
@ -626,7 +649,7 @@ class AnoNumeroOrderingFilter(django_filters.OrderingFilter):
return super().filter(qs, _value) return super().filter(qs, _value)
def gerar_hash_arquivo(arquivo, pk, block_size=2**20): def gerar_hash_arquivo(arquivo, pk, block_size=2 ** 20):
md5 = hashlib.md5() md5 = hashlib.md5()
arq = open(arquivo, 'rb') arq = open(arquivo, 'rb')
while True: while True:
@ -727,7 +750,7 @@ def texto_upload_path(instance, filename, subpath='', pk_first=False):
if subpath is None: if subpath is None:
subpath = '_' subpath = '_'
path = str_path %\ path = str_path % \
{ {
'prefix': prefix, 'prefix': prefix,
'model_name': instance._meta.model_name, 'model_name': instance._meta.model_name,

2
sapl/webpack-stats.json

@ -1 +1 @@
{"status":"done","publicPath":"/static/sapl/","chunks":{"chunk-vendors":[{"name":"css/chunk-vendors.3c9fe6b4.css","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css"},{"name":"js/chunk-vendors.0003dc37.js","publicPath":"/static/sapl/js/chunk-vendors.0003dc37.js","path":"../sapl/sapl/static/sapl/js/chunk-vendors.0003dc37.js"},{"name":"css/chunk-vendors.3c9fe6b4.css.map","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css.map","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css.map"}],"compilacao":[{"name":"css/compilacao.3372b760.css","publicPath":"/static/sapl/css/compilacao.3372b760.css","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css"},{"name":"js/compilacao.68b9eb03.js","publicPath":"/static/sapl/js/compilacao.68b9eb03.js","path":"../sapl/sapl/static/sapl/js/compilacao.68b9eb03.js"},{"name":"css/compilacao.3372b760.css.map","publicPath":"/static/sapl/css/compilacao.3372b760.css.map","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css.map"}],"global":[{"name":"css/global.e4ae5421.css","publicPath":"/static/sapl/css/global.e4ae5421.css","path":"../sapl/sapl/static/sapl/css/global.e4ae5421.css"},{"name":"js/global.eb461386.js","publicPath":"/static/sapl/js/global.eb461386.js","path":"../sapl/sapl/static/sapl/js/global.eb461386.js"},{"name":"css/global.e4ae5421.css.map","publicPath":"/static/sapl/css/global.e4ae5421.css.map","path":"../sapl/sapl/static/sapl/css/global.e4ae5421.css.map"}],"painel":[{"name":"css/painel.baa845ab.css","publicPath":"/static/sapl/css/painel.baa845ab.css","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css"},{"name":"js/painel.f4adb91b.js","publicPath":"/static/sapl/js/painel.f4adb91b.js","path":"../sapl/sapl/static/sapl/js/painel.f4adb91b.js"},{"name":"css/painel.baa845ab.css.map","publicPath":"/static/sapl/css/painel.baa845ab.css.map","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css.map"}]}} {"status":"done","publicPath":"/static/sapl/","chunks":{"chunk-vendors":[{"name":"css/chunk-vendors.3c9fe6b4.css","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css"},{"name":"js/chunk-vendors.0003dc37.js","publicPath":"/static/sapl/js/chunk-vendors.0003dc37.js","path":"../sapl/sapl/static/sapl/js/chunk-vendors.0003dc37.js"},{"name":"css/chunk-vendors.3c9fe6b4.css.map","publicPath":"/static/sapl/css/chunk-vendors.3c9fe6b4.css.map","path":"../sapl/sapl/static/sapl/css/chunk-vendors.3c9fe6b4.css.map"}],"compilacao":[{"name":"css/compilacao.3372b760.css","publicPath":"/static/sapl/css/compilacao.3372b760.css","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css"},{"name":"js/compilacao.c9cbd558.js","publicPath":"/static/sapl/js/compilacao.c9cbd558.js","path":"../sapl/sapl/static/sapl/js/compilacao.c9cbd558.js"},{"name":"css/compilacao.3372b760.css.map","publicPath":"/static/sapl/css/compilacao.3372b760.css.map","path":"../sapl/sapl/static/sapl/css/compilacao.3372b760.css.map"}],"global":[{"name":"css/global.f7113e2c.css","publicPath":"/static/sapl/css/global.f7113e2c.css","path":"../sapl/sapl/static/sapl/css/global.f7113e2c.css"},{"name":"js/global.2b34f8ff.js","publicPath":"/static/sapl/js/global.2b34f8ff.js","path":"../sapl/sapl/static/sapl/js/global.2b34f8ff.js"},{"name":"css/global.f7113e2c.css.map","publicPath":"/static/sapl/css/global.f7113e2c.css.map","path":"../sapl/sapl/static/sapl/css/global.f7113e2c.css.map"}],"painel":[{"name":"css/painel.baa845ab.css","publicPath":"/static/sapl/css/painel.baa845ab.css","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css"},{"name":"js/painel.f4adb91b.js","publicPath":"/static/sapl/js/painel.f4adb91b.js","path":"../sapl/sapl/static/sapl/js/painel.f4adb91b.js"},{"name":"css/painel.baa845ab.css.map","publicPath":"/static/sapl/css/painel.baa845ab.css.map","path":"../sapl/sapl/static/sapl/css/painel.baa845ab.css.map"}]}}
Loading…
Cancel
Save