¿Hay alguna razón lógica para generar automáticamente la documentación del código? [cerrado]

60

La generación automática de documentación se puede hacer con una variedad de herramientas, siendo GhostDoc una de las más destacadas. Sin embargo, por definición, todo lo que genera es redundante. Echa un vistazo a los nombres de métodos, clases, etc. y genera inglés que podría explicarlos de manera más detallada. En el mejor de los casos, hace lo que el lector ya podría hacer en su cabeza (ejemplos tomados de aquí ):

/// <summary>
/// Initializes a new instance of the <see cref="Person"/> class.
/// </summary>
public Person() ...

En el peor de los casos, puede terminar generando documentación extraña que en realidad es engañosa en su intento de descubrir heurísticamente el significado de los nombres:

/// <summary>
/// Riches the text selection changed.
/// </summary>
/// <param name="richTextBox">The rich text box.</param>
private void RichTextSelection_Changed(System.Windows.Controls.RichTextBox richTextBox) ...

Parece que la actitud con GhostDoc es "es intrínsecamente mejor tener algún tipo de documentación XML formal", pero cuando esa documentación es 100% redundante, ¿por qué? ¿No es solo desperdiciar una tonelada de espacio en el mejor de los casos?

En mi lugar de trabajo, tenemos que documentar todo, y casi siempre con los documentos autogenerados de GhostDoc. ¿Hace esto y hay alguna razón racional para no dejar simplemente el código sin documentar si no va a escribir la documentación usted mismo?

Jez
fuente
3
relacionado: Documento de diseño del código
mosquito
55
Si reutiliza sus archivos DLL y desea mantener las sugerencias de IntelliSense sobre lo que hacen los métodos y parámetros, debe tener comentarios sobre cada clase, método y parámetro. De lo contrario, el proyecto explotará y el XML no se creará. Creo que usar comentarios generados automáticamente como ese es un enfoque ridículamente perezoso para hacerlo.
krillgar
11
Genera documentación redundante para que los desarrolladores se molesten y completen la documentación correcta. Juegos mentales en todas partes.
Kroltan
2
a veces puedes dar el documento pero no el código
Leo
2
Respuesta corta: No.
Thomas Eding

Respuestas:

14

[...] documente todo, y casi siempre con los documentos autogenerados de GhostDoc. ¿Hace esto y hay alguna razón racional para no dejar simplemente el código sin documentar si no va a escribir la documentación usted mismo?

No. La documentación generada por GhostDoc es repetitiva (similar a cómo crear una nueva clase OO en un IDE crea la repetitiva para una clase con un constructor o algo así). La parte útil de la documentación es lo que seguiría después de agregar el repetitivo.

Si bien tiene que documentar todo en su lugar de trabajo, parece que sus colegas encontraron la manera perfecta de evitarlo: solo finja.

utnapistim
fuente
-1. ¿Simplemente finge? Eso podría funcionar muy bien para un proyecto de una persona que nunca se volverá a usar. Se necesita cierto nivel de documentación / comentario incluso con un proyecto de una persona si su complejidad es mayor que la de "hola mundo" y si planea retomar ese proyecto dentro de seis meses. En un proyecto que involucra a docenas o incluso cientos de personas, la falta de documentación / comentario puede matar el proyecto.
David Hammen
14
@DavidHammen, soy consciente de que un proyecto puede morir debido a la falta de documentación. Además, la "pretensión justa" no fue un consejo para el OP, sino una crítica de sus colegas.
utnapistim
73

En un lenguaje de tipo estático, la documentación de estilo Javadoc no es para los autores, es para los consumidores. La autogeneración simplemente facilita que los autores mantengan la documentación para que otras personas la consuman.

Si está utilizando un lenguaje tipado estáticamente y no está escribiendo una biblioteca para consumo de terceros, la autogeneración no le compra mucho y, en mi experiencia, rara vez se usa. Si está utilizando un lenguaje de tipo dinámico, la documentación de estilo javadoc a menudo se utiliza para documentar los tipos, incluso para uso interno, pero la autogeneración no los conoce, por lo que todo lo que ahorra es evitar la copia manual de la repetitiva.

De cualquier manera, no piense en la autogeneración como la producción de un producto terminado. Piense en ello como la producción de la repetitiva para usted, por lo que cualquier cambio que realice manualmente es significativo.

Karl Bielefeldt
fuente
26

¿Hay alguna razón lógica para generar automáticamente la documentación del código?

¿Desde cuya perspectiva?

Si estaba ejecutando la empresa o el grupo de desarrollo, entonces no hay una buena razón. Estoy firmemente en el campo "los comentarios deberían explicar por qué ". Obligar a las personas a comentar clases / funciones / propiedades es peor que inútil, ya que se desactualizan, engañan al lector, se usan como excusa para no hacer código legible, y así sucesivamente. Estos comentarios pierden tiempo escribiéndolos, leyendo el código y los errores causados ​​por ellos. Algunos argumentarán que los documentos API de estilo JavaDoc son una razón para hacer los comentarios, pero incluso bajo ese argumento una pequeña porción de su código debería ser parte de la API pública, y JavaDoc no es un reemplazo para los documentos API reales.

Como desarrollador, he trabajado en algunos lugares que requieren comentarios en estos lugares, a pesar de mi opinión. Como no tengo el tiempo ni la paciencia para escribir un montón de basura que nadie va a usar, en su lugar, GhostDoc. Esto me permite pasar ese tiempo haciendo cosas que realmente importan. Mucho más eficiente que cambiar la política corporativa.

Otra cosa buena que he encontrado usando GhostDoc es que sirve para verificar que mis nombres son buenos. Si GhostDoc no puede generar documentación decente para una función, es un olor que los nombres de mis funciones o parámetros pueden ser deficientes. Si bien no usaría la herramienta solo para esto, es un pequeño efecto secundario si me obligan a perder el tiempo de todos modos.

Telastyn
fuente
1
Excepto que mi ejemplo muestra que GhostDoc puede no generar una documentación decente incluso cuando el nombre no es realmente tan malo.
Jez
11
Sí, algún gerente proclama "documentamos todo nuestro código" y otro gerente piensa que todo es excelente como resultado. Los desinformados permanecen así, pero siguen siendo felices.
JeffO
3
@jez - Claro, es solo un olor. A veces es correcto, a veces no lo es.
Telastyn
1
Respondiendo con una pregunta. Nice;)
Pierre Arlaud
@Jez Has dicho que el nombre no es realmente tan malo. Sin embargo, el RichTextSelection_Changedmétodo podría ser más fácil de usar si perteneciera a un objeto de selección y si no tuviera el nombre del tipo de su parámetro. Aunque, como dijo Telastyn, es solo un olor, que podría ser correcto o incorrecto para su diseño, y mis sugerencias probablemente no mejorarán la salida de GhostDoc.
dcorking
21

EDITAR : no entendí la pregunta original; Aunque creo que la generación de la documentación (es decir, no del código de documentos ) puede ser extremadamente valiosa (véase la respuesta inicial en relación con Doxygen más adelante), la generación de auto- comentarios (que es algo que realmente hace GhostDoc) parece una locura para mí. No puedo entender por qué alguien esperaría que un programa pueda leer el código fuente sin comentarios y escribir comentarios que realmente lo aclaren.

Es concebible para mí que una utilidad muy "inteligente" comentario generación podría ser programado para reconocer ciertos patrones y generar "cómo" al estilo de los comentarios; por ejemplo, podría reconocer el algoritmo de cálculo de varianza de Knuth y proporcionar un comentario que explique cómo funciona y por qué el algoritmo ingenuo no sería apropiado. Quizás tal utilidad podría incluso programarse para reconocer patrones de diseño orientados a objetos canónicos (por ejemplo, Abstract Factory) e insertar comentarios que indiquen qué patrón se está utilizando y qué clases están desempeñando qué roles.

Pero en mi opinión, los comentarios más útiles no explican "cómo" funciona algo, ya que el código en sí debería mostrar esto, sino " por qué " comenta, explicando "por qué" se está haciendo algo en particular. Como señaló David Hammen en los comentarios a continuación, para generar comentarios de "por qué", una utilidad necesitaría "leer la mente del programador". Obviamente esto es imposible.

Sin embargo, según los ejemplos dados, parece que GhostDoc ni siquiera cumple la tarea de crear verdaderos comentarios al estilo "cómo". Por lo tanto, es, en mi opinión, peor que inútil, ya que lo que genera puede ser insano y engañoso (como en el segundo ejemplo).


Respuesta original: por qué la extracción y el formato automáticos de documentación es una buena idea

Mi equipo de software usa Doxygen. La razón principal de esto es que necesitamos documentación sin código fuente (es decir, legible por no programadores) de las características / comportamiento del código / etc., pero creemos que es una mejor práctica integrar esto en el código fuente en sí mismo que mantenerlo como un segundo documento . Esto nos ayuda a mantener la documentación sincronizada con el código fuente (aunque, por supuesto, eso no puede garantizarse por completo, mucho menos automatizado) y minimiza la sobrecarga de la escritura de la documentación (ya que la documentación de un fragmento de código puede incorporarse trivialmente en el archivo que contiene el código en sí).

Por lo tanto, el enfoque de nuestro uso de Doxygen no es extraer información del código en sí, sino mantener la documentación del código fuente lo más cerca posible del código fuente en sí.

Esto también nos permite usar una sola herramienta para crear una "teoría de operaciones" que describa toda nuestra base de código y varios conjuntos de "notas de la versión" que describen el producto de software pero que de hecho no contienen ninguna "documentación de código" real en el sentido típico

En cuanto a por qué necesitaríamos documentación sin código fuente del comportamiento de nuestro código, hay dos razones:

  • Nuestro producto no es simplemente software; Es una herramienta compleja que integra muchos componentes de hardware, incluidos algunos láseres y fluidos sofisticados. Necesitamos ingenieros sin mucha experiencia en software para que comprendan exactamente cómo se comportan los componentes internos de nuestro código, y decirles que "leer el código fuente" no va a lograr esto.
  • Debemos seguir bastantes regulaciones de calidad, algunas ordenadas internamente por la compañía y otras legalmente ordenadas por el gobierno federal. Aunque el proceso de calidad es (o al menos puede ser) extremadamente valioso y útil, implica una cantidad no despreciable de gastos generales, parte del cual es el deber del equipo de software proporcionar este tipo de documentación detallada del software. Nuevamente, la integración de esta documentación con el código mismo minimiza los gastos generales y nos ayuda a mantener la documentación actualizada.

Tenga en cuenta que el segundo punto es bastante similar al punto que un par de otras respuestas han hecho sobre los gerentes que quieren la seguridad (/ los derechos de fanfarronear) de saber que existe cierta documentación (independientemente de la calidad) para cada pieza de código fuente; esa forma de enmarcarlo, sin embargo, ignora el hecho de que la documentación exigida externamente puede tener algunas ventajas legítimas.

Kyle Strand
fuente
¿Doxygen emite inglés o simplemente formatea cadenas de documentos que ya están escritas en inglés?
dcorking
3
@dcorking Este último, aunque también trata de organizar todo de acuerdo con la estructura estática del código y proporcionar hipervínculos automáticos en todas partes posibles (y estos son frecuentemente incorrectos).
Kyle Strand
2
En realidad, son las dos cosas. doxygen analiza el código y los comentarios de doxygen. Nombres de clases, nombres de clases primarias, nombres de miembros de datos, nombres de funciones, tipos de argumentos y nombres, tipo de retorno: todos provienen del código analizado. Lo que significan esas cosas proviene de los comentarios de doxygen. Doxygen se queja si un artículo especificado como \ param en el comentario de doxygen no es un argumento, y se puede hacer que se queje de artículos indocumentados. Además de estas comprobaciones mínimas, el problema de la falta de coincidencia de comentarios vs código sigue siendo una posibilidad. Dicho esto, me encanta el oxígeno. Es mucho mejor que escribir una API a mano.
David Hammen
@DavidHammen, ¿Doxygen genera oraciones, como "Riquezas, cambió la selección de texto"? (No lo he usado en muchos años, y esas primeras versiones no generaban inglés que yo recuerde.)
dcorking
@dcorking _ No tengo la menor idea de lo que quieres decir con eso. Doxygen no puede leer la mente del programador. Para un buen ejemplo de lo que puede hacer doxygen, vea esta página de nivel superior para Eigen , un paquete de computación científica C ++ bastante popular. ¡Hurgar! Puede ver cierta documentación que obviamente está escrita por humanos, otra que es puramente autogenerada, y otra que es una mezcla de escritura humana y autogenerada. Si se le indica, doxygen generará automáticamente la entrada (que hace referencia a esta función) y la salida (lo que llama esta función).
David Hammen
7

Ciertamente, la documentación automatizada es particularmente útil cuando puede reproducir descripciones perspicaces y apropiadas escritas por los autores del código. De lo contrario, es solo un formateador automático glorificado.

Pero el formateo no es inútil. Es valioso poder encontrar los métodos públicos de un componente grande en una sola mirada, ordenados y garantizados para ser completos. Si necesita un frobnickmutador y no está allí, sabe que no está allí sin leer el código fuente. (Los resultados negativos también tienen valor: sabes que tienes que hacer algo y tienes más tiempo para hacerlo porque no tienes que vadear).

Entonces, sí, la generación automática de documentos agrega algo de valor. Ciertamente, no tanto como los gerentes probablemente suponen, y generalmente ni siquiera tanto como lo haría un editor de copias realmente bueno, pero nada.

Kilian Foth
fuente
44
No entiendo tu comentario sobre "leer el código fuente". Seguramente en ambos casos, buscaría algo como 'frobnick mutator' o 'frobnickmutator' ... ¿cómo ayuda la documentación autogenerada?
Jez
2
@Jez No todos los que necesitan saber sobre frobnickmutadores serán desarrolladores de software; Es posible que no entiendan cómo mirar el código fuente (lo que puede requerir familiaridad con grep/ cscope/ ack/ etc.), e incluso si encuentran el archivo correcto, entonces pueden no encontrar el código fuente real fácil de leer, incluso si está bien comentado desde una perspectiva SW. La capacidad de mirar a través de un índice o escribir en una barra de búsqueda, luego navegar a través del texto que parece ser parte de una página web, puede ser muy valiosa.
Kyle Strand
44
@Jez, un documento legible para humanos que no son programadores o al menos no expertos no es redundante. Es necesario. Para expresar claramente lo que se pretende que haga el código . Tiene que ser capturado antes de escribir cualquier código. Y actualizado a medida que crece el conocimiento de los problemas y las soluciones. No vale la pena guardar los ejemplos citados, pero 'todo está en el código fuente' es arrojar al bebé con el agua del baño. "Generación automática" suena mal, "no hay documentos, solo lea la fuente" es peor. Es como cuando le preguntas a alguien: "¿Qué hace eso?" y dicen: "¡Hmm, vamos a correr y averiguarlo!"
Proyecto de ley IV
6

De esta forma, es peor que inútil, pero solo porque se basa solo en la firma pública (que, en el caso de Javadoc, es visible de todos modos para cualquiera que lea el documento API).

Pero es posible escribir herramientas de documentación automatizadas que también consideren el cuerpo del método. Como prueba de concepto, escribí un pequeño y cojo plugin Eclipse que agrega una lista de otros métodos llamados desde el método documentado al Javadoc. (No todas las llamadas, por supuesto, puede definir filtros, por paquete, por ejemplo).

Y en realidad lo he encontrado bastante útil cuando mapeo mentalmente una base de código completamente desconocida. De acuerdo, es un caso de uso muy limitado, pero definitivamente fue una ayuda.

Según esa experiencia, la respuesta a la pregunta es: sí, pero necesitamos herramientas mucho más inteligentes.

Actualización: Por supuesto, una pregunta adicional (una que debe hacerse antes de escribir cualquier tipo de documentación) es quién es el público objetivo. Si estamos documentando una API pública para clientes de esa API, agregar todos estos detalles de implementación es un gran no-no, ya que cualquier cosa que coloque en el Javadoc es técnicamente parte de la API.

Pero si el público objetivo son otros desarrolladores que trabajan en el mismo producto, agregar información automáticamente sobre los detalles de implementación, como qué métodos modificar o leer un determinado campo es aceptable y bastante útil.

biziclop
fuente
6

No conozco otros entornos, pero cuando se trata de proyectos PHP grandes (a menudo de código abierto) que otras personas han escrito, phpXRef es un salvavidas absoluto (especialmente si el documento se coloca en línea y Google puede indexarlo).

Incluso un proyecto mal comentado puede al menos ayudarme a localizar dónde se han definido las cosas y dónde se usan (por ejemplo, cuando se refactoriza).

Cuando está bien comentado, las páginas resultantes se forman cerca de una Biblia perfecta para la base de código (para mis usos de todos modos).

Además, mi IDE preferido generará automáticamente el bloque de comentarios (si escribo / **) que realiza aproximadamente el 75% del trabajo de comentarios para mí. Es sorprendente la cantidad de cosas estúpidas que me han impedido cometer durante mi vida de codificador solo porque he tenido que explicar a otras personas (y en el futuro a mí) lo que estoy haciendo. Cuando mi comentario para el generador de documentos es más grande que el método, esto generalmente significa que no he tomado suficiente café y que tal vez quiera pensar un poco más.

Esos mismos bloques de comentarios también crean el texto de "ayuda" de finalización en línea para que pueda ver exactamente lo que se esperaba (por los otros codificadores) mientras escribo la llamada a la función. Este es un gran impulso de productividad para mí (especialmente en esos casos extremos poco comunes en los que algún otro desarrollador útil ha escrito "por amor de Dios, hacer / no hacer X", lo que puede ahorrar mucho dolor.

No puedo enfatizar lo suficiente lo útil que es tener los tipos de entrada esperados especificados en proyectos PHP complejos (y a menudo mal nombrados) y el orden de los argumentos en los métodos menos utilizados. Incluso con mi propio código, no siempre puedo recordar qué argumentos especifiqué para algo que no he tocado en una época.

En un caso, significaba que la fuente de los problemas recurrentes era que, por alguna razón que se refleja mal en los desarrolladores anteriores, algunas funciones e incluso constantes se definieron en una gran cantidad de lugares (con un cierto grado de inconsistencia para "diversión" adicional) . Esa fue la señal para alejarse del proyecto.

En proyectos más grandes que comenzaron antes de que me uniera, puedo ver qué desarrollador (suponiendo que etiquetaron el archivo de clase con un nombre y un correo electrónico) creó la clase y simplemente poder encontrar y hablar con el desarrollador correcto es de gran ayuda.

Listas de tareas automáticas: el uso de la etiqueta @todo (común en el tipo de proyectos en los que me encuentro trabajando) significa que la documentación puede realizar un seguimiento de las cosas que necesitan más trabajo (o características que se reconoce que faltan). Una vez más, mi IDE realiza un seguimiento de esto y solo eso actúa como una buena guía sobre lo que necesita mi atención primero.

Por último (y muy importante para mí) elimina la sobrecarga no trivial de escribir todo eso y luego tratar de mantenerlo actualizado cuando algunos (leer muchos) codificadores cometen cambios y no hablan con los encargados de la documentación.

Entonces, las razones incluyen:

  • Ahorrando a los desarrolladores posteriores una pila de tiempo,
  • Realizar un seguimiento de dónde se llaman (y se definen) las funciones,
  • Manchado de codificaciones tontas,
  • Encontrar (como ha señalado otro) cuando obviamente falta algo,
  • Simplificar la refactorización (nunca es muy divertido)
  • (En muchos casos) tener una idea de lo que el desarrollador estaba tratando de hacer (suponiendo que dejara algunas notas).
  • Si el proyecto es lo suficientemente complejo como para tener varias licencias en curso (no es divertido), puedo ver rápidamente qué licencias se aplican a cualquier sección. Es cierto que este es un bono adicional.
  • Tener una idea de con quién hablar sobre un archivo de proyecto.
  • Listas de tareas automáticas

Además, no subestimes el valor de mantener contentos a los jefes de cabello puntiagudo con solo tocar un botón.

En resumen, los "comentarios de documentación automática" son vitales para mis hábitos de codificación. Estoy seguro de que hay muchos que piensan que es tonto, pero también estoy seguro de que hay algunas personas que saben exactamente lo que estoy diciendo. No sé cómo sobreviví antes de descubrir phpXRef (y mi IDE favorito).

Matthew Brown, también conocido como Lord Matt
fuente
4

A menudo es bueno usar generadores de documentación para crear repeticiones o comentarios "suplentes" que luego son revisados ​​por desarrolladores reales. A menudo uso la función auto-JavaDoc de Eclipse para generar el comentario del encabezado con los tipos de parámetros y los valores de retorno ya completados, luego simplemente agrego la "carne" de la documentación.

TMN
fuente
3

Como desarrollador de C #, uso Stylecop, que exige comentarios para todas las clases, métodos, etc. Autogenero estos comentarios usando una herramienta. La mayoría de las veces, los comentarios generados por la herramienta son suficientes y pueden inferirse por el nombre del objeto, por ejemplo, una clase de persona tiene un campo ID.

Pero si quiero comentar un método no obvio, es muy fácil expandir la documentación repetitiva y algunas explicaciones sobre lo que hace. Como ejemplo: tengo un método en mi clase de Persona, que devuelve Nombre + Apellido, pero agregué un poco de documentación sobre lo que sucede cuando falta uno de los dos.

En resumen: creo que el documento repetitivo puede ser perjudicial si nunca cambia el texto proporcionado por el generador. En ese caso, es solo ruido de línea. Pero si los ve como una plantilla, bajan la barra para proporcionar comentarios buenos y útiles para usted o sus consumidores. ¿Podría escribir los comentarios sin autogenerarlos? Claro, pero tendría que cumplir con el formato (que en el caso de C # es bastante detallado y molesto de generar a mano) y eso reduce la posibilidad de que realmente proporcione este comentario en todo momento.

Christian Sauer
fuente
Sin embargo, esa regla Stylecop se puede deshabilitar. Regla SA1600 si no me equivoco.
Jez
@Jez Sí, pero decidí no hacerlo. Conduce a muchos comentarios innecesarios, pero también me anima a escribir los comentarios necesarios. No es perfecto, pero ¿qué es? Lo que sí deshabilité fue el corrector ortográfico, que aparentemente ni siquiera sabe palabras básicas de TI
Christian Sauer
3

Evitar la tautología

La única vez que necesite algún tipo de documentación para el código es explicar por qué un método / función está haciendo algo, el nombre debería ser suficiente para lo que está haciendo.

Si está haciendo algo que no es idiomático o que viola el principio de menor asombro , se requiere documentación.

Los consumidores de su código casi exigen la documentación generada automáticamente que es solo un formateador para la salida de información. Javadoc hace esto extremadamente bien.

No todo debe documentarse manualmente

Cosas como los métodos getXXX / setXXX deben explicarse por sí mismo, por lo que la documentación de generación automática que le permita saber que existe será bien recibida.


fuente
2

La documentación del código, al menos del tipo "automático", representa el denominador menos común para las personas que intentan comprender la aplicación.

Los usuarios más sofisticados no apreciarían la documentación automática del código. Preferirían tener documentación "dirigida" que les diga qué (poco) necesitan que les digan.

Los usuarios menos sofisticados no lo apreciarían por la razón opuesta; ellos no lo entenderían de todos modos.

Los usuarios más "agradecidos" de la documentación de código automática son aquellos para quienes "un poco de conocimiento" es algo peligroso. "Pueden o no entender la documentación (aunque es probable que lo hagan), pero se sentirán bien por" ser se mantiene al tanto. "Esta audiencia incluye la mayoría de los tipos" gerenciales ". Si esa es su audiencia principal, la documentación de código automática podría ser algo bueno.

Tom Au
fuente
0

la respuesta simple a "por qué generar documentos" se puede responder simplemente mostrando MSDN.

Imagínese tratando de escribir un programa que use cualquier biblioteca donde no haya documentación API. Sería una pesadilla. MSDN es un gran ejemplo del tipo de documento que se puede generar a partir del código fuente y los comentarios y formar un recurso esencial para los desarrolladores.

Si está escribiendo una aplicación (es decir, no una biblioteca para ser consumida por otros), entonces tal vez exista un caso para que no le moleste, pero aun así, la cantidad de una aplicación grande, solo interna, no contiene un montón de bibliotecas ¿de todas formas? Cuando te unes a un equipo así, será útil tener un documento de API navegable.

Ninguna herramienta va a escribir su documentación por usted, pero sí le dan la referencia que tendría que escribir manualmente de todos modos, algunas herramientas (como doxygen) también generarán diagramas y listas de referencias (por ejemplo, funciones llamadas y llamadas) ) que no se descubriría fácilmente incluso mirando el código fuente.

Obviamente, el sentido común pragmático debe aplicarse a lo que se documenta, las propiedades y las funciones menores pueden ignorarse (y omitirse de la generación incluso en las herramientas), pero en ningún momento nadie debería decir "ahí está el código fuente, es suficiente documentación" en cualquier momento .

gbjbaanb
fuente