Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
Dishly
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
2
Issues
2
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
O Bar da Lora
Dishly
Commits
9ac9484c
Commit
9ac9484c
authored
Jun 10, 2026
by
Natã Frederico Sangalletti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
App.py finalmente legivel
parent
14de57e3
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
412 additions
and
356 deletions
+412
-356
README.md
README.md
+0
-0
app.py
app.py
+68
-0
app.py
app/app.py
+0
-54
user-solid.png
static/img/user-solid.png
+0
-0
style.css
static/style.css
+336
-0
index.html
templates/index.html
+8
-302
No files found.
README.md
deleted
100644 → 0
View file @
14de57e3
app.py
0 → 100644
View file @
9ac9484c
import
os
from
flask
import
Flask
,
redirect
,
render_template
,
request
,
url_for
from
flask_sqlalchemy
import
SQLAlchemy
# Como o app.py está na raiz, o Flask encontra as pastas 'templates' e 'static' automaticamente
app
=
Flask
(
__name__
)
# Configuração do Banco de Dados na pasta 'instance'
# O 'app.instance_path' vai apontar automaticamente para 'meu_projeto/instance/'
app
.
config
[
"SQLALCHEMY_DATABASE_URI"
]
=
"sqlite:///"
+
os
.
path
.
join
(
app
.
instance_path
,
"database.db"
)
app
.
config
[
"SQLALCHEMY_TRACK_MODIFICATIONS"
]
=
False
db
=
SQLAlchemy
(
app
)
# Modelo da Tabela
class
Receita
(
db
.
Model
):
id
=
db
.
Column
(
db
.
Integer
,
primary_key
=
True
)
nome
=
db
.
Column
(
db
.
String
(
100
),
nullable
=
False
)
@app.route
(
"/"
)
def
index
():
receitas
=
Receita
.
query
.
all
()
return
render_template
(
"index.html"
,
receitas
=
receitas
)
@app.route
(
"/cadastro"
,
methods
=
[
"GET"
,
"POST"
])
def
cadastro
():
if
request
.
method
==
"POST"
:
nova
=
Receita
(
nome
=
request
.
form
[
"nome"
])
db
.
session
.
add
(
nova
)
db
.
session
.
commit
()
return
redirect
(
url_for
(
"index"
))
return
render_template
(
"cadastro.html"
)
@app.route
(
"/editar/<int:id>"
,
methods
=
[
"GET"
,
"POST"
])
def
editar
(
id
):
receita
=
Receita
.
query
.
get_or_404
(
id
)
if
request
.
method
==
"POST"
:
receita
.
nome
=
request
.
form
[
"nome"
]
db
.
session
.
commit
()
return
redirect
(
url_for
(
"index"
))
return
render_template
(
"editar.html"
,
receita
=
receita
)
@app.route
(
"/excluir/<int:id>"
)
def
excluir
(
id
):
receita
=
Receita
.
query
.
get_or_404
(
id
)
db
.
session
.
delete
(
receita
)
db
.
session
.
commit
()
return
redirect
(
url_for
(
"index"
))
@app.route
(
"/templates/perfil"
)
def
acessoPerfil
():
return
render_template
(
"perfil.html"
)
if
__name__
==
"__main__"
:
# Garante que a pasta 'instance' seja criada na raiz antes de iniciar o banco
os
.
makedirs
(
app
.
instance_path
,
exist_ok
=
True
)
with
app
.
app_context
():
db
.
create_all
()
app
.
run
(
debug
=
True
)
\ No newline at end of file
app/app.py
deleted
100644 → 0
View file @
14de57e3
from
flask
import
Flask
,
render_template
,
request
,
redirect
,
url_for
from
flask_sqlalchemy
import
SQLAlchemy
import
os
app
=
Flask
(
__name__
,
template_folder
=
'../templates'
)
# Caminho do banco de dados
basedir
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
app
.
config
[
'SQLALCHEMY_DATABASE_URI'
]
=
'sqlite:///'
+
os
.
path
.
join
(
basedir
,
'database.db'
)
db
=
SQLAlchemy
(
app
)
# Modelo da Tabela
class
Receita
(
db
.
Model
):
id
=
db
.
Column
(
db
.
Integer
,
primary_key
=
True
)
nome
=
db
.
Column
(
db
.
String
(
100
),
nullable
=
False
)
@app.route
(
'/'
)
def
index
():
receitas
=
Receita
.
query
.
all
()
return
render_template
(
'index.html'
,
receitas
=
receitas
)
@app.route
(
'/cadastro'
,
methods
=
[
'GET'
,
'POST'
])
def
cadastro
():
if
request
.
method
==
'POST'
:
nova
=
Receita
(
nome
=
request
.
form
[
'nome'
]
)
db
.
session
.
add
(
nova
)
db
.
session
.
commit
()
return
redirect
(
url_for
(
'index'
))
return
render_template
(
'cadastro.html'
)
@app.route
(
'/editar/<int:id>'
,
methods
=
[
'GET'
,
'POST'
])
def
editar
(
id
):
receita
=
Receita
.
query
.
get_or_404
(
id
)
if
request
.
method
==
'POST'
:
receita
.
nome
=
request
.
form
[
'nome'
]
db
.
session
.
commit
()
return
redirect
(
url_for
(
'index'
))
return
render_template
(
'editar.html'
,
receita
=
receita
)
@app.route
(
'/excluir/<int:id>'
)
def
excluir
(
id
):
receita
=
Receita
.
query
.
get_or_404
(
id
)
db
.
session
.
delete
(
receita
)
db
.
session
.
commit
()
return
redirect
(
url_for
(
'index'
))
if
__name__
==
'__main__'
:
with
app
.
app_context
():
db
.
create_all
()
app
.
run
(
host
=
'10.35.124.137'
,
port
=
8080
,
debug
=
True
)
\ No newline at end of file
img/user-solid.png
→
static/
img/user-solid.png
View file @
9ac9484c
File moved
static/style.css
View file @
9ac9484c
*,
*
::before
,
*
::after
{
box-sizing
:
border-box
;
margin
:
0
;
padding
:
0
;
}
body
{
font-family
:
"Segoe UI"
,
system-ui
,
sans-serif
;
background-color
:
#f9f9f9
;
color
:
#111
;
}
/* Acessibilidade de foco geral */
:focus-visible
{
outline
:
2px
solid
#e60023
;
outline-offset
:
2px
;
}
/* ── Header ── */
.header
{
position
:
sticky
;
top
:
0
;
z-index
:
100
;
background
:
#fff
;
border-bottom
:
1px
solid
#e8e8e8
;
padding
:
12px
24px
;
display
:
flex
;
align-items
:
center
;
gap
:
16px
;
}
.header__logo
{
font-size
:
22px
;
font-weight
:
700
;
color
:
#e60023
;
text-decoration
:
none
;
flex-shrink
:
0
;
}
.header__search
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
background
:
#efefef
;
border-radius
:
24px
;
padding
:
0
16px
;
gap
:
8px
;
max-width
:
600px
;
}
.header__search
svg
{
flex-shrink
:
0
;
color
:
#767676
;
}
.header__search
input
{
border
:
none
;
background
:
transparent
;
outline
:
none
;
font-size
:
15px
;
width
:
100%
;
padding
:
10px
0
;
color
:
#111
;
}
.header__search
input
::placeholder
{
color
:
#767676
;
}
.header__search-btn
{
display
:
none
;
/* busca acontece inline */
}
/* ── Categorias (Nav) ── */
.nav
{
background
:
#fff
;
padding
:
8px
24px
12px
;
display
:
flex
;
gap
:
8px
;
overflow-x
:
auto
;
scrollbar-width
:
none
;
border-bottom
:
1px
solid
#e8e8e8
;
}
.nav
::-webkit-scrollbar
{
display
:
none
;
}
.nav
a
{
flex-shrink
:
0
;
text-decoration
:
none
;
font-size
:
14px
;
font-weight
:
600
;
padding
:
8px
16px
;
border-radius
:
20px
;
background
:
#efefef
;
color
:
#111
;
transition
:
background
0.2s
ease
,
color
0.2s
ease
;
}
.nav
a
:hover
{
background
:
#e60023
;
color
:
#fff
;
}
.nav
a
.active
{
background
:
#111
;
color
:
#fff
;
}
/* ── Feed (grid masonry) ── */
.feed
{
padding
:
20px
16px
80px
;
columns
:
5
180px
;
/* cria a grade tipo Pinterest */
column-gap
:
12px
;
}
/* ── Cartão ── */
.card
{
break-inside
:
avoid
;
margin-bottom
:
12px
;
border-radius
:
16px
;
overflow
:
hidden
;
background
:
#fff
;
cursor
:
pointer
;
transition
:
transform
0.2s
ease
,
box-shadow
0.2s
ease
;
position
:
relative
;
}
.card
:hover
{
transform
:
scale
(
1.02
);
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.1
);
}
/* Placeholder de imagem com altura aleatória */
.card__img
{
width
:
100%
;
background
:
#e0e0e0
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.card
:nth-child
(
3n
+
1
)
.card__img
{
height
:
200px
;
}
.card
:nth-child
(
3n
+
2
)
.card__img
{
height
:
280px
;
}
.card
:nth-child
(
3n
)
.card__img
{
height
:
240px
;
}
.card__img
svg
{
opacity
:
0.35
;
}
/* overlay de ações aparece no hover */
.card__overlay
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
border-radius
:
16px
;
background
:
rgba
(
0
,
0
,
0
,
0.2
);
/* Leve escurecimento opcional */
opacity
:
0
;
transition
:
opacity
0.2s
ease
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
padding
:
12px
;
}
.card
:hover
.card__overlay
,
.card
:focus-within
.card__overlay
{
opacity
:
1
;
}
.card__overlay-top
{
display
:
flex
;
justify-content
:
flex-end
;
}
.btn-salvar
{
background
:
#e60023
;
color
:
#fff
;
border
:
none
;
border-radius
:
20px
;
padding
:
8px
16px
;
font-size
:
14px
;
font-weight
:
700
;
cursor
:
pointer
;
transition
:
background
0.2s
ease
;
}
.btn-salvar
:hover
{
background
:
#ad081b
;
}
.card__overlay-bottom
{
display
:
flex
;
gap
:
6px
;
align-items
:
center
;
}
.btn-editar
{
text-decoration
:
none
;
background
:
rgba
(
255
,
255
,
255
,
0.9
);
color
:
#111
;
border-radius
:
20px
;
padding
:
6px
14px
;
font-size
:
13px
;
font-weight
:
600
;
margin-left
:
auto
;
/* Melhor que 10rem fixo, adapta a qualquer largura */
transition
:
background
0.2s
ease
;
}
.btn-editar
:hover
{
background
:
#fff
;
}
/* Informações do cartão */
.card__info
{
padding
:
10px
12px
14px
;
}
.card__title
{
font-size
:
14px
;
font-weight
:
600
;
color
:
#111
;
line-height
:
1.4
;
}
/* ── FAB (botão +) ── */
.fab
{
position
:
fixed
;
bottom
:
32px
;
/* Subi um pouco para alinhar melhor visualmente */
right
:
32px
;
width
:
60px
;
/* Um pouquinho maior para dar presença */
height
:
60px
;
border-radius
:
50%
;
background
:
linear-gradient
(
135deg
,
#ff1a3c
,
#e60023
);
/* Degradê sutil para dar volume */
color
:
#ffffff
;
border
:
none
;
cursor
:
pointer
;
z-index
:
1000
;
/* Garante que fica por cima de tudo */
/* Centralização moderna */
display
:
inline-flex
;
align-items
:
center
;
justify-content
:
center
;
/* Sombra suave e realista (estilo Material Design moderno) */
box-shadow
:
0
8px
24px
rgba
(
230
,
0
,
35
,
0.25
),
0
4px
12px
rgba
(
0
,
0
,
0
,
0.15
);
/* Transição robusta usando 'will-change' para alta performance */
will-change
:
transform
,
box-shadow
;
transition
:
transform
0.3s
cubic-bezier
(
0.34
,
1.56
,
0.64
,
1
),
box-shadow
0.3s
ease
,
filter
0.3s
ease
;
}
/* Efeito de passar o mouse (Hover) */
.fab
:hover
{
transform
:
translateY
(
-4px
)
scale
(
1.05
);
/* Sobe de leve e cresce com efeito mola */
filter
:
brightness
(
1.1
);
/* Ilumina o botão em vez de trocar para uma cor estática sem graça */
box-shadow
:
0
12px
32px
rgba
(
230
,
0
,
35
,
0.4
),
0
6px
16px
rgba
(
0
,
0
,
0
,
0.2
);
}
/* Efeito de clique (Active) - Essencial para o mobile! */
.fab
:active
{
transform
:
translateY
(
-1px
)
scale
(
0.98
);
/* Dá a sensação física de que o botão foi pressionado */
box-shadow
:
0
4px
12px
rgba
(
230
,
0
,
35
,
0.3
);
transition
:
transform
0.1s
ease
;
/* Resposta ao clique instantânea */
}
/* Garante que o ícone dentro dele (seja SVG ou Font Icon) fique perfeito */
.fab
i
,
.fab
svg
{
font-size
:
24px
;
width
:
24px
;
height
:
24px
;
transition
:
transform
0.3s
ease
;
}
/* Bônus: Gira o ícone de leve no hover se você quiser um charme extra */
.fab
:hover
i
,
.fab
:hover
svg
{
transform
:
rotate
(
15deg
);
}
/* ── Footer ── */
footer
{
background
:
#fff
;
border-top
:
1px
solid
#e8e8e8
;
text-align
:
center
;
padding
:
16px
;
font-size
:
13px
;
color
:
#767676
;
position
:
fixed
;
bottom
:
0
;
width
:
100%
;
z-index
:
10
;
/* Garante que o footer fique acima do feed */
}
/* ── Responsividade ── */
@media
(
max-width
:
600px
)
{
.feed
{
columns
:
2
140px
;
}
.header__logo
{
font-size
:
18px
;
}
.fab
{
bottom
:
70px
;
/* Ajuste fino para mobile caso o footer seja maior */
right
:
16px
;
}
}
\ No newline at end of file
templates/index.html
View file @
9ac9484c
...
@@ -4,313 +4,15 @@
...
@@ -4,313 +4,15 @@
<meta
charset=
"UTF-8"
/>
<meta
charset=
"UTF-8"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<link
rel=
"stylesheet"
href=
"/static/style.css"
/>
<link
rel=
"stylesheet"
href=
"/static/style.css"
/>
<link
href=
"https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
rel=
"stylesheet"
integrity=
"sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin=
"anonymous"
>
<title>
Dishly — Feed
</title>
<title>
Dishly — Feed
</title>
<style>
/* ── Reset & Base ── */
*,
*
::before
,
*
::after
{
box-sizing
:
border-box
;
margin
:
0
;
padding
:
0
;
}
body
{
font-family
:
"Segoe UI"
,
system-ui
,
sans-serif
;
background-color
:
#f9f9f9
;
color
:
#111
;
}
/* Acessibilidade de foco geral */
:focus-visible
{
outline
:
2px
solid
#e60023
;
outline-offset
:
2px
;
}
/* ── Header ── */
.header
{
position
:
sticky
;
top
:
0
;
z-index
:
100
;
background
:
#fff
;
border-bottom
:
1px
solid
#e8e8e8
;
padding
:
12px
24px
;
display
:
flex
;
align-items
:
center
;
gap
:
16px
;
}
.header__logo
{
font-size
:
22px
;
font-weight
:
700
;
color
:
#e60023
;
text-decoration
:
none
;
flex-shrink
:
0
;
}
.header__search
{
flex
:
1
;
display
:
flex
;
align-items
:
center
;
background
:
#efefef
;
border-radius
:
24px
;
padding
:
0
16px
;
gap
:
8px
;
max-width
:
600px
;
}
.header__search
svg
{
flex-shrink
:
0
;
color
:
#767676
;
}
.header__search
input
{
border
:
none
;
background
:
transparent
;
outline
:
none
;
font-size
:
15px
;
width
:
100%
;
padding
:
10px
0
;
color
:
#111
;
}
.header__search
input
::placeholder
{
color
:
#767676
;
}
.header__search-btn
{
display
:
none
;
/* busca acontece inline */
}
/* ── Categorias (Nav) ── */
.nav
{
background
:
#fff
;
padding
:
8px
24px
12px
;
display
:
flex
;
gap
:
8px
;
overflow-x
:
auto
;
scrollbar-width
:
none
;
border-bottom
:
1px
solid
#e8e8e8
;
}
.nav
::-webkit-scrollbar
{
display
:
none
;
}
.nav
a
{
flex-shrink
:
0
;
text-decoration
:
none
;
font-size
:
14px
;
font-weight
:
600
;
padding
:
8px
16px
;
border-radius
:
20px
;
background
:
#efefef
;
color
:
#111
;
transition
:
background
0.2s
ease
,
color
0.2s
ease
;
}
.nav
a
:hover
{
background
:
#e60023
;
color
:
#fff
;
}
.nav
a
.active
{
background
:
#111
;
color
:
#fff
;
}
/* ── Feed (grid masonry) ── */
.feed
{
padding
:
20px
16px
80px
;
columns
:
5
180px
;
/* cria a grade tipo Pinterest */
column-gap
:
12px
;
}
/* ── Cartão ── */
.card
{
break-inside
:
avoid
;
margin-bottom
:
12px
;
border-radius
:
16px
;
overflow
:
hidden
;
background
:
#fff
;
cursor
:
pointer
;
transition
:
transform
0.2s
ease
,
box-shadow
0.2s
ease
;
position
:
relative
;
}
.card
:hover
{
transform
:
scale
(
1.02
);
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.1
);
}
/* Placeholder de imagem com altura aleatória */
.card__img
{
width
:
100%
;
background
:
#e0e0e0
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.card
:nth-child
(
3n
+
1
)
.card__img
{
height
:
200px
;
}
.card
:nth-child
(
3n
+
2
)
.card__img
{
height
:
280px
;
}
.card
:nth-child
(
3n
)
.card__img
{
height
:
240px
;
}
.card__img
svg
{
opacity
:
0.35
;
}
/* overlay de ações aparece no hover */
.card__overlay
{
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
border-radius
:
16px
;
background
:
rgba
(
0
,
0
,
0
,
0.2
);
/* Leve escurecimento opcional */
opacity
:
0
;
transition
:
opacity
0.2s
ease
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
padding
:
12px
;
}
.card
:hover
.card__overlay
,
.card
:focus-within
.card__overlay
{
opacity
:
1
;
}
.card__overlay-top
{
display
:
flex
;
justify-content
:
flex-end
;
}
.btn-salvar
{
background
:
#e60023
;
color
:
#fff
;
border
:
none
;
border-radius
:
20px
;
padding
:
8px
16px
;
font-size
:
14px
;
font-weight
:
700
;
cursor
:
pointer
;
transition
:
background
0.2s
ease
;
}
.btn-salvar
:hover
{
background
:
#ad081b
;
}
.card__overlay-bottom
{
display
:
flex
;
gap
:
6px
;
align-items
:
center
;
}
.btn-editar
{
text-decoration
:
none
;
background
:
rgba
(
255
,
255
,
255
,
0.9
);
color
:
#111
;
border-radius
:
20px
;
padding
:
6px
14px
;
font-size
:
13px
;
font-weight
:
600
;
margin-left
:
auto
;
/* Melhor que 10rem fixo, adapta a qualquer largura */
transition
:
background
0.2s
ease
;
}
.btn-editar
:hover
{
background
:
#fff
;
}
/* Informações do cartão */
.card__info
{
padding
:
10px
12px
14px
;
}
.card__title
{
font-size
:
14px
;
font-weight
:
600
;
color
:
#111
;
line-height
:
1.4
;
}
/* ── FAB (botão +) ── */
.fab
{
position
:
fixed
;
bottom
:
60px
;
right
:
24px
;
width
:
56px
;
height
:
56px
;
border-radius
:
50%
;
background
:
#e60023
;
color
:
white
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.2
);
cursor
:
pointer
;
border
:
none
;
z-index
:
100
;
transition
:
background
0.2s
ease
,
transform
0.2s
ease
;
}
.fab
:hover
{
background
:
#ad081b
;
transform
:
scale
(
1.08
);
}
/* ── Footer ── */
footer
{
background
:
#fff
;
border-top
:
1px
solid
#e8e8e8
;
text-align
:
center
;
padding
:
16px
;
font-size
:
13px
;
color
:
#767676
;
position
:
fixed
;
bottom
:
0
;
width
:
100%
;
z-index
:
10
;
/* Garante que o footer fique acima do feed */
}
/* ── Responsividade ── */
@media
(
max-width
:
600px
)
{
.feed
{
columns
:
2
140px
;
}
.header__logo
{
font-size
:
18px
;
}
.fab
{
bottom
:
70px
;
/* Ajuste fino para mobile caso o footer seja maior */
right
:
16px
;
}
}
</style>
</head>
</head>
<body>
<body>
<!-- Cabeçalho com logo e busca -->
<!-- Cabeçalho com logo e busca -->
<header
class=
"header"
>
<header
class=
"header"
>
<a
class=
"header_user"
href=
"/templates/perfil"
<a
class=
"header_user"
href=
"/templates/perfil"
><img
src=
"/img/user-solid.png"
alt=
"Perfil"
width=
"30px"
><img
src=
"{{ url_for('static', filename='img/user-solid.png') }}"
alt=
"Perfil"
width=
"30px"
></a>
/></a>
<a
class=
"header__logo"
href=
"/"
>
Dishly
</a>
<a
class=
"header__logo"
href=
"/"
>
Dishly
</a>
<div
class=
"header__search"
>
<div
class=
"header__search"
>
<!-- ícone de lupa -->
<!-- ícone de lupa -->
...
@@ -380,8 +82,12 @@
...
@@ -380,8 +82,12 @@
</main>
</main>
<!-- Botão flutuante para cadastrar nova receita -->
<!-- Botão flutuante para cadastrar nova receita -->
<a
class=
"fab"
href=
"/cadastro"
title=
"Nova receita"
>
+
</a>
<a
class=
"fab"
href=
"/cadastro"
title=
"Nova receita"
>
<svg
width=
"24"
height=
"24"
viewBox=
"0 0 24 24"
fill=
"none"
stroke=
"currentColor"
stroke-width=
"2"
stroke-linecap=
"round"
stroke-linejoin=
"round"
>
<line
x1=
"12"
y1=
"5"
x2=
"12"
y2=
"19"
/>
<line
x1=
"5"
y1=
"12"
x2=
"19"
y2=
"12"
/>
</svg>
</a>
<footer>
<footer>
<p>
©
2026 Dishly. Todos os direitos reservados.
</p>
<p>
©
2026 Dishly. Todos os direitos reservados.
</p>
</footer>
</footer>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment