diff --git a/docs/bocetos/boceto-10.svg b/docs/bocetos/boceto-10.svg new file mode 100644 index 0000000..a467e1d --- /dev/null +++ b/docs/bocetos/boceto-10.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/bocetos/boceto-6.svg b/docs/bocetos/boceto-6.svg new file mode 100644 index 0000000..7d9cd9d --- /dev/null +++ b/docs/bocetos/boceto-6.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/bocetos/boceto-7.svg b/docs/bocetos/boceto-7.svg new file mode 100644 index 0000000..9a33f21 --- /dev/null +++ b/docs/bocetos/boceto-7.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/bocetos/boceto-8.svg b/docs/bocetos/boceto-8.svg new file mode 100644 index 0000000..a5b235e --- /dev/null +++ b/docs/bocetos/boceto-8.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/bocetos/boceto-9.svg b/docs/bocetos/boceto-9.svg new file mode 100644 index 0000000..4124805 --- /dev/null +++ b/docs/bocetos/boceto-9.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/plaza.svg b/docs/plaza.svg new file mode 100644 index 0000000..9e648f1 --- /dev/null +++ b/docs/plaza.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/sites/takethestreet/en/index.html b/sites/takethestreet/en/index.html deleted file mode 100644 index d354310..0000000 --- a/sites/takethestreet/en/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - -Take the Street · One street, every struggle - - - - - - - - - - -
- Take the Street - -
- -
-
-

One street,
every struggle

-

Home · Land · No borders · Peace

- A colourful crowd fills the street - -
- -
-

We were born in Madrid's Puerta del Sol on 26 September, fighting for housing. Today housing groups, environmentalists, anti-racists, anti-militarists and feminists share the squares, and the camps are spreading to Portugal and Italy.

-

They don't take our homes, the planet, our papers and our peace one at a time. It's the same system, putting the profit of a few above everyone's lives. That's why we take to the same street together.

-
- -
-

Four axes

-
-
- -

Home

-

Housing is a right, not a business.

-

Against evictions, speculation, vulture funds and touristification. For public housing and neighbourhoods people can actually live in.

-
-
- -

Land

-

The planet is our home too.

-

Climate justice: polluters pay, not neighbourhoods. Green cities, public transport and an end to the destruction of the land.

-
-
- -

No borders

-

No one is illegal.

-

Regularisation, an end to racist raids and detention centres, and equal rights for everyone who lives here.

-
-
- -

Peace

-

More homes, fewer tanks.

-

Money for life, not for war. An end to the arms trade and solidarity with peoples living under war and occupation: with Palestine, loud and clear.

-
-
-
- -

Feminisms throughout. The women hit hardest by evictions, the women who carry the care work, the women who cross borders: we look at all four axes through purple glasses.

-
-
- -
-

Camps

-
-
-

Spain

-

Since 26 September, camps in 18 cities. All of them at acampada26s.net.

-

Madrid · Sol

-
- -
-

Italy

-

Milano · Statale
Roma · piazza Bologna
Tents at a dozen universities

-
-
-

What about your city?

-

If there's a camp where you live, or you want to start one, write to us at acampada26s@riseup.net and we'll add it to the network.

-
-
-
- -
-

How we organise

- -
- -
-

Spread the word

-

#takethestreet#unacalletodaslasluchas#26s

-

On the 26th of every month, every square at once. Post in your language with the common hashtag and your city's.

-

Logos and drawing for posters and social media: logotype · symbol · drawing

-
-
- - - - diff --git a/sites/takethestreet/img/calle.svg b/sites/takethestreet/img/calle.svg index e14b7cf..9e648f1 100644 --- a/sites/takethestreet/img/calle.svg +++ b/sites/takethestreet/img/calle.svg @@ -1,405 +1,13 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + diff --git a/sites/tomalacalle/img/calle.svg b/sites/tomalacalle/img/calle.svg index e14b7cf..9e648f1 100644 --- a/sites/tomalacalle/img/calle.svg +++ b/sites/tomalacalle/img/calle.svg @@ -1,405 +1,13 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + diff --git a/tools/bocetos.py b/tools/bocetos.py index 349a76a..ee0191f 100644 --- a/tools/bocetos.py +++ b/tools/bocetos.py @@ -3,7 +3,6 @@ # De cada portal sale un reguero de un color (cada lucha) y todos se juntan en la piña, # que en el centro arde en colores de fuego. import sys, random, math, os -OUT = sys.argv[1] INK = "#111" FUEGO = ["#fffbe6", "#ffe066", "#ffb627", "#ff7b1c", "#f04e23", "#c8102e"] # del centro hacia fuera LUCHAS = ["#8e44c9", "#3b5bdb", "#14965a", "#d6336c", "#2a9d8f", "#5b2a86"] # un color por reguero @@ -19,6 +18,8 @@ DEFS = ''' + + ''' class Calle: @@ -200,6 +201,8 @@ def b5(): c.gente((-.5, 12.5, 2.2, 3.5, 9000, 2.8), regueros(c, (4.0, 7.0, 17.0)), extra=lateral) return c -os.makedirs(OUT, exist_ok=True) -for n, f in enumerate([b1, b2, b3, b4, b5], 1): - open(f"{OUT}/boceto-{n}.svg", "w").write(f().svg()) +if __name__ == "__main__": + OUT = sys.argv[1] + os.makedirs(OUT, exist_ok=True) + for n, f in enumerate([b1, b2, b3, b4, b5], 1): + open(f"{OUT}/boceto-{n}.svg", "w").write(f().svg()) diff --git a/tools/plazas.py b/tools/plazas.py new file mode 100644 index 0000000..18687fb --- /dev/null +++ b/tools/plazas.py @@ -0,0 +1,320 @@ +# Genera la portada (la plaza que nace del cruce del boceto 5) y los bocetos 6 a 10: +# plazas y cruces con el mismo acabado a mano que tools/bocetos.py. +import sys, random, math, os +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from bocetos import Calle, INK, FUEGO, FRIO, LUCHAS + +EJES = ["#f04e23", "#14965a", "#f2b705", "#3b5bdb", "#8e44c9"] + + +class Escena(Calle): + def zn(s): + return s.EYE * s.F / (s.H + s.Y0 - s.VY) * .8 + + def seg(s, a, b, w=None, op=.95): + zn = s.zn() + if a[2] < zn and b[2] < zn: + return + if a[2] > b[2]: + a, b = b, a + if a[2] < zn: + t = (zn - a[2]) / (b[2] - a[2]) + a = tuple(a[i] + (b[i] - a[i]) * t for i in range(3)) + if w is None: + w = 34 / ((a[2] + b[2]) / 2) + 1.6 + s.linea(s.P(*a), s.P(*b), w, op) + + def poli(s, pts, w=None, op=.95): + for a, b in zip(pts, pts[1:]): + s.seg(a, b, w, op) + + def abrir(s, *mascaras): + for m in mascaras: + s.o.append(f'') + s.o.append('') + s.cierre = '' + '' * len(mascaras) + + def cerrar(s): + s.o.append(s.cierre) + + def portal(s, a, b, alto=2.5, cornisa=True): + s.poli([(a[0], 0, a[1]), (a[0], alto, a[1]), (b[0], alto, b[1]), (b[0], 0, b[1])]) + if cornisa: + dx, dz = b[0] - a[0], b[1] - a[1] + s.seg((a[0] - dx * .2, alto + .35, a[1] - dz * .2), (b[0] + dx * .2, alto + .35, b[1] + dz * .2), None, .6) + + def fachada(s, a, b, portales=(), alto=2.5): + s.seg((a[0], 0, a[1]), (b[0], 0, b[1])) + L = math.hypot(b[0] - a[0], b[1] - a[1]) + ux, uz = (b[0] - a[0]) / L, (b[1] - a[1]) / L + for d in portales: + s.portal((a[0] + ux * d, a[1] + uz * d), (a[0] + ux * (d + 1.5), a[1] + uz * (d + 1.5)), alto) + + def esquina(s, X, Z, alto=3.2): + s.seg((X, 0, Z), (X, alto, Z), None, .7) + + def farola(s, X, Z, h=4.2): + s.seg((X, 0, Z), (X, h, Z), None, .9) + s.seg((X, h, Z), (X + .6, h - .1, Z), None, .9) + c = s.P(X + .6, h - .35, Z) + s.o.append(f'') + + def tienda(s, X, Z, col, a=2.0, f=2.2, alto=1.2): + x0, x1, xm = X - a / 2, X + a / 2, X + fr = [(x0, 0, Z), (xm, alto, Z), (x1, 0, Z)] + s.poli(fr, None, .9) + s.seg((xm, alto, Z), (xm, alto, Z + f), None, .6) + s.seg((x0, 0, Z), (x0, 0, Z + f), None, .5) + s.seg((x1, 0, Z), (x1, 0, Z + f), None, .5) + p = [s.P(*q) for q in fr] + d = f"M{p[0][0]:.1f},{p[0][1]:.1f} L{p[1][0]:.1f},{p[1][1]:.1f} L{p[2][0]:.1f},{p[2][1]:.1f} Z" + s.tiendas.append(f'') + + def gente(s, pina, regueros, extra=(), puños=.1, zona=None, zmax=40, ejes=None): + CX, CZ, sx, sz, n, R = pina + zmin = s.EYE * s.F / (s.H + s.Y0 - s.VY) + .3 + zona = zona or (lambda X, Z: True) + g = [] + + def cabe(X, Z): + return all(math.hypot(X - a, (Z - b) * .8) > .42 + .022 * Z for a, b, _ in g) + for X0, Z0, col, k in regueros: + for j in range(k): + t = (j + .5) / k + X = X0 + (CX - X0) * t + random.uniform(-.3, .3) + Z = Z0 + (CZ - Z0) * t + random.uniform(-.3, .3) + if Z > zmin and cabe(X, Z): + g.append((X, Z, col)) + for _ in range(n): + X, Z = random.gauss(CX, sx), random.gauss(CZ, sz) + if zmin < Z < zmax and zona(X, Z) and cabe(X, Z): + g.append((X, Z, None)) + g += list(extra) + c = s.P(CX, 1.0, CZ) + r0 = 2600 / CZ + s.o.append(f'') + for _ in range(700): + ang, rr = random.uniform(0, 2 * math.pi), abs(random.gauss(0, r0 * .55)) + k = min(len(FUEGO) - 1, int(rr / r0 * len(FUEGO))) + s.o.append(f'') + s.o += s.tiendas + for X, Z, col in sorted(g, key=lambda q: -q[1]): + x, y = s.P(X, 0, Z) + h = 1.7 * s.F / Z * random.uniform(.9, 1.08) + d = math.hypot(X - CX, Z - CZ) / R + if d < 1: + col = FUEGO[min(len(FUEGO) - 1, int(max(0, d + random.uniform(-.12, .12)) * len(FUEGO)))] + elif col is None: + col = random.choice(ejes or FRIO) if ejes and random.random() < .35 else random.choice(FRIO) + s.monigote(x, y, h, col, random.uniform(-.06, .04), random.random() < .35, random.random() < puños) + return len(g) + + def __init__(s, **k): + super().__init__(**k) + s.tiendas = [] + + +def llegan(X0, Z0, col, n): + return (X0, Z0, col, n) + + +def portada(): + # El cruce del boceto 5 se abre en una plaza: la calle llega desde abajo y la gente entra por todas partes + random.seed(15) + c = Escena(VX=1000, VY=60, EYE=9.0, F=600, Y0=100) + FA, FD, KI, KD = -6.5, 6.6, -4.2, 3.6 + z1, z2, xl, xr = 11.0, 25.0, -24.0, 17.0 + c.abrir("lados", "arriba") + c.fachada((FA, 3.0), (FA, z1), (4.0,)) + c.fachada((FD, z1), (FD, 3.0), (3.0,)) + c.seg((KI, 0, 3.0), (KI, 0, z1 - 1), 9) + c.seg((KI + .18, 0, 3.0), (KI + .18, 0, z1 - 1), 3, .7) + c.seg((KD, 0, 3.0), (KD, 0, z1 - 1), 7, .8) + for z in (4.0, 9.0): + c.seg((-.3, 0, z), (-.3, 0, z + 2.2), None, .8) + c.esquina(FA, z1); c.esquina(FD, z1) + c.fachada((FA, z1), (xl, z1), (6.0, 12.0)) + c.fachada((xr, z1), (FD, z1), (4.0,)) + c.fachada((xl, z1), (xl, 15.5), ()) + c.fachada((xl, 19.5), (xl, z2), ()) + for z in (15.5, 19.5): + c.esquina(xl, z) + c.seg((xl, 0, z), (-70, 0, z)) + c.fachada((xr, z2), (xr, z1), (3.0, 9.0)) + c.fachada((xl, z2), (-4.5, z2), (4.0, 10.0, 15.0)) + c.fachada((4.5, z2), (xr, z2), (3.0, 8.0)) + for x in (-4.5, 4.5): + c.esquina(x, z2) + c.seg((x, 0, z2), (x, 0, 90)) + c.esquina(xl, z1); c.esquina(xr, z1); c.esquina(xl, z2); c.esquina(xr, z2) + for x, z in ((-8, 13.5), (8, 13.5), (-8, 22.5), (8, 22.5)): + c.farola(x, z) + c.cerrar() + c.tienda(-19.5, 12.5, "#14965a") + c.tienda(-16.0, 21.0, "#f2b705") + c.tienda(13.0, 12.8, "#3b5bdb") + c.tienda(13.5, 20.0, "#8e44c9") + zona = lambda X, Z: (KI - 1.4 < X < KD - .3 and Z < z1) or (xl + .8 < X < xr - .8 and z1 + .5 < Z < z2 - .5) or (abs(X) < 4 and Z >= z2) + c.gente((-1.0, 16.0, 3.4, 2.8, 4200, 3.4), + [llegan(FA + .5, 4.75, LUCHAS[0], 6), llegan(-60, 17.5, EJES[1], 14), + llegan(-.3, 60, EJES[3], 12), llegan(xr - 1, 16, EJES[2], 6), llegan(.3, 3.2, EJES[0], 9)], + zona=zona, ejes=EJES, puños=.14, zmax=80) + return c + + +def b6(): + # La plaza: de frente, fachadas en U y la gente llenándola + random.seed(21) + c = Escena(VX=800, VY=120, EYE=6.0, F=560, Y0=80) + zf, xl, xr = 26.0, -15.0, 15.0 + c.abrir("lados", "arriba") + c.fachada((xl, 3.0), (xl, zf), (5.0, 10.0, 15.0)) + c.fachada((xr, zf), (xr, 3.0), (4.0, 9.0, 14.0)) + c.fachada((xl, zf), (-4.0, zf), (2.0, 6.0)) + c.fachada((4.0, zf), (xr, zf), (2.5, 6.5)) + for x in (-4.0, 4.0): + c.esquina(x, zf) + c.seg((x, 0, zf), (x, 0, 70)) + c.esquina(xl, zf); c.esquina(xr, zf) + for x in (-10.0, 10.0): + c.farola(x, 9.0); c.farola(x, 20.0) + c.cerrar() + c.gente((0, 15, 3.2, 2.6, 3500, 3.0), + [llegan(0, 40, LUCHAS[0], 10), llegan(xl + .6, 8.0, LUCHAS[1], 5), llegan(xr - .6, 7.0, LUCHAS[3], 5)], + zona=lambda X, Z: xl + .8 < X < xr - .8 and Z < zf - .5 or abs(X) < 3.5, ejes=EJES, puños=.15) + return c + + +def b7(): + # Dos calles que se cruzan en X: de cada esquina llega un eje con su color + random.seed(22) + c = Escena(VX=800, VY=110, EYE=7.0, F=560, Y0=80) + cz, a = 16.0, 4.5 + r = math.sqrt(.5) + + def W(u, v): + return ((u - v) * r, (u + v) * r + cz) + c.abrir("lados", "arriba") + for su in (-1, 1): + for sv in (-1, 1): + p0 = W(su * a, sv * a) + pu = W(su * 60, sv * a) + pv = W(su * a, sv * 60) + c.esquina(*p0) + for q in (pu, pv): + c.seg((p0[0], 0, p0[1]), (q[0], 0, q[1])) + for d in (6.0, 12.0): + for (u, v) in ((su * (a + d), sv * a), (su * a, sv * (a + d))): + x, z = W(u, v) + x2, z2 = W(u + su * 1.5 * (v == sv * a), v + sv * 1.5 * (u == su * a)) + c.portal((x, z), (x2, z2)) + for k in range(-8, 9, 3): + for u, v in ((k, 0), (0, k)): + if abs(k) > a + 1: + p, q = W(u, v), W(u + (1.6 if v == 0 else 0), v + (1.6 if u == 0 else 0)) + c.seg((p[0], 0, p[1]), (q[0], 0, q[1]), None, .7) + c.cerrar() + llegadas = [] + for (u, v), col in zip(((-30, 0), (30, 0), (0, -9), (0, 30)), EJES): + x, z = W(u, v) + llegadas.append(llegan(x, z, col, 12)) + zona = lambda X, Z: abs((X / r + (Z - cz) / r) / 2) < a - .3 or abs(((Z - cz) / r - X / r) / 2) < a - .3 + c.gente((0, cz, 1.8, 1.8, 2500, 2.6), llegadas, zona=zona, puños=.15) + return c + + +def b8(): + # La acampada: tiendas de colores en la plaza y la asamblea en el centro + random.seed(23) + c = Escena(VX=800, VY=120, EYE=6.5, F=560, Y0=80) + zf, xl, xr = 28.0, -16.0, 16.0 + c.abrir("lados", "arriba") + c.fachada((xl, 3.0), (xl, zf), (6.0, 12.0, 18.0)) + c.fachada((xr, zf), (xr, 3.0), (5.0, 11.0, 17.0)) + c.fachada((xl, zf), (xr, zf), (4.0, 9.0, 14.0, 19.5, 25.0)) + c.esquina(xl, zf); c.esquina(xr, zf) + c.farola(-6, 10); c.farola(6, 10); c.farola(0, 24) + c.cerrar() + random.seed(230) + tiendas = [] + for fila, z in enumerate((10.5, 13.0, 22.0, 24.8)): + for x in range(-13, 14, 4): + if abs(x) > 5 or z > 20: + tiendas.append((x + random.uniform(-.6, .6) + (fila % 2) * 2, z + random.uniform(-.4, .4))) + for k, (x, z) in enumerate(sorted(tiendas, key=lambda t: -t[1])): + c.tienda(x, z, EJES[k % len(EJES)]) + lejos = lambda X, Z: all(math.hypot(X - x, Z - (z + 1.1)) > 1.6 for x, z in tiendas) + c.gente((0, 17, 2.6, 1.8, 3000, 2.6), [], zona=lambda X, Z: xl < X < xr and Z < zf - .5 and lejos(X, Z), ejes=EJES, puños=.2) + return c + + +def b9(): + # Sol: cinco calles llegan a la misma plaza, cada una con su reguero + random.seed(24) + c = Escena(VX=800, VY=120, EYE=8.0, F=560, Y0=80) + cz, R = 22.0, 11.0 + angs = [-70, -35, 0, 35, 70] + c.abrir("lados", "arriba") + pts = [] + for k in range(-90, 91, 6): + t = math.radians(k) + pts.append((R * math.sin(t), cz + R * math.cos(t) * .9)) + huecos = [math.radians(a) for a in angs] + tramo = [] + for k, (x, z) in zip(range(-90, 91, 6), pts): + dentro = any(abs(math.radians(k) - h) < math.radians(8) for h in huecos) + if dentro: + if len(tramo) > 1: + s0 = [(px, 0, pz) for px, pz in tramo] + c.poli(s0) + tramo = [] + else: + tramo.append((x, z)) + if len(tramo) > 1: + c.poli([(px, 0, pz) for px, pz in tramo]) + for h in huecos: + for d in (-1, 1): + t = h + d * math.radians(8) + x0, z0 = R * math.sin(t), cz + R * math.cos(t) * .9 + x1, z1 = x0 + math.sin(h) * 40, z0 + math.cos(h) * 40 + c.esquina(x0, z0) + c.seg((x0, 0, z0), (x1, 0, z1)) + c.seg((-R, 0, cz), (-R, 0, 4)); c.seg((R, 0, cz), (R, 0, 4)) + c.farola(0, cz - 3) + c.cerrar() + llegadas = [llegan(math.sin(math.radians(a)) * (R + 14), cz + math.cos(math.radians(a)) * (R + 14) * .9, col, 10) + for a, col in zip(angs, EJES)] + c.gente((0, cz - 1, 2.8, 2.6, 3500, 3.0), llegadas, zona=lambda X, Z: math.hypot(X, (Z - cz) / .9) < R - .6 or Z < cz, ejes=EJES, puños=.15, zmax=60) + return c + + +def b10(): + # Desde el balcón: la plaza vista desde arriba, la piña como una hoguera de gente + random.seed(25) + c = Escena(VX=800, VY=40, EYE=16.0, F=520, Y0=100) + zf, xl, xr = 34.0, -18.0, 18.0 + c.abrir("lados") + c.fachada((xl, 8.0), (xl, zf), (8.0, 16.0)) + c.fachada((xr, zf), (xr, 8.0), (6.0, 14.0)) + c.fachada((xl, zf), (-4.0, zf), (3.0, 9.0)) + c.fachada((4.0, zf), (xr, zf), (3.0, 9.0)) + for x in (-4.0, 4.0): + c.seg((x, 0, zf), (x, 0, 80)) + for x, z in ((-12, 14), (12, 14), (-12, 28), (12, 28)): + c.farola(x, z) + c.cerrar() + c.gente((0, 21, 3.6, 3.2, 4500, 3.8), + [llegan(0, 60, EJES[3], 12), llegan(xl + .6, 12, EJES[1], 6), llegan(xr - .6, 30, EJES[2], 6)], + zona=lambda X, Z: (xl + .8 < X < xr - .8 and Z < zf - .5) or abs(X) < 3.5, ejes=EJES, puños=.12, zmax=70) + return c + + +if __name__ == "__main__": + salidas = sys.argv[1:] + bocetos = salidas.pop(0) + os.makedirs(bocetos, exist_ok=True) + for n, f in zip(range(6, 11), [b6, b7, b8, b9, b10]): + open(f"{bocetos}/boceto-{n}.svg", "w").write(f().svg()) + p = portada().svg() + for ruta in salidas: + open(ruta, "w").write(p)