ar-poncho 2.0.320 → 2.0.321

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/.editorconfig +1 -1
  2. package/.github/workflows/build-poncho.yml +13 -29
  3. package/dist/css/device-breadcrumb.css +1 -1
  4. package/dist/css/icono-arg.css +168 -8
  5. package/dist/css/poncho-map.css +1 -1
  6. package/dist/css/poncho-table-1.1.css +1 -0
  7. package/dist/css/poncho.css +2 -2
  8. package/dist/css/poncho.min.css +2 -2
  9. package/dist/css/poncho_mobile.css +2 -2
  10. package/dist/fonts/{icono-arg_9fd8913a0f55b524cf2c5287f865d425.eot → icono-arg_02c1319743cdcf3da43dbf293119dc6c.eot} +0 -0
  11. package/dist/fonts/{icono-arg_9fd8913a0f55b524cf2c5287f865d425.svg → icono-arg_02c1319743cdcf3da43dbf293119dc6c.svg} +679 -40
  12. package/dist/fonts/{icono-arg_9fd8913a0f55b524cf2c5287f865d425.ttf → icono-arg_02c1319743cdcf3da43dbf293119dc6c.ttf} +0 -0
  13. package/dist/fonts/icono-arg_02c1319743cdcf3da43dbf293119dc6c.woff +0 -0
  14. package/dist/fonts/icono-arg_02c1319743cdcf3da43dbf293119dc6c.woff2 +0 -0
  15. package/dist/ilustraciones/ilus-arg-adultos-mayores-16x9.svg +303 -0
  16. package/dist/ilustraciones/ilus-arg-adultos-mayores-640x360.svg +297 -0
  17. package/dist/ilustraciones/ilus-arg-argentinos-por-el-mundo-16x9.svg +111 -0
  18. package/dist/ilustraciones/ilus-arg-argentinos-por-el-mundo-640x360.svg +106 -0
  19. package/dist/ilustraciones/ilus-arg-artistas-16x9.svg +425 -0
  20. package/dist/ilustraciones/ilus-arg-artistas-640x360.svg +420 -0
  21. package/dist/ilustraciones/ilus-arg-circula-con-auto-o-moto-16x9.svg +469 -0
  22. package/dist/ilustraciones/ilus-arg-circula-con-auto-o-moto-640x360.svg +464 -0
  23. package/dist/ilustraciones/ilus-arg-consumidores-16x9.svg +258 -0
  24. package/dist/ilustraciones/ilus-arg-consumidores-640x360.svg +251 -0
  25. package/dist/ilustraciones/ilus-arg-discapacidad-16x9.svg +158 -0
  26. package/dist/ilustraciones/ilus-arg-discapacidad-640x360.svg +151 -0
  27. package/dist/ilustraciones/ilus-arg-documentacion-16x9.svg +67 -0
  28. package/dist/ilustraciones/ilus-arg-documentacion-640x360.svg +60 -0
  29. package/dist/ilustraciones/ilus-arg-educacion-16x9.svg +108 -0
  30. package/dist/ilustraciones/ilus-arg-educacion-640x360.svg +100 -0
  31. package/dist/ilustraciones/ilus-arg-emergencias-16x9.svg +466 -0
  32. package/dist/ilustraciones/ilus-arg-emergencias-640x360.svg +460 -0
  33. package/dist/ilustraciones/ilus-arg-emprendimientos-y-negocios-16x9.svg +127 -0
  34. package/dist/ilustraciones/ilus-arg-emprendimientos-y-negocios-640x360.svg +121 -0
  35. package/dist/ilustraciones/ilus-arg-extranjeros-16x9.svg +196 -0
  36. package/dist/ilustraciones/ilus-arg-extranjeros-640x360.svg +190 -0
  37. package/dist/ilustraciones/ilus-arg-pav-celular-16x9.svg +48 -0
  38. package/dist/ilustraciones/ilus-arg-pav-computadora1-16x9.svg +97 -0
  39. package/dist/ilustraciones/ilus-arg-pav-computadora2-16x9.svg +82 -0
  40. package/dist/ilustraciones/ilus-arg-pav-computadora3-16x9.svg +46 -0
  41. package/dist/ilustraciones/ilus-arg-pav-persona-16x9.svg +51 -0
  42. package/dist/ilustraciones/ilus-arg-salud-malestar1-16x9.svg +52 -0
  43. package/dist/ilustraciones/ilus-arg-salud-malestar10-16x9.svg +95 -0
  44. package/dist/ilustraciones/ilus-arg-salud-malestar11-16x9.svg +116 -0
  45. package/dist/ilustraciones/ilus-arg-salud-malestar2-16x9.svg +122 -0
  46. package/dist/ilustraciones/ilus-arg-salud-malestar3-16x9.svg +60 -0
  47. package/dist/ilustraciones/ilus-arg-salud-malestar4-16x9.svg +61 -0
  48. package/dist/ilustraciones/ilus-arg-salud-malestar5-16x9.svg +103 -0
  49. package/dist/ilustraciones/ilus-arg-salud-malestar6-16x9.svg +61 -0
  50. package/dist/ilustraciones/ilus-arg-salud-malestar7-16x9.svg +56 -0
  51. package/dist/ilustraciones/ilus-arg-salud-malestar8-16x9.svg +66 -0
  52. package/dist/ilustraciones/ilus-arg-salud-malestar9-16x9.svg +72 -0
  53. package/dist/ilustraciones/ilus-arg-trabajo-16x9.svg +183 -0
  54. package/dist/ilustraciones/ilus-arg-trabajo-640x360.svg +177 -0
  55. package/dist/ilustraciones/ilus-arg-transito-16x9.svg +769 -0
  56. package/dist/ilustraciones/ilus-arg-transito-640x360.svg +764 -0
  57. package/dist/ilustraciones/ilus-arg-vacaciones-16x9.svg +172 -0
  58. package/dist/ilustraciones/ilus-arg-vacaciones-640x360.svg +166 -0
  59. package/dist/ilustraciones/ilus-arg-violencia-y-abuso-16x9.svg +80 -0
  60. package/dist/ilustraciones/ilus-arg-violencia-y-abuso-640x360.svg +74 -0
  61. package/dist/ilustraciones/ilus-arg-vivienda-16x9.svg +4468 -0
  62. package/dist/ilustraciones/ilus-arg-vivienda-640x360.svg +4462 -0
  63. package/dist/js/device-breadcrumb.js +1 -1
  64. package/dist/js/mapa-argentina.js +1 -1
  65. package/dist/js/poncho-map-provinces-contenidos.js +1 -0
  66. package/dist/js/poncho.js +2594 -797
  67. package/dist/js/poncho.min.js +21 -1
  68. package/dist/jsons/icono-arg.json +7813 -0
  69. package/dist/jsons/illustrations-colors.json +1 -0
  70. package/dist/jsons/ilus-arg.json +322 -0
  71. package/dist/jsons/poncho-colors.json +1 -0
  72. package/dist/jsons/poncho-headers-colors.json +1 -0
  73. package/gulpfile.js +41 -12
  74. package/noresults.txt +1 -0
  75. package/package.json +58 -48
  76. package/readme.md +1 -1
  77. package/test/collections.test.js +51 -0
  78. package/test/html.test.js +6 -0
  79. package/test/poncho-gapi-legacy.test.js +18 -1
  80. package/test/string.test.js +42 -1
  81. package/.npmignore +0 -2
  82. package/dist/css/argentina.css +0 -8
  83. package/dist/fonts/icono-arg_9fd8913a0f55b524cf2c5287f865d425.woff +0 -0
  84. package/dist/fonts/icono-arg_9fd8913a0f55b524cf2c5287f865d425.woff2 +0 -0
  85. package/package-lock.json +0 -10493
  86. package/test/color.test.js +0 -24
  87. package/yarn.lock +0 -5545
package/dist/js/poncho.js CHANGED
@@ -1,526 +1,1562 @@
1
1
  /**
2
- * Definición de colores Poncho
2
+ * Listado de colores colores www.argentina.gob.ar
3
+ *
4
+ * MIT License
5
+ *
6
+ * Copyright (c) 2024 Argentina.gob.ar
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person
9
+ * obtaining a copy of this software and associated documentation
10
+ * files (the "Software"), to deal in the Software without restriction,
11
+ * including without limitation the rightsto use, copy, modify, merge,
12
+ * publish, distribute, sublicense, and/or sell copies of the Software,
13
+ * and to permit persons to whom the Software is furnished to do so,
14
+ * subject to the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ * SOFTWARE.
27
+ */
28
+ const ponchoColorDefinitionsList = [{"name": "www.argentina.gob.ar", "space": "arg", "hidden_space": false, "description": "", "data": [{"scope": "arg", "name": "Azul principal", "group": "primary", "color": {"900": "#232D4F", "800": "#2C3C5F", "700": "#354B6E", "600": "#3E5A7E", "500": "#5A7290", "400": "#7589A3", "300": "#91A1B5", "200": "#ACB8C8", "100": "#C8D0DA", "50": "#E3E7ED"}, "instance": [{"name": "Azul", "code": "arg-azul", "description": "Color principal", "scope": "arg", "related_color": "900", "parent_group": "primary", "color": "#232D4F", "variant": [{"variant": "half", "color": "#9296A7", "name": "Azul medio tono", "code": "arg-azul-half"}, {"variant": "lighter", "color": "#C8D0DA", "name": "Azul muy claro", "code": "arg-azul-lighter"}], "alias": [{"code": "arg-azul", "exclude": false}, {"code": "primary", "exclude": true}, {"code": "azul", "exclude": true}, {"code": "azul-marino", "exclude": true}, {"code": "primary-alt", "exclude": true}]}, {"name": "Secundario", "code": "arg-secundario", "description": "", "scope": "arg", "related_color": "600", "parent_group": "primary", "color": "#3E5A7E", "variant": [], "alias": [{"code": "arg-secundario", "exclude": false}, {"code": "secondary", "exclude": true}, {"code": "secundario", "exclude": true}]}, {"name": "Primary light", "code": "arg-primary-light", "description": "", "scope": "arg", "related_color": "50", "parent_group": "primary", "color": "#E3E7ED", "variant": [], "alias": [{"code": "arg-primary-light", "exclude": false}, {"code": "primary-light", "exclude": true}]}, {"name": "Info", "code": "arg-info", "description": "", "scope": "arg", "related_color": "500", "parent_group": "primary", "color": "#5A7290", "variant": [{"variant": "lighter", "color": "#E3E7ED", "name": "Info muy claro", "code": "arg-info-lighter"}], "alias": [{"code": "arg-info", "exclude": false}, {"code": "info", "exclude": true}]}]}, {"scope": "arg", "name": "Verde", "group": "verde", "color": {"50": "#F1F5D7", "100": "#DEE8A3", "200": "#CCDB6E", "300": "#B9CE39", "400": "#93B727", "500": "#6EA015", "600": "#4E8F24", "700": "#2E7D33", "800": "#27692A", "900": "#1F5421"}, "instance": [{"name": "Verde", "code": "arg-verde", "description": "", "scope": "arg", "related_color": "700", "parent_group": "verde", "color": "#2E7D33", "variant": [{"variant": "light", "color": "#6EA015", "name": "Verde claro", "code": "arg-verde-light"}, {"variant": "half", "color": "#96BE99", "name": "Verde medio tono", "code": "arg-verde-half"}, {"variant": "dark", "color": "#1F5421", "name": "Verde oscuro", "code": "arg-verde-dark"}], "alias": [{"code": "arg-verde", "exclude": false}, {"code": "success", "exclude": true}, {"code": "verde", "exclude": true}]}, {"name": "Verd\u00edn", "code": "arg-verdin", "description": "", "scope": "arg", "related_color": "500", "parent_group": "verde", "color": "#6EA015", "variant": [{"variant": "light", "color": "#B9CE39", "name": "Verd\u00edn claro", "code": "arg-verdin-light"}, {"variant": "dark", "color": "#2E7D33", "name": "Verd\u00edn oscuro", "code": "arg-verdin-dark"}], "alias": [{"code": "arg-verdin", "exclude": false}, {"code": "verdin", "exclude": true}]}, {"name": "Lima", "code": "arg-lima", "description": "", "scope": "arg", "related_color": "300", "parent_group": "verde", "color": "#B9CE39", "variant": [{"variant": "light", "color": "#DEE8A3", "name": "Lima claro", "code": "arg-lima-light"}, {"variant": "dark", "color": "#6EA015", "name": "Lima oscuro", "code": "arg-lima-dark"}], "alias": [{"code": "arg-lima", "exclude": false}, {"code": "limon", "exclude": true}, {"code": "lima", "exclude": true}]}]}, {"scope": "arg", "name": "Amarillo", "group": "amarillo", "color": {"50": "#FFFAE8", "100": "#FFF1C0", "200": "#FFE997", "300": "#FFE06E", "400": "#FFD745", "500": "#FFCE1C", "600": "#D8AE18", "700": "#B18F15", "800": "#8A6F12", "900": "#634F0E"}, "instance": [{"name": "Ma\u00edz", "code": "arg-maiz", "description": "", "scope": "arg", "related_color": "500", "parent_group": "amarillo", "color": "#FFCE1C", "variant": [{"variant": "light", "color": "#FFE997", "name": "Ma\u00edz claro", "code": "arg-maiz-light"}, {"variant": "dark", "color": "#B18F15", "name": "Ma\u00edz oscuro", "code": "arg-maiz-dark"}], "alias": [{"code": "arg-maiz", "exclude": false}, {"code": "maiz", "exclude": true}]}]}, {"scope": "arg", "name": "Fucsia", "group": "fucsia", "color": {"50": "#FCDDE6", "100": "#F8B6C9", "200": "#F48EAB", "300": "#F16798", "400": "#ED3F85", "500": "#EC407A", "600": "#D72C6B", "700": "#C2185B", "800": "#9A144A", "900": "#721038"}, "instance": [{"name": "Ar\u00e1ndano", "code": "arg-arandano", "description": "", "scope": "arg", "related_color": "700", "parent_group": "fucsia", "color": "#C2185B", "variant": [{"variant": "light", "color": "#EC407A", "name": "Ar\u00e1ndano claro", "code": "arg-arandano-light"}, {"variant": "dark", "color": "#721038", "name": "Ar\u00e1ndano oscuro", "code": "arg-arandano-dark"}, {"variant": "half", "color": "#E18CAD", "name": "Ar\u00e1ndano medio tono", "code": "arg-arandano-half"}, {"variant": "lighter", "color": "#FCDDE6", "name": "Ar\u00e1ndano muy claro", "code": "arg-arandano-lighter"}], "alias": [{"code": "arg-arandano", "exclude": false}, {"code": "arandano", "exclude": true}]}, {"name": "Fucsia", "code": "arg-fucsia", "description": "", "scope": "arg", "related_color": "500", "parent_group": "fucsia", "color": "#EC407A", "variant": [{"variant": "light", "color": "#F16798", "name": "Fucsia claro", "code": "arg-fucsia-light"}, {"variant": "dark", "color": "#9A144A", "name": "Fucsia oscuro", "code": "arg-fucsia-dark"}], "alias": [{"code": "arg-fucsia", "exclude": false}, {"code": "cereza", "exclude": true}, {"code": "fucsia", "exclude": true}]}, {"name": "Rosado", "code": "arg-rosado", "description": "", "scope": "arg", "related_color": "200", "parent_group": "fucsia", "color": "#F48EAB", "variant": [{"variant": "light", "color": "#FCDDE6", "name": "Rosado claro", "code": "arg-rosado-light"}, {"variant": "dark", "color": "#ED3F85", "name": "Rosado oscuro", "code": "arg-rosado-dark"}, {"variant": "half", "color": "#FAC7D5", "name": "Rosado medio tono", "code": "arg-rosado-half"}], "alias": [{"code": "arg-rosado", "exclude": false}]}]}, {"scope": "arg", "name": "Violeta", "group": "violeta", "color": {"50": "#E9E6F2", "100": "#D3CEE5", "200": "#BEB5D8", "300": "#A89DCB", "400": "#9284BE", "500": "#8561B2", "700": "#6A1B99", "800": "#4B0F7A", "900": "#2C035C", "600": "#773EA5"}, "instance": [{"name": "Lavanda", "code": "arg-lavanda", "description": "", "scope": "arg", "related_color": "400", "parent_group": "violeta", "color": "#9284BE", "variant": [], "alias": [{"code": "arg-lavanda", "exclude": false}, {"code": "lavanda", "exclude": true}]}, {"name": "Uva", "code": "arg-uva", "description": "", "scope": "arg", "related_color": "700", "parent_group": "violeta", "color": "#6A1B99", "variant": [], "alias": [{"code": "arg-uva", "exclude": false}, {"code": "uva", "exclude": true}]}]}, {"scope": "arg", "name": "Negro", "group": "negro", "color": {"50": "#F0F0F0", "100": "#E9E9E9", "200": "#DDDDDD", "300": "#838383", "150": "#DEE2E6", "75": "#F2F2F2", "500": "#555555", "600": "#444444", "900": "#141414", "25": "#FFFFFF"}, "instance": [{"name": "Negro", "code": "arg-negro", "description": "Elementos b\u00e1sicos", "scope": "arg", "related_color": "900", "parent_group": "negro", "color": "#141414", "variant": [{"variant": "lighter", "color": "#F0F0F0", "name": "Negro muy claro", "code": "arg-negro-lighter"}, {"variant": "light", "color": "#DDDDDD", "name": "Gris", "code": "arg-negro-light"}], "alias": [{"code": "arg-negro", "exclude": false}, {"code": "negro", "exclude": true}, {"code": "black", "exclude": true}, {"code": "gray-base", "exclude": true}]}, {"name": "Default", "code": "arg-default", "description": "", "scope": "arg", "related_color": "300", "parent_group": "negro", "color": "#838383", "variant": [], "alias": [{"code": "arg-default", "exclude": false}, {"code": "default", "exclude": true}]}, {"name": "Gray light", "code": "arg-gray-light", "description": "", "scope": "arg", "related_color": "200", "parent_group": "negro", "color": "#DDDDDD", "variant": [], "alias": [{"code": "arg-gray-light", "exclude": false}, {"code": "gray-light", "exclude": true}]}, {"name": "Gray hover", "code": "arg-gray-hover", "description": "", "scope": "arg", "related_color": "100", "parent_group": "negro", "color": "#E9E9E9", "variant": [], "alias": [{"code": "arg-gray-hover", "exclude": false}, {"code": "gray-hover", "exclude": true}]}, {"name": "Gray hover light", "code": "arg-gray-hover-light", "description": "", "scope": "arg", "related_color": "50", "parent_group": "negro", "color": "#F0F0F0", "variant": [], "alias": [{"code": "arg-gray-hover-light", "exclude": false}, {"code": "gray-hover-light", "exclude": true}]}, {"name": "Gris intermedio", "code": "arg-gris-intermedio", "description": "", "scope": "arg", "related_color": "500", "parent_group": "negro", "color": "#555555", "variant": [], "alias": [{"code": "arg-gris-intermedio", "exclude": false}, {"code": "gray", "exclude": true}, {"code": "grisintermedio", "exclude": true}, {"code": "gris-area", "exclude": true}, {"code": "gris", "exclude": false}]}, {"name": "Gray dark", "code": "arg-gray-dark", "description": "", "scope": "arg", "related_color": "600", "parent_group": "negro", "color": "#444444", "variant": [], "alias": [{"code": "arg-gray-dark", "exclude": false}, {"code": "gray-dark", "exclude": true}]}, {"name": "Gray border", "code": "arg-gray-border", "description": "", "scope": "arg", "related_color": "150", "parent_group": "negro", "color": "#DEE2E6", "variant": [], "alias": [{"code": "arg-gray-border", "exclude": false}, {"code": "gray-border", "exclude": true}]}, {"name": "Gris niebla", "code": "arg-gris-niebla", "description": "", "scope": "arg", "related_color": "75", "parent_group": "negro", "color": "#F2F2F2", "variant": [], "alias": [{"code": "arg-gris-niebla", "exclude": false}, {"code": "gray-lighter", "exclude": true}]}, {"name": "Gray background", "code": "arg-gray-background", "description": "", "scope": "arg", "related_color": "25", "parent_group": "negro", "color": "#FFFFFF", "variant": [], "alias": [{"code": "arg-gray-background", "exclude": false}, {"code": "gray-background", "exclude": true}]}]}, {"scope": "arg", "name": "Turquesa", "group": "turquesa", "color": {"50": "#DCF1F0", "100": "#C0E5E3", "200": "#A4D9D7", "300": "#88CECB", "400": "#6CC3BE", "500": "#50B7B2", "600": "#459E99", "700": "#3B8681", "800": "#306D69", "900": "#255450"}, "instance": [{"name": "Palta", "code": "arg-palta", "description": "", "scope": "arg", "related_color": "500", "parent_group": "turquesa", "color": "#50B7B2", "variant": [{"variant": "half", "color": "#A8DBD9", "name": "Palta medio tono", "code": "arg-palta-half"}, {"variant": "lighter", "color": "#C0E5E3", "name": "Palta muy claro", "code": "arg-palta-lighter"}], "alias": [{"code": "arg-palta", "exclude": false}, {"code": "palta", "exclude": true}]}, {"name": "Verde azulado", "code": "arg-verde-azulado", "description": "", "scope": "arg", "related_color": "700", "parent_group": "turquesa", "color": "#3B8681", "variant": [], "alias": [{"code": "arg-verde-azulado", "exclude": false}, {"code": "verde-azulado", "exclude": true}, {"code": "verdeazulado", "exclude": true}]}, {"name": "Eucalipto", "code": "arg-eucalipto", "description": "", "scope": "arg", "related_color": "800", "parent_group": "turquesa", "color": "#306D69", "variant": [{"variant": "lighter", "color": "#A4D9D7", "name": "Eucalipto muy claro", "code": "arg-eucalipto-lighter"}, {"variant": "dark", "color": "#255450", "name": "Eucalipto oscuro", "code": "arg-eucalipto-dark"}], "alias": [{"code": "arg-eucalipto", "exclude": false}]}]}, {"scope": "arg", "name": "Azul", "group": "azul", "color": {"50": "#CDEBFA", "100": "#9AD7F5", "200": "#68C3EF", "300": "#35AFEA", "400": "#039BE5", "500": "#0581C6", "600": "#0767A7", "700": "#084E87", "800": "#0A3468", "900": "#0C1A49"}, "instance": [{"name": "Cielo", "code": "arg-cielo", "description": "", "scope": "arg", "related_color": "400", "parent_group": "azul", "color": "#039BE5", "variant": [], "alias": [{"code": "arg-cielo", "exclude": false}, {"code": "cielo", "exclude": true}, {"code": "celeste", "exclude": true}]}, {"name": "Escarapela", "code": "arg-escarapela", "description": "", "scope": "arg", "related_color": "200", "parent_group": "azul", "color": "#68C3EF", "variant": [], "alias": [{"code": "arg-escarapela", "exclude": false}, {"code": "escarapela", "exclude": true}, {"code": "celesteargentina", "exclude": true}, {"code": "celeste-argentina", "exclude": false}]}]}, {"scope": "arg", "name": "Rojo", "group": "rojo", "color": {"50": "#FCDDDC", "100": "#F9BBB9", "200": "#F69896", "300": "#F27673", "400": "#EF5350", "500": "#E14543", "600": "#D43635", "700": "#C62828", "800": "#A12222", "900": "#7C1C1C"}, "instance": [{"name": "Rojo", "code": "arg-rojo", "description": "Atenci\u00f3n o peligro", "scope": "arg", "related_color": "700", "parent_group": "rojo", "color": "#C62828", "variant": [{"variant": "light", "color": "#E14543", "name": "Rojo claro", "code": "arg-rojo-light"}, {"variant": "dark", "color": "#7C1C1C", "name": "Rojo oscuro", "code": "arg-rojo-dark"}, {"variant": "lighter", "color": "#FCDDDC", "name": "Rojo muy claro", "code": "arg-rojo-lighter"}], "alias": [{"code": "arg-rojo", "exclude": false}, {"code": "danger", "exclude": true}, {"code": "rojo", "exclude": true}]}, {"name": "Tomate", "code": "arg-tomate", "description": "", "scope": "arg", "related_color": "400", "parent_group": "rojo", "color": "#EF5350", "variant": [{"variant": "light", "color": "#F69896", "name": "Tomate claro", "code": "arg-tomate-light"}, {"variant": "dark", "color": "#C62828", "name": "Tomate oscuro", "code": "arg-tomate-dark"}], "alias": [{"code": "arg-tomate", "exclude": false}, {"code": "complementary", "exclude": true}, {"code": "tomate", "exclude": true}]}]}, {"scope": "arg", "name": "Naranja", "group": "naranja", "color": {"50": "#FDE7BF", "100": "#FBCE80", "200": "#F9B640", "300": "#F79D00", "400": "#F38500", "500": "#EF6C00", "600": "#CE5701", "700": "#AE4203", "800": "#8D2D04", "900": "#6C1805"}, "instance": [{"name": "Marr\u00f3n claro", "code": "arg-marron-claro", "description": "", "scope": "arg", "related_color": "800", "parent_group": "naranja", "color": "#8D2D04", "variant": [{"variant": "light", "color": "#CE5701", "name": "Marr\u00f3n claro claro", "code": "arg-marron-claro-light"}, {"variant": "dark", "color": "#6C1805", "name": "Marr\u00f3n claro oscuro", "code": "arg-marron-claro-dark"}], "alias": [{"code": "arg-marron-claro", "exclude": false}, {"code": "marron-claro", "exclude": true}]}, {"name": "Naranja", "code": "arg-naranja", "description": "", "scope": "arg", "related_color": "500", "parent_group": "naranja", "color": "#EF6C00", "variant": [{"variant": "light", "color": "#EF6C00", "name": "Naranja claro", "code": "arg-naranja-light"}, {"variant": "dark", "color": "#6C1805", "name": "Naranja oscuro", "code": "arg-naranja-dark"}], "alias": [{"code": "arg-naranja", "exclude": false}, {"code": "naranjaoscuro", "exclude": true}, {"code": "naranja", "exclude": true}]}, {"name": "Mandarina", "code": "arg-mandarina", "description": "", "scope": "arg", "related_color": "300", "parent_group": "naranja", "color": "#F79D00", "variant": [{"variant": "light", "color": "#FBCE80", "name": "Mandarina claro", "code": "arg-mandarina-light"}, {"variant": "dark", "color": "#CE5701", "name": "Mandarina oscuro", "code": "arg-mandarina-dark"}], "alias": [{"code": "arg-mandarina", "exclude": false}, {"code": "mandarina", "exclude": true}]}]}, {"scope": "arg", "name": "Blanco", "group": "blanco", "color": {"150": "#FFFFFF"}, "instance": [{"name": "Blanco", "code": "arg-white", "description": "", "scope": "arg", "related_color": "150", "parent_group": "blanco", "color": "#FFFFFF", "variant": [], "alias": [{"code": "arg-white", "exclude": false}, {"code": "white", "exclude": true}]}]}, {"scope": "arg", "name": "Ocre", "group": "ocre", "color": {"50": "#FAF8ED", "100": "#F4F0DB", "200": "#EAE1B7", "300": "#E9CE8C", "400": "#E7BA61", "500": "#C98941", "600": "#AA5821", "700": "#8C2701", "800": "#6F2001", "900": "#511901"}, "instance": [{"name": "Arena", "code": "arg-arena", "description": "", "scope": "arg", "related_color": "200", "parent_group": "ocre", "color": "#EAE1B7", "variant": [{"variant": "light", "color": "#FAF8ED", "name": "Arena claro", "code": "arg-arena-light"}, {"variant": "dark", "color": "#E7BA61", "name": "Arena oscuro", "code": "arg-arena-dark"}, {"variant": "half", "color": "#F5F0DB", "name": "Arena medio tono", "code": "arg-arena-half"}], "alias": [{"code": "arg-arena", "exclude": false}]}, {"name": "Amarillo", "code": "arg-amarillo", "description": "Foco o alerta", "scope": "arg", "related_color": "400", "parent_group": "ocre", "color": "#E7BA61", "variant": [{"variant": "light", "color": "#EAE1B7", "name": "Amarillo claro", "code": "arg-amarillo-light"}, {"variant": "dark", "color": "#AA5821", "name": "Amarillo oscuro", "code": "arg-amarillo-dark"}, {"variant": "half", "color": "#F3DDB0", "name": "Amarillo medio tono", "code": "arg-amarillo-half"}], "alias": [{"code": "arg-amarillo", "exclude": false}, {"code": "warning", "exclude": true}, {"code": "amarillo", "exclude": true}, {"code": "amarillo-intenso", "exclude": true}]}, {"name": "Marr\u00f3n oscuro", "code": "arg-marron-oscuro", "description": "", "scope": "arg", "related_color": "900", "parent_group": "ocre", "color": "#511901", "variant": [], "alias": [{"code": "arg-marron-oscuro", "exclude": false}]}]}, {"scope": "arg", "name": "Morado", "group": "morado", "color": {"150": "#3A3796"}, "instance": [{"name": "Azul morado", "code": "arg-azul-morado", "description": "", "scope": "arg", "related_color": "150", "parent_group": "morado", "color": "#3A3796", "variant": [], "alias": [{"code": "arg-azul-morado", "exclude": false}]}]}]}, {"name": "MiArgentina", "space": "miarg", "hidden_space": false, "description": "", "data": [{"scope": "miarg", "name": "Azul MiArgentina", "group": "azul", "color": {"150": "#3526C3"}, "instance": [{"name": "Azul MiArgentina", "code": "miarg-azul", "description": "Azul principal para aplicaciones MiArgentina", "scope": "miarg", "related_color": "150", "parent_group": "azul", "color": "#3526C3", "variant": [{"variant": "half", "color": "#6B66CC", "name": "Azul MiArgentina medio tono", "code": "miarg-azul-half"}], "alias": [{"code": "miarg-azul", "exclude": false}]}]}, {"scope": "miarg", "name": "Celeste MiArgentina", "group": "celeste", "color": {"150": "#2CB9EE"}, "instance": [{"name": "Celeste MiArgentina", "code": "miarg-celeste", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "celeste", "color": "#2CB9EE", "variant": [], "alias": [{"code": "miarg-celeste", "exclude": false}]}]}, {"scope": "miarg", "name": "Amarillo claro MiArgentina", "group": "amarillo-claro", "color": {"150": "#ffe9b8"}, "instance": [{"name": "Amarillo claro MiArgentina", "code": "miarg-amarillo-claro", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "amarillo-claro", "color": "#ffe9b8", "variant": [], "alias": [{"code": "miarg-amarillo-claro", "exclude": false}]}]}, {"scope": "miarg", "name": "Rosa claro MiArgentina", "group": "rosa-claro", "color": {"150": "#EECCCF"}, "instance": [{"name": "Rosa claro MiArgentina", "code": "miarg-rosa-claro", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "rosa-claro", "color": "#EECCCF", "variant": [], "alias": [{"code": "miarg-rosa-claro", "exclude": false}]}]}, {"scope": "miarg", "name": "Verde claro MiArgentina", "group": "verde-claro", "color": {"150": "#CFEEDC"}, "instance": [{"name": "Verde claro MiArgentina", "code": "miarg-verde-claro", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "verde-claro", "color": "#CFEEDC", "variant": [], "alias": [{"code": "miarg-verde-claro", "exclude": false}]}]}, {"scope": "miarg", "name": "Azul oscuro MiArgentina", "group": "azul-oscuro", "color": {"150": "#222C50"}, "instance": [{"name": "Azul oscuro MiArgentina", "code": "miarg-oscuro", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "azul-oscuro", "color": "#222C50", "variant": [], "alias": [{"code": "miarg-oscuro", "exclude": false}]}]}, {"scope": "miarg", "name": "Gris MiArgentina", "group": "gris", "color": {"150": "#7E848E"}, "instance": [{"name": "Gris MiArgentina", "code": "miarg-gris", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "gris", "color": "#7E848E", "variant": [], "alias": [{"code": "miarg-gris", "exclude": false}]}]}, {"scope": "miarg", "name": "Celeste claro MiArgentina", "group": "celeste-claro", "color": {"150": "#BEE6F6"}, "instance": [{"name": "Celeste claro MiArgentina", "code": "miarg-celeste-claro", "description": "", "scope": "miarg", "related_color": "150", "parent_group": "celeste-claro", "color": "#BEE6F6", "variant": [], "alias": [{"code": "miarg-celeste-claro", "exclude": false}]}]}]}, {"name": "Colores de la bandera de la Rep\u00fablica Argentina", "space": "bandera", "hidden_space": false, "description": "De acuerdo al <a href=\"https://www.argentina.gob.ar/normativa/nacional/decreto-1650-2010-175328\">Decreto 1650/2010</a>, que establece las medidas, caracter\u00edsticas de la tela, colores y accesorios de la Bandera Argentina.", "data": [{"scope": "bandera", "name": "Amarillo", "group": "amarillo", "color": {"150": "#FCBF49"}, "instance": [{"name": "Amarillo Bandera", "code": "bandera-amarillo", "description": "Color amarillo oficial para la bandera Argentina", "scope": "bandera", "related_color": "150", "parent_group": "amarillo", "color": "#FCBF49", "variant": [], "alias": [{"code": "bandera-amarillo", "exclude": false}]}]}, {"scope": "bandera", "name": "Celeste", "group": "celeste", "color": {"150": "#75AADB"}, "instance": [{"name": "Celeste Bandera", "code": "bandera-celeste", "description": "Color celeste oficial para la bandera Argentina", "scope": "bandera", "related_color": "150", "parent_group": "celeste", "color": "#75AADB", "variant": [], "alias": [{"code": "bandera-celeste", "exclude": false}]}]}, {"scope": "bandera", "name": "Marr\u00f3n", "group": "marron", "color": {"150": "#843511"}, "instance": [{"name": "Marr\u00f3n Bandera", "code": "bandera-marron", "description": "Color marr\u00f3n oficial para la bandera Argentina", "scope": "bandera", "related_color": "150", "parent_group": "marron", "color": "#843511", "variant": [], "alias": [{"code": "bandera-marron", "exclude": false}]}]}]}, {"name": "Gendarmer\u00eda Nacional", "space": "gna", "hidden_space": false, "description": "", "data": [{"scope": "gna", "name": "Verde jade", "group": "verde-jade", "color": {"150": "#006666"}, "instance": [{"name": "Verde oscuro Gendarmer\u00eda", "code": "gna-verde-jade", "description": "", "scope": "gna", "related_color": "150", "parent_group": "verde-jade", "color": "#006666", "variant": [], "alias": [{"code": "gna-verde-jade", "exclude": false}, {"code": "verde-jade", "exclude": true}, {"code": "verdejade", "exclude": true}]}]}, {"scope": "gna", "name": "Verde aloe", "group": "verde-aloe", "color": {"150": "#4FBB73"}, "instance": [{"name": "Verde claro Gendarmer\u00eda", "code": "gna-verde-aloe", "description": "", "scope": "gna", "related_color": "150", "parent_group": "verde-aloe", "color": "#4FBB73", "variant": [], "alias": [{"code": "gna-verde-aloe", "exclude": false}, {"code": "verde-aloe", "exclude": true}]}]}, {"scope": "gna", "name": "Verde cemento", "group": "verde-cemento", "color": {"150": "#B4BEBA"}, "instance": [{"name": "Gris Gendarmer\u00eda", "code": "gna-verde-cemento", "description": "", "scope": "gna", "related_color": "150", "parent_group": "verde-cemento", "color": "#B4BEBA", "variant": [], "alias": [{"code": "gna-verde-cemento", "exclude": false}, {"code": "verde-cemento", "exclude": true}, {"code": "verdecemento", "exclude": true}]}]}]}];
29
+
30
+ if (typeof exports !== "undefined") {
31
+ module.exports = {
32
+ ponchoColorDefinitionsList,
33
+ };
34
+ }
35
+
36
+
37
+ /**
38
+ * Configuración de colores www.argentina.gob.ar
39
+ *
40
+ * MIT License
41
+ *
42
+ * Copyright (c) 2024 Argentina.gob.ar
43
+ *
44
+ * Permission is hereby granted, free of charge, to any person
45
+ * obtaining a copy of this software and associated documentation
46
+ * files (the "Software"), to deal in the Software without restriction,
47
+ * including without limitation the rightsto use, copy, modify, merge,
48
+ * publish, distribute, sublicense, and/or sell copies of the Software,
49
+ * and to permit persons to whom the Software is furnished to do so,
50
+ * subject to the following conditions:
51
+ *
52
+ * The above copyright notice and this permission notice shall be
53
+ * included in all copies or substantial portions of the Software.
54
+ *
55
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
56
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
58
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
59
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
60
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
61
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
62
+ * SOFTWARE.
63
+ */
64
+ class Color { //jslint-ignore-line
65
+ constructor(colorDefinitions){
66
+ if(!this.isValidColorDefinitionList(colorDefinitions)){
67
+ console.error("No se pasado por argumento el listado de color");
68
+ return;
69
+ }
70
+ this.definitions = colorDefinitions;
71
+ }
72
+
73
+
74
+ /**
75
+ * Remueve acentos y caracteres especiales.
76
+ *
77
+ * @param {string} data Cadena de texto a limpiar.
78
+ * @example
79
+ * // returns Accion Murcielago arbol nino
80
+ * removeAccents("Acción Murciélago árbol niño")
81
+ * @returns {string} Cadena de texto sin acentos.
82
+ */
83
+ replaceSpecialChars = (data) => {
84
+ if(typeof data !== "string" || data.trim().length === 0){
85
+ console.warn("replaceSpecialChars: Debe pasar una cadena de texto.");
86
+ return "";
87
+ }
88
+
89
+ const search = "àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕ"
90
+ + "ŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż";
91
+ const replace = "aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnooooooooop"
92
+ + "rrsssssttuuuuuuuuuwxyyzzz";
93
+
94
+ const a = search + search.toUpperCase();
95
+ const b = replace + replace.toUpperCase();
96
+ const p = new RegExp(a.split("").join("|"), "g");
97
+ return data.toString().replace(p, c => b.charAt(a.indexOf(c)));
98
+ };
99
+
100
+
101
+ /**
102
+ *
103
+ * @param {array} definitions
104
+ * @returns {boolean}
105
+ */
106
+ isValidColorDefinitionList(definitions){
107
+ return (
108
+ Array.isArray(definitions) &&
109
+ definitions.length > 0 &&
110
+ definitions[0].hasOwnProperty('space')
111
+ );
112
+ }
113
+
114
+
115
+ /**
116
+ * Listado de colores
117
+ * @returns {object}
118
+ */
119
+ get list(){
120
+ let result = this.definitions
121
+ .flatMap( m => m.data.flatMap(i => i.instance.map(x => x)) );
122
+
123
+ return result || [];
124
+ }
125
+
126
+
127
+ /**
128
+ * Buscador de colores.
129
+ *
130
+ * @param {string} value Color a buscar.
131
+ * @returns {object}
132
+ */
133
+ findColor = value => {
134
+ if(typeof value !== "string" || value.trim().length === 0){
135
+ console.error(
136
+ "findColor:",
137
+ "El valor a buscar debe ser una cadena de texto.");
138
+ return [];
139
+ }
140
+ let searchTerm = value.toLowerCase();
141
+ let searchList = [
142
+ ...this.variables.map(([code, color]) => [code, color]),
143
+ ...this.colors];
144
+
145
+ let searchResults = searchList.filter( function(item){
146
+ if( item[0].includes( searchTerm ) ){
147
+ return item;
148
+ }
149
+ }).map(([code, color]) => [code, color]);
150
+
151
+ return searchResults;
152
+ }
153
+
154
+
155
+ /**
156
+ *
157
+ * @param {*} colorDefinitions
158
+ * @returns
159
+ */
160
+ get variables(){
161
+ let collect = [];
162
+
163
+ this.list.flatMap(m => {
164
+ const {alias, color, description, code, variant=[], name} = m;
165
+
166
+ alias.forEach(function(a){
167
+ collect.push( [a.code, color, description, code, name] );
168
+
169
+ variant.forEach(function(value){
170
+ if(!a.exclude){
171
+ collect.push( [`${a.code}-${value.variant}`, value.color, "", code, value.name] );
172
+ }
173
+ });
174
+ })
175
+ });
176
+ return collect.sort();
177
+ };
178
+
179
+
180
+ get spaces(){
181
+ return this.definitions.map(m => m.space).sort();
182
+ }
183
+
184
+
185
+ groupsBySpace = space => {
186
+ if (typeof space !== 'string') {
187
+ throw new TypeError('groupsBySpace: El argumetno debe ser un string');
188
+ }
189
+ const spaceToLower = space.toLocaleLowerCase();
190
+ const data = this.definitions
191
+ .find(f => f.space == spaceToLower)?.data?.map(m => m.group);
192
+
193
+ const result = data ? data.sort() : [];
194
+ return result;
195
+ }
196
+
197
+
198
+ /**
199
+ * Colores poncho a hexa
200
+ *
201
+ * @see https://argob.github.io/poncho/identidad/colores/
202
+ * @param {string} color Nombre de color Poncho.
203
+ * @example
204
+ * // returns "#2897d4"
205
+ * getColor("celeste")
206
+ * @returns {string} Color en formato hexadecimal.
207
+ */
208
+ ponchoColor = color => {
209
+ const defaultColor = "#999999";
210
+ const self = this;
211
+
212
+ if (typeof color !== "string") {
213
+ console.warn(
214
+ `Invalid color provided. Using default: ${defaultColor}`
215
+ );
216
+ return defaultColor;
217
+ }
218
+
219
+ const searchTerm = self.replaceSpecialChars(color).toLowerCase();
220
+
221
+ const definition = (this.variables.find(v => v[0] === searchTerm) ||
222
+ this.colors.find(c => c[0] === searchTerm));
223
+
224
+ return (definition ? definition[1] : defaultColor);
225
+ };
226
+
227
+
228
+ /**
229
+ * Listado de colores
230
+ * @returns
231
+ */
232
+ get colors(){
233
+ const colorList = this.definitions
234
+ .map(space => space.data)
235
+ .flatMap(function(spaceGroups){
236
+
237
+ return spaceGroups.flatMap(function(groupColor){
238
+ const {color, group, scope} = groupColor;
239
+ return Object.entries(color).map(function(colorValues){
240
+ const [label, value] = colorValues;
241
+ return [`${scope}-${group}-${label}`, value]
242
+ });
243
+ });
244
+ });
245
+
246
+ return colorList || [];
247
+ }
248
+
249
+
250
+ /**
251
+ * Definición por color
252
+ *
253
+ * @see colorDefinitionsList
254
+ * @param {string} color Nombre del cólor a buscar.
255
+ * @returns {string|boolean}
256
+ */
257
+ colorDefinitions = (ponchoColor) => {
258
+ if(typeof ponchoColor == undefined || !ponchoColor.trim()){
259
+ return;
260
+ }
261
+
262
+ const lowerCasePonchoColor = this.replaceSpecialChars(ponchoColor).toLowerCase();
263
+ let result;
264
+ let gSpace = "";
265
+
266
+ // Iteración por espacios (space)
267
+ for(let i = 0; i <= this.definitions.length - 1; i += 1){
268
+ const {data, space} = this.definitions[i];
269
+ gSpace = space;
270
+
271
+ // Itero por cada grupo de color dentro de data
272
+ for(let y = 0; y <= data.length - 1; y += 1) {
273
+ const {instance} = data[y];
274
+
275
+ // Itero sobre las instancias de color
276
+ for(let x = 0; x <= instance.length - 1; x += 1) {
277
+ const {alias, variant} = instance[x];
278
+ debugger
279
+ if ( alias.some(s => s.code == lowerCasePonchoColor) ) {
280
+ result = instance[x];
281
+ break;
282
+ }
283
+ else if( variant.some(s => s.code == lowerCasePonchoColor) ){
284
+ result = instance[x];
285
+ break;
286
+ }
287
+ }
288
+ if (result) break;
289
+ }
290
+ }
291
+
292
+ return result;
293
+ };
294
+
295
+
296
+ /**
297
+ * Grupo de color
298
+ * @param {string} name Nombre del grupo
299
+ * @returns
300
+ */
301
+ colorGroup = (themeSpace, spaceGroup) => {
302
+ if(typeof spaceGroup == undefined || !spaceGroup?.trim()){
303
+ return;
304
+ }
305
+
306
+ let result;
307
+ for(let i = 0; i <= this.definitions.length -1; i += 1){
308
+ const {data, space} = this.definitions[i];
309
+ result = data.find(obj => (obj.group==spaceGroup && space==themeSpace));
310
+ if (result) break;
311
+ }
312
+ return result;
313
+ };
314
+
315
+
316
+ /**
317
+ * Espacio de color
318
+ * @param {string} name Nombre del espacio
319
+ * @returns
320
+ */
321
+ colorSpace = (space) => {
322
+ if(typeof space == undefined || !space?.trim()){
323
+ return;
324
+ }
325
+
326
+ return this.definitions.find(obj => obj.space==space);
327
+ };
328
+
329
+
330
+ /**
331
+ * Retorna el código de color poncho por hexadecimal.
332
+ * @param {string} value Valor hexadecimal a buscar
333
+ * @see colorDefinitionsList
334
+ * @example
335
+ * // {
336
+ * // "description": "",
337
+ * // "name": "Mandarina",
338
+ * // "color": "#f79525",
339
+ * // "code": "mandarina",
340
+ * // "alias": [
341
+ * // "mandarina"
342
+ * // ]
343
+ * // }
344
+ * findByHex("#f79525");
345
+ * @returns {object} Objecto con la defición del color
346
+ */
347
+ colorByHex = (hexColor) => {
348
+ if(!this.isValidHex(hexColor)){
349
+ return;
350
+ }
351
+
352
+ var result = [];
353
+ const targetColor = this.cleanHex(hexColor);
354
+
355
+ for(let i = 0; i <= this.definitions.length -1; i += 1){
356
+ let {data} = this.definitions[i];
357
+
358
+ for(let entry of data){
359
+ const {instance} = entry;
360
+ for(let item of instance){
361
+ const {color} = item;
362
+ if( this.cleanHex(color) == targetColor ){
363
+ result.push(item);
364
+ }
365
+ }
366
+ }
367
+ }
368
+ return result;
369
+ };
370
+
371
+
372
+ /**
373
+ * Hace un refactor del número hexa
374
+ *
375
+ * @param {string} value Valor hexadecimal
376
+ * @returns {string}
377
+ */
378
+ cleanHex = value => {
379
+ let hex = value
380
+ .toString()
381
+ .replace("#", "")
382
+ .trim()
383
+ .toUpperCase();
384
+
385
+ if (hex.length < 3 || hex.length > 6){
386
+ return false;
387
+ } else if(hex.length == 3){
388
+ hex = Array.from(hex).map(a => a.repeat(2)).join("");
389
+ }
390
+ return `#${hex}`;
391
+ };
392
+
393
+
394
+ /**
395
+ * Valida un color hexadecimal
396
+ * @param {string} hexColor Color hexadecimal
397
+ * @returns {boolean}
398
+ */
399
+ isValidHex = (hexColor) => {
400
+ if (hexColor === null || hexColor === undefined) {
401
+ return false;
402
+ }
403
+
404
+ if (typeof hexColor !== 'string') {
405
+ return false;
406
+ }
407
+
408
+ const regx = new RegExp(/^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/);
409
+ if (!regx.test(hexColor)) {
410
+ console.warn("Invalid hex color format:", hexColor);
411
+ return false;
412
+ }
413
+ return true;
414
+ };
415
+
416
+
417
+ /**
418
+ * Converson de HEX a RGB.
419
+ * @param {string} hexColor Color hexadecimal
420
+ * @returns {object}
421
+ */
422
+ hexToRgb = hexColor => {
423
+ if (!this.isValidHex(hexColor)) {
424
+ return;
425
+ }
426
+
427
+ const hex = this.cleanHex(hexColor);
428
+ const cleanedHex = (hex.startsWith("#") ? hex.slice(1) : hex);
429
+
430
+ const red = parseInt(cleanedHex.slice(0, 2), 16);
431
+ const green = parseInt(cleanedHex.slice(2, 4), 16);
432
+ const blue = parseInt(cleanedHex.slice(4, 6), 16);
433
+
434
+ return [red, green, blue];
435
+ }
436
+
437
+
438
+ /**
439
+ * Imprime el nombre de un color
440
+ *
441
+ * @param {array} args Array list [arg, arg, arg]
442
+ * @param {array} options object Objeto con opciones para los switch.
443
+ * @example
444
+ * // maíz - azul a verde
445
+ * colorName(
446
+ * ["arg-maiz", "arg-azul", "arg-verde"],
447
+ * {
448
+ * switchLastConnector: {'i': "a", "o": "a"},
449
+ * defaultLastConnector: "a",
450
+ * listConnector: " - "
451
+ * }
452
+ * )
453
+ * @returns {string}
454
+ */
455
+ colorName = (args, options={}) => {
456
+ if(typeof args == "undefined"){
457
+ return
458
+ }
459
+
460
+ if(args.length < 1){
461
+ console.error("Error.", "Debe pasar al menos un argumento.");
462
+ return;
463
+ }
464
+
465
+ if(typeof args == "string"){
466
+ args = [args];
467
+ }
468
+
469
+ if(!args.every(e => typeof e === "string")){
470
+ console.error("Error.", "Solo se admiten cadenas de texto");
471
+ return;
472
+ }
473
+
474
+ // Options
475
+ const defaultConnectorSwitch = {"i": "e", "o": "u"};
476
+ const defaultConnector = "y";
477
+ const defaultListConnector = ", ";
478
+
479
+ const optionConnectorSwitch = (typeof options == "object" &&
480
+ options.hasOwnProperty('switchLastConnector') ?
481
+ options.switchLastConnector : defaultConnectorSwitch);
482
+ const optionDefaultConnector = (typeof options == "object" &&
483
+ options.hasOwnProperty('defaultLastConnector') ?
484
+ options.defaultLastConnector : defaultConnector);
485
+ const optionDefaultListConnector = (typeof options == "object" &&
486
+ options.hasOwnProperty('listConnector') ?
487
+ options.listConnector : defaultListConnector);
488
+
489
+
490
+ const getColorName = (arg) => {
491
+ const result = this.variables.find(f => (f[0] == arg));
492
+ return typeof result != "undefined" ? result[4] : arg;
493
+ };
494
+
495
+ if (args.length === 1) {
496
+ return getColorName(args.join(""));
497
+ }
498
+
499
+ const totalArgs = args.length;
500
+ const lastArg = args.pop(totalArgs - 1);
501
+ const firstCharName = Array.from( getColorName(lastArg) )[0].toLowerCase();
502
+ const connector = (optionConnectorSwitch[firstCharName] ||
503
+ optionDefaultConnector);
504
+
505
+ const result = `${args.map(m => getColorName(m)).join(optionDefaultListConnector)} ${connector}`
506
+ + ` ${getColorName(lastArg)}`;
507
+
508
+ return result.toLowerCase();
509
+ };
510
+ }
511
+
512
+
513
+ if (typeof exports !== "undefined") {
514
+ module.exports = {Color};
515
+ }
516
+
517
+ /**
518
+ * Configuración de colores www.argentina.gob.ar
519
+ *
520
+ * MIT License
521
+ *
522
+ * Copyright (c) 2024 Argentina.gob.ar
523
+ *
524
+ * Permission is hereby granted, free of charge, to any person
525
+ * obtaining a copy of this software and associated documentation
526
+ * files (the "Software"), to deal in the Software without restriction,
527
+ * including without limitation the rightsto use, copy, modify, merge,
528
+ * publish, distribute, sublicense, and/or sell copies of the Software,
529
+ * and to permit persons to whom the Software is furnished to do so,
530
+ * subject to the following conditions:
531
+ *
532
+ * The above copyright notice and this permission notice shall be
533
+ * included in all copies or substantial portions of the Software.
534
+ *
535
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
536
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
537
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
538
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
539
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
540
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
541
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
542
+ * SOFTWARE.
543
+ */
544
+
545
+ /**
546
+ * Códigos de color válidos para utilizar en ilustraciones.
547
+ */
548
+ const illustrationColors = [
549
+ "arg-azul",
550
+ "arg-arena",
551
+ "arg-amarillo",
552
+ "arg-palta",
553
+ "arg-verde",
554
+ "arg-arandano",
555
+ "arg-rosado",
556
+ "miarg-azul",
557
+ ];
558
+
559
+ const headersBackground = {
560
+ solid: [
561
+ "bg-arg-azul",
562
+ "bg-arg-rojo",
563
+ "bg-arg-info",
564
+ "bg-arg-eucalipto",
565
+ "bg-arg-palta",
566
+ "bg-arg-arandano",
567
+ "bg-arg-negro-light"
568
+ ],
569
+ mixed: [
570
+ "bg-mix-azul-info",
571
+ "bg-mix-info-azul",
572
+ "bg-mix-palta-azul",
573
+ "bg-mix-azul-palta"
574
+ ]
575
+ };
576
+
577
+ /**
578
+ * Variaciones de color
579
+ */
580
+ const colorVariations = {
581
+ high: [
582
+ 'arg-azul', 'arg-eucalipto', 'arg-verde', 'arg-naranja', 'arg-rojo',
583
+ 'arg-arandano', 'arg-uva', 'arg-cielo', 'arg-palta', 'arg-verdin',
584
+ 'arg-amarillo', 'arg-tomate', 'arg-fucsia', 'arg-lavanda', 'arg-negro'
585
+ ],
586
+ medium: [
587
+ "arg-info","arg-verde-azulado","arg-verdin","arg-amarillo","arg-tomate",
588
+ "arg-fucsia","arg-lavanda","arg-palta","arg-lima","arg-maiz",
589
+ "arg-gris-intermedio"
590
+ ]
591
+ };
592
+
593
+
594
+ // @legacy Creo ponchoColor y color como una variable global.
595
+ var ponchoColor;
596
+ var color;
597
+ if (typeof Color !== 'undefined') {
598
+ color = new Color(ponchoColorDefinitionsList);
599
+ ponchoColor = color.ponchoColor;
600
+ }
601
+
602
+
603
+ if (typeof exports !== "undefined") {
604
+ module.exports = {
605
+ colorVariations, illustrationColors, headersBackground, color
606
+ };
607
+ }
608
+
609
+ /**
610
+ * Fetch data
611
+ *
612
+ * @example
613
+ * ```js
614
+ * (async() => {
615
+ * const data = await fetch_json("https://som.url.com");
616
+ * });
617
+ * ```
618
+ */
619
+ async function fetch_json(uri, options={}) {
620
+
621
+ let defaultOptions = {
622
+ method: "GET",
623
+ headers: {
624
+ "Accept": "application/json",
625
+ "Content-Type": "application/json"
626
+ },
627
+ redirect: "follow"
628
+ };
629
+ let opts = Object.assign({}, defaultOptions, options);
630
+ const response = await fetch(uri, opts);
631
+
632
+ if (!response.ok) {
633
+ throw new Error(`HTTP error! status: ${response.status}`);
634
+ }
635
+ return await response.json();
636
+ };
637
+
638
+ /**
639
+ * Remueve acentos y caracteres especiales.
640
+ *
641
+ * @param {string} data Cadena de texto a limpiar.
642
+ * @example
643
+ * // returns Accion Murcielago arbol nino
644
+ * removeAccents("Acción Murciélago árbol niño")
645
+ * @returns {string} Cadena de texto sin acentos.
646
+ */
647
+ const replaceSpecialChars = (data) => {
648
+ if(typeof data !== "string" || data.trim().length === 0){
649
+ console.warn("replaceSpecialChars: Debe pasar una cadena de texto.");
650
+ return "";
651
+ }
652
+
653
+ const search = "àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕ"
654
+ + "ŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż";
655
+ const replace = "aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnooooooooop"
656
+ + "rrsssssttuuuuuuuuuwxyyzzz";
657
+
658
+ const a = search + search.toUpperCase();
659
+ const b = replace + replace.toUpperCase();
660
+ const p = new RegExp(a.split("").join("|"), "g");
661
+ return data.toString().replace(p, c => b.charAt(a.indexOf(c)));
662
+ };
663
+
664
+
665
+ /**
666
+ * Slugify
667
+ *
668
+ * @param {string} string Cadena de texto a convertir.
669
+ * @example
670
+ * // returns el-murcielago-remolon-parece-un-nino
671
+ * slugify("El murciélago remolón parece un niño")
672
+ * @returns {string} Cadena de texto en formato slug.
673
+ */
674
+ const slugify = (str) =>{
675
+ if(typeof str !== "string" || str.trim().length === 0){
676
+ console.warn("slugify: Debe pasar una cadena de texto.");
677
+ return str;
678
+ }
679
+ const a = "àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕ"
680
+ + "ŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;";
681
+ const b = "aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnooooooooop"
682
+ + "rrsssssttuuuuuuuuuwxyyzzz------";
683
+ const p = new RegExp(a.split("").join("|"), "g");
684
+
685
+ return str.toString().toLowerCase()
686
+ .replace(/\s+/g, "-")
687
+ .replace(p, c => b.charAt(a.indexOf(c)))
688
+ .replace(/&/g, "-and-")
689
+ .replace(/[^\w\-]+/g, "")
690
+ .replace(/\-\-+/g, "-")
691
+ .replace(/^-+/, "")
692
+ .replace(/-+$/, "");
693
+ };
694
+
695
+
696
+ /**
697
+ * Palabras en title-case.
698
+ * @param {string} str Cadena a transformar
699
+ * @param {boolean} allWords True title-case a todas las palabras
700
+ * @returns {string}
701
+ */
702
+ const toTitleCase = (str, allWords=true) => {
703
+ if(typeof str !== "string" || str.trim().length === 0){
704
+ console.warn("[toTitleCase] Debe ingresar una cadena de texto.");
705
+ return str;
706
+ }
707
+ const titleCase = w => w[0].toUpperCase() + w.substring(1).toLowerCase();
708
+ str = str.replace(/(^\s+|\s+$)/g, "");
709
+
710
+ if(!allWords){
711
+ return titleCase(str);
712
+ }
713
+ const words = str.split(/\s+/);
714
+ return words.map(w => titleCase(w)).join(" ");
715
+ }
716
+
717
+
718
+ if (typeof exports !== "undefined") {
719
+ module.exports = {slugify, replaceSpecialChars, toTitleCase};
720
+ }
721
+
722
+ /**
723
+ * HTML utilities
724
+ *
725
+ * @summary Validadores y herramientas para manipulación de código HTML.
726
+ *
727
+ * ADVERTENCIA
728
+ *
729
+ * Estas funciones JavaScript no fueron realizadas con el propósito de
730
+ * proporcionar seguridad contra ataques externos en aplicaciones. Para
731
+ * proteger aplicaciones web construidas con JavaScript, es crucial
732
+ * implementar medidas de seguridad adicionales como validación de datos en
733
+ * el lado del servidor, protección contra inyección de código (XSS) y el
734
+ * uso de bibliotecas y frameworks que promuevan prácticas de
735
+ * seguridad sólidas.
736
+ *
737
+ * Si no está seguro de cómo utilizarla y los posibles riesgos que corre al
738
+ * exponerla en su sitio web, tome el recaudo de asesorarse con
739
+ * un especialista.
740
+ *
741
+ *
742
+ *
743
+ * MIT License
744
+ *
745
+ * Copyright (c) 2024 Argentina.gob.ar
746
+ *
747
+ * Permission is hereby granted, free of charge, to any person
748
+ * obtaining a copy of this software and associated documentation
749
+ * files (the "Software"), to deal in the Software without restriction,
750
+ * including without limitation the rightsto use, copy, modify, merge,
751
+ * publish, distribute, sublicense, and/or sell copies of the Software,
752
+ * and to permit persons to whom the Software is furnished to do so,
753
+ * subject to the following conditions:
754
+ *
755
+ * The above copyright notice and this permission notice shall be
756
+ * included in all copies or substantial portions of the Software.
757
+ *
758
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
759
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
760
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
761
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
762
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
763
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
764
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
765
+ * SOFTWARE.
766
+ */
767
+
768
+
769
+ /**
770
+ * Impide que se impriman etiquetas HTML.
771
+ *
772
+ * @summary Impide que se impriman etiquetas HTML exceptuando aquellas
773
+ * asignadas en el parámetro exclude.
774
+ * @param {string} str Cadena de texto a remplazar.
775
+ * @param {object} exclude Etiquetas que deben preservarse.
776
+ * @example
777
+ * // returns &lt;h1&gt;Hello world!&lt;/h1&gt; <a href="#">Link</a>
778
+ * secureHTML('<h1>Hello world!</h1> <a href="#">Link</a>', ["a"])
779
+ *
780
+ * @returns {string} Texto remplazado.
781
+ */
782
+ const secureHTML = (str, exclude=[]) => {
783
+ if(typeof str !== "string" || str.trim().length === 0){
784
+ console.error("secureHTML:", "Solo admite cadenas de texto.");
785
+ return str;
786
+ }
787
+
788
+ if(!Array.isArray(exclude)){
789
+ console.error(
790
+ "secureHTML:", "El segundo argumento debe ser un Array.");
791
+ return;
792
+ }
793
+
794
+ if(exclude.some(e => e === "*")){
795
+ return str;
796
+ }
797
+
798
+ let replaceString = str.toString()
799
+ .replace(/</g, "&lt;")
800
+ .replace(/>/g, "&gt;");
801
+
802
+ if(exclude.length > 0){
803
+ const regexStart = new RegExp(
804
+ "&lt;(" + exclude.join("|") + ")(.*?)&gt;", "g");
805
+ const regexEnd = new RegExp(
806
+ "&lt;\/(" + exclude.join("|") + ")(.*?)&gt;", "g");
807
+
808
+ return replaceString
809
+ .replace(regexStart, "<$1$2>")
810
+ .replace(regexEnd, "</$1>");
811
+ }
812
+ return replaceString;
813
+ };
814
+
815
+
816
+ if (typeof exports !== "undefined") {
817
+ module.exports = {secureHTML};
818
+ }
819
+
820
+
821
+ /**
822
+ * HEAD STYLE
823
+ *
824
+ * @summary Permite agregar definiciones css dentro del head.
825
+ *
826
+ * @author Agustín Bouillet <bouilleta@jefatura.gob.ar>
827
+ * @param {string} id Nombre único para identificar las asignaciones css
828
+ * @param {string} styleDefinitions Definiciones CSS
829
+ * @param {string} mediaType Definición para media query
830
+ * @example
831
+ * //<style id="custom-id">div {border: 2px solid red}</div>
832
+ * headStyle("custom-id", `div { border: 2px solid red}`);
833
+ *
834
+ * //<style id="custom-id" media="all and (max-width: 500px)">
835
+ * // div {border: 2px solid red}
836
+ * //</div>
837
+ * headStyle(
838
+ * "custom-id",
839
+ * `div { border: 2px solid red}`,
840
+ * "all and (max-width: 500px)"
841
+ * );
842
+ * @returns {undefined}
843
+ *
844
+ * MIT License
845
+ *
846
+ * Copyright (c) 2023 Argentina.gob.ar
847
+ *
848
+ * Permission is hereby granted, free of charge, to any person
849
+ * obtaining a copy of this software and associated documentation
850
+ * files (the "Software"), to deal in the Software without restriction,
851
+ * including without limitation the rightsto use, copy, modify, merge,
852
+ * publish, distribute, sublicense, and/or sell copies of the Software,
853
+ * and to permit persons to whom the Software is furnished to do so,
854
+ * subject to the following conditions:
855
+ *
856
+ * The above copyright notice and this permission notice shall be
857
+ * included in all copies or substantial portions of the Software.
858
+ *
859
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
860
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
861
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
862
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
863
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
864
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
865
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
866
+ * SOFTWARE.
3
867
  */
4
- const ponchoColorDefinitionsList = [
5
- {
6
- description: "",
7
- name: "Azul",
8
- color: "#0072BB",
9
- code: "primary",
10
- alias: [
11
- "azul",
12
- "primary"
13
- ]
14
- },
15
- {
16
- description: "Acción principal o exitosa",
17
- name: "Verde",
18
- color: "#2E7D33",
19
- code: "success",
20
- alias: [
21
- "verde",
22
- "success"
23
- ]
24
- },
25
- {
26
- description: "Atención o peligro",
27
- name: "Rojo",
28
- color: "#C62828",
29
- code: "danger",
30
- alias: [
31
- "rojo",
32
- "danger"
33
- ]
34
- },
35
- {
36
- description: "Foco o alerta",
37
- name: "Amarillo",
38
- color: "#F9A822",
39
- code: "warning",
40
- alias: [
41
- "amarillo",
42
- "warning"
43
- ]
44
- },
45
- {
46
- description: "",
47
- name: "Celeste",
48
- color: "#2897D4",
49
- code: "info",
50
- alias: [
51
- "celeste",
52
- "info"
53
- ]
54
- },
55
- {
56
- description: "Elementos básicos",
57
- name: "Negro",
58
- color: "#333333",
59
- code: "black",
60
- alias: [
61
- "negro",
62
- "black"
63
- ]
64
- },
65
- {
66
- description: "Enlace visitado",
67
- name: "Uva",
68
- color: "#6A1B99",
69
- code: "uva",
70
- alias: [
71
- "uva"
72
- ]
73
- },
74
- {
75
- description: "Texto secundario (subtitulos)",
76
- name: "Gris",
77
- color: "#525252",
78
- code: "muted",
79
- alias: [
80
- "gris",
81
- "muted"
82
- ]
83
- },
84
- {
85
- description: "Gris área",
86
- name: "Gris intermedio",
87
- color: "#F2F2F2",
88
- code: "gray",
89
- alias: [
90
- "grisintermedio",
91
- "gris-area",
92
- "gray"
93
- ]
94
- },
95
- {
96
- description: "Fondo footer/header",
97
- name: "Celeste Argentina",
98
- color: "#37BBED",
99
- code: "celeste-argentina",
100
- alias: [
101
- "celesteargentina",
102
- "celeste-argentina"
103
- ]
104
- },
105
- {
106
- description: "",
107
- name: "Fucsia",
108
- color: "#EC407A",
109
- code: "fucsia",
110
- alias: [
111
- "fucsia"
112
- ]
113
- },
114
- {
115
- description: "",
116
- name: "Arándano",
117
- color: "#C2185B",
118
- code: "arandano",
119
- alias: [
120
- "arandano"
121
- ]
122
- },
123
- {
124
- description: "",
125
- name: "Cielo",
126
- color: "#039BE5",
127
- code: "cielo",
128
- alias: [
129
- "cielo"
130
- ]
131
- },
132
- {
133
- description: "",
134
- name: "Verdin",
135
- color: "#6EA100",
136
- code: "verdin",
137
- alias: [
138
- "verdin"
139
- ]
140
- },
141
- {
142
- description: "",
143
- name: "Lima",
144
- color: "#CDDC39",
145
- code: "lima",
146
- alias: [
147
- "lima"
148
- ]
149
- },
150
- {
151
- description: "",
152
- name: "Maiz",
153
- color: "#FFCE00",
154
- code: "maiz",
155
- alias: [
156
- "maiz",
157
- "maíz"
158
- ]
159
- },
160
- {
161
- description: "",
162
- name: "Tomate",
163
- color: "#EF5350",
164
- code: "tomate",
165
- alias: [
166
- "tomate"
167
- ]
168
- },
169
- {
170
- description: "",
171
- name: "Naranja oscuro",
172
- color: "#EF6C00",
173
- code: "naranja",
174
- alias: [
175
- "naranjaoscuro",
176
- "naranja"
177
- ]
178
- },
179
- {
180
- description: "",
181
- name: "Verde azulado",
182
- color: "#008388",
183
- code: "verde-azulado",
184
- alias: [
185
- "verdeazulado",
186
- "verde-azulado"
187
- ]
188
- },
189
- {
190
- description: "",
191
- name: "Escarapela",
192
- color: "#2CB9EE",
193
- code: "escarapela",
194
- alias: [
195
- "escarapela"
196
- ]
197
- },
198
- {
199
- description: "",
200
- name: "Lavanda",
201
- color: "#9284BE",
202
- code: "lavanda",
203
- alias: [
204
- "lavanda"
205
- ]
206
- },
207
- {
208
- description: "",
209
- name: "Mandarina",
210
- color: "#F79525",
211
- code: "mandarina",
212
- alias: [
213
- "mandarina"
214
- ]
215
- },
216
- {
217
- description: "",
218
- name: "Palta",
219
- color: "#50B7B2",
220
- code: "palta",
221
- alias: [
222
- "palta"
223
- ]
224
- },
225
- {
226
- description: "",
227
- name: "Cereza",
228
- color: "#ED3D8F",
229
- code: "cereza",
230
- alias: [
231
- "cereza"
232
- ]
233
- },
234
- {
235
- description: "",
236
- name: "Limón",
237
- color: "#D7DF23",
238
- code: "limon",
239
- alias: [
240
- "limon"
241
- ]
242
- },
243
- {
244
- description: "",
245
- name: "Verde Jade",
246
- color: "#006666",
247
- code: "verde-jade",
248
- alias: [
249
- "verdejade",
250
- "verde-jade"
251
- ]
252
- },
253
- {
254
- description: "",
255
- name: "Verde Aloe",
256
- color: "#4FBB73",
257
- code: "verde-aloe",
258
- alias: [
259
- "verdealoe",
260
- "verde-aloe"
261
- ]
262
- },
263
- {
264
- description: "",
265
- name: "Verde Cemento",
266
- color: "#B4BEBA",
267
- code: "verde-cemento",
268
- alias: [
269
- "verdecemento",
270
- "verde-cemento"
271
- ]
868
+ const headStyle = (id, styleDefinitions, mediaType) => {
869
+ if (typeof id !== "string" || id.trim() === "") {
870
+ console.warn("No se ha provisto un _id_ válido. Se usará: "
871
+ + "'argob-custom-css'.");
872
+ id = "argob-custom-css";
873
+ }
874
+
875
+ if (typeof styleDefinitions !== "string" || styleDefinitions.trim() == ""){
876
+ console.warn("No se ha provisto definición de estilos. "
877
+ + "Se pasa por alto la petición.");
878
+ return;
879
+ }
880
+
881
+ const styleExists = document.getElementById(id);
882
+ if (styleExists !== null) {
883
+ if (styleExists.textContent.trim() === styleDefinitions.trim()) {
884
+ console.warn("[addHeadStyle] Una definición de estilos "
885
+ + "con las mismas definiciones ya existe.");
886
+ return;
887
+
888
+ } else {
889
+ styleExists.remove();
890
+ console.warn("[addHeadStyle] Un estilo con el mismo _id_ "
891
+ + "existe, pero tiene definiciones distintas. Se pisa.");
892
+ }
893
+ }
894
+
895
+ document.querySelectorAll("head").forEach(h => {
896
+ const tag = document.createElement("style");
897
+ tag.setAttribute("rel", "stylesheet");
898
+ tag.id = id;
899
+ if(typeof mediaType === "string" && mediaType.trim() !== ""){
900
+ tag.setAttribute("media", mediaType);
901
+ }
902
+
903
+ tag.textContent = styleDefinitions;
904
+
905
+ h.appendChild(tag);
906
+ });
907
+ };
908
+
909
+
910
+ /**
911
+ * Copia texto en el portapapeles (clipboard)
912
+ *
913
+ * @param {string} selector Selector html, ej: .class o #id
914
+ * @param {function} callback Función de retorno.
915
+ * @returns {void}
916
+ */
917
+ function copyToClipboard(selector, callback) {
918
+ if(typeof selector !== "string" || selector == ""){
919
+ return;
920
+ }
921
+
922
+ const copyText = document.querySelector(selector);
923
+ if(!copyText){
924
+ console.error("[copyToClipboard] No se puede encontrar el elemento.");
925
+ return;
926
+ }
927
+ const str = copyText.textContent;
928
+ navigator.clipboard.writeText(str)
929
+ .then(function(){
930
+ if(typeof callback === "function"){
931
+ callback(copyText);
932
+ }
933
+ }, function(){
934
+ console.error("[copyToClipboard] No se puede copiar el texto.");
935
+ });
936
+ }
937
+
938
+ function flattenNestedObjects(entries) {
939
+ return entries.map(entry => {
940
+ return flattenObject(entry, "");
941
+ });
942
+ }
943
+
944
+ function flattenObject(obj, prefix) {
945
+ const flattened = {};
946
+ for (const key in obj) {
947
+ const value = obj[key];
948
+ const newKey = (prefix ? `${prefix}__${key}` : key);
949
+
950
+ if (typeof value === "object" && value !== null) {
951
+ Object.assign(flattened, flattenObject(value, newKey));
952
+ } else {
953
+ flattened[newKey] = value;
954
+ }
955
+ }
956
+ return flattened;
957
+ }
958
+
959
+
960
+ if (typeof exports !== "undefined") {
961
+ module.exports = {flattenObject, flattenNestedObjects};
962
+ }
963
+
964
+ /**
965
+ *
966
+ */
967
+ ponchoTableLegacyPatch = () => {
968
+ document
969
+ .querySelectorAll("select[id=ponchoTableFiltro]")
970
+ .forEach(element => {
971
+ // const node = element.closest(".form-group");
972
+ const node = element.parentElement;
973
+ const newElement = document.createElement("div");
974
+ newElement.id = "ponchoTableFiltro";
975
+ newElement.classList.add("row");
976
+ node.parentElement.appendChild(newElement);
977
+ node.remove();
978
+ });
979
+ };
980
+
981
+
982
+ function ponchoTable(opt) {
983
+ ponchoTableLegacyPatch();
984
+ return ponchoTableDependant(opt);
985
+ }
986
+
987
+
988
+ /**
989
+ * Agenda
990
+ *
991
+ * @summary Agenda de eventos basada en PonchoTable donde se agrupan las
992
+ * entradas por fecha de inicio, fecha de fin, y categoría.
993
+ * @author Agustín Bouillet <bouilleta@jefatura.gob.ar>
994
+ * @requires jQuery, dataTables
995
+ * @see https://github.com/argob/poncho/tree/master/src/js/poncho-table
996
+ *
997
+ *
998
+ * MIT License
999
+ *
1000
+ * Copyright (c) 2024 Argentina.gob.ar
1001
+ *
1002
+ * Permission is hereby granted, free of charge, to any person
1003
+ * obtaining a copy of this software and associated documentation
1004
+ * files (the "Software"), to deal in the Software without restriction,
1005
+ * including without limitation the rightsto use, copy, modify, merge,
1006
+ * publish, distribute, sublicense, and/or sell copies of the Software,
1007
+ * and to permit persons to whom the Software is furnished to do so,
1008
+ * subject to the following conditions:
1009
+ *
1010
+ * The above copyright notice and this permission notice shall be
1011
+ * included in all copies or substantial portions of the Software.
1012
+ *
1013
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1014
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1015
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1016
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
1017
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
1018
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1019
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1020
+ * SOFTWARE.
1021
+ */
1022
+ class PonchoAgenda {
1023
+
1024
+ DATE_REGEX = /^([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\/([1-9]|0[1-9]|1[0-2])\/([1-9][0-9]{3})$/;
1025
+
1026
+ constructor(options={}){
1027
+ options.headers = this._refactorHeaders(options);
1028
+ options.headersOrder = this._refactorHeadersOrder(options);
1029
+
1030
+ // Global Options
1031
+ this.opts = Object.assign({}, this.defaults, options);
1032
+
1033
+ this.categoryTitleClassList = this.opts.categoryTitleClassList;
1034
+ this.itemContClassList = this.opts.itemContClassList;
1035
+ this.itemClassList = this.opts.itemClassList;
1036
+ this.groupCategory = this.opts.groupCategory;
1037
+ this.dateSeparator = this.opts.dateSeparator;
1038
+ this.startDateId = this.opts.startDateId;
1039
+ this.endDateId = this.opts.endDateId;
1040
+ this.timeId = this.opts.timeId;
1041
+
1042
+ this.descriptionId = this.opts.descriptionId;
1043
+ this.criteriaOneId = this.opts.criteriaOneId;
1044
+ this.criteriaTwoId = this.opts.criteriaTwoId;
1045
+ this.criteriaThreeId = this.opts.criteriaThreeId;
1046
+ }
1047
+
1048
+
1049
+ /**
1050
+ * Opciones por defecto
1051
+ */
1052
+ defaults = {
1053
+ allowedTags: [
1054
+ "strong","span", "dl", "dt", "dd", "img", "em","button", "button",
1055
+ "p", "div", "h3", "ul", "li", "time", "a", "h1"],
1056
+
1057
+ criteriaOneId: "destinatarios",
1058
+ criteriaThreeId: "destacado",
1059
+ criteriaTwoId: "url",
1060
+ descriptionId: "descripcion",
1061
+ categoryTitleClassList: ["h6", "text-secondary"],
1062
+ itemContClassList: ["list-unstyled"],
1063
+ itemClassList: ["m-b-2"],
1064
+ dateSeparator: "/",
1065
+ filterStatus: {
1066
+ header: "Estado",
1067
+ nextDates: "Próximas",
1068
+ pastDates: "Anteriores",
1069
+ },
1070
+ endDateId: "hasta",
1071
+ groupCategory: "filtro-ministerio",
1072
+ rangeLabel: "Fechas",
1073
+ startDateId: "desde",
1074
+ timeId: "horario",
1075
+ };
1076
+
1077
+
1078
+ /**
1079
+ * Agrega los indices range y filtro-status al al array si no existieran.
1080
+ *
1081
+ * @param {object} options Opciones para ponchoTabla y Agenda
1082
+ * @returns {object}
1083
+ */
1084
+ _refactorHeadersOrder = options => {
1085
+ if(options.hasOwnProperty("headersOrder") &&
1086
+ options.headersOrder.length > 0){
1087
+ let order = options.headersOrder;
1088
+ for(const i of ["range", "filtro-status"]){
1089
+ if(!options.headersOrder.includes(i)){
1090
+ options.headersOrder.push(i);
1091
+ }
1092
+ }
1093
+ return order;
1094
+ }
1095
+ return [];
1096
+ };
1097
+
1098
+ /**
1099
+ * Mapea los headers.
1100
+ *
1101
+ * @return {string} key Key del item.
1102
+ */
1103
+ _header = (key) => {
1104
+ return (this.opts.headers.hasOwnProperty(key) ?
1105
+ this.opts.headers[key] : key);
1106
+ };
1107
+
1108
+ /**
1109
+ * Refactor de headers
1110
+ *
1111
+ * @summary Agrega los headers de range y filterheader a los
1112
+ * asignados en el JSON.
1113
+ * @param {object} options Opciones para ponchoTabla y Agenda
1114
+ * @returns {object}
1115
+ */
1116
+ _refactorHeaders = options => {
1117
+ let labelStatus = this.defaults.filterStatus.header;
1118
+ if(options?.filterStatus?.header){
1119
+ labelStatus = options.filterStatus.header;
1120
+ }
1121
+
1122
+ let rangeLabel = this.defaults.rangeLabel;
1123
+ if(options?.rangeLabel){
1124
+ rangeLabel = options.rangeLabel;
1125
+ }
1126
+
1127
+ const headers = {
1128
+ ...{ "range": rangeLabel},
1129
+ ...options.headers,
1130
+ ...{"filtro-status": labelStatus}
1131
+ };
1132
+
1133
+ return headers;
1134
+ }
1135
+
1136
+
1137
+ /**
1138
+ * Showdown habilitado.
1139
+ *
1140
+ * Verifica si la librería _showdown_ está disponible.
1141
+ * @returns {boolean}
1142
+ */
1143
+ _isMarkdownEnable = () => {
1144
+ if(typeof showdown !== "undefined" &&
1145
+ showdown.hasOwnProperty("Converter")){
1146
+ return true;
1147
+ }
1148
+ return false;
1149
+ };
1150
+
1151
+
1152
+ /**
1153
+ * Opciones para markdown
1154
+ * @returns {object}
1155
+ */
1156
+ _markdownOptions = () => {
1157
+ if(this._isMarkdownEnable()){
1158
+ if(this.opts.hasOwnProperty("markdownOptions") &&
1159
+ typeof this.opts.markdownOptions === "object"){
1160
+ return this.opts.markdownOptions;
1161
+ }
1162
+ }
1163
+ return {};
1164
+ };
1165
+
1166
+
1167
+ /**
1168
+ * Convierte un string a markdown
1169
+ *
1170
+ * @param {string} str Cadena de texto a convertir
1171
+ * @returns {string}
1172
+ */
1173
+ _markdownConverter = str => {
1174
+ if(this._isMarkdownEnable()){
1175
+ const converter = new showdown.Converter(this._markdownOptions());
1176
+ return converter.makeHtml(str);
1177
+ }
1178
+ return str;
1179
+ };
1180
+
1181
+
1182
+ /**
1183
+ * Fecha pasada
1184
+ *
1185
+ * @param {string} fecha Fecha a evaluar
1186
+ * @returns {boolean}
1187
+ */
1188
+ _isPastDate = fecha => {
1189
+ if(!this._isValidDateFormat(fecha)){
1190
+ console.error(`La fecha no tiene un formato válido: ${fecha}`);
1191
+ return false;
1192
+ }
1193
+
1194
+ const dateToEvaluate = this._dateParser(fecha).date.getTime();
1195
+ const current = this._currentDate().date.getTime();
1196
+ return current > dateToEvaluate;
272
1197
  }
273
- ];
274
1198
 
275
1199
 
276
- /**
277
- * Variaciones de color
278
- */
279
- const colorVariations = {
280
- high: [
281
- "primary","verde-jade","success","naranja","danger","arandano",
282
- "uva","celeste-argentina","palta","verdin","warning","tomate",
283
- "fucsia","lavanda","black"
284
- ],
285
- medium: [
286
- "info","verde-azulado","verdin","warning","tomate","fucsia",
287
- "lavanda","palta","lima","maiz","muted"
288
- ]
289
- };
1200
+ /**
1201
+ * Formato para fecha y hora
1202
+ *
1203
+ * @param {objecct} date Fecha como objeto {day, month, year}
1204
+ * @param {object} time Tiempo como objeto {hours, minutes, seconds}
1205
+ * @returns {string}
1206
+ */
1207
+ _dateTimeFormat = (date, time=false) => {
1208
+ const {day, month, year} = date;
1209
+ const dateFormat = [day, month, year].join(this.dateSeparator);
1210
+ let timeFormat = "";
1211
+ if(time){
1212
+ timeFormat = [hours, minutes].join(":");
1213
+ }
1214
+ return dateFormat + timeFormat;
1215
+ };
290
1216
 
291
1217
 
292
- /**
293
- * Definición por color
294
- *
295
- * @see ponchoColorDefinitionsList
296
- * @param {string} color Nombre del cólor a buscar.
297
- * @returns {string|boolean}
298
- */
299
- const ponchoColorDefinitions = color => {
300
- const result = ponchoColorDefinitionsList.find(
301
- f => f.alias.some(s => typeof color != undefined && s == color)
302
- );
303
- return result || false;
304
- };
1218
+ /**
1219
+ * Fecha al momento de ejecutarse el script.
1220
+ *
1221
+ * @returns {object} Retorna un objeto con: el día, mes, año y el
1222
+ * objeto Date en fecha.
1223
+ */
1224
+ _currentDate = () => {
1225
+ const today = new Date();
1226
+ const year = today.getFullYear();
1227
+ const month = today.getMonth() + 1;
1228
+ const day = today.getDate();
1229
+ const format = [
1230
+ this._pad(day),
1231
+ this._pad(month),
1232
+ year].join(this.dateSeparator);
1233
+
1234
+ return {...this._dateParser(format), ...{format}};
1235
+ }
1236
+
1237
+ /**
1238
+ * Rellena con ceros a la izquierda
1239
+ *
1240
+ * @param {string|int} num Numero a rellenar con ceros.
1241
+ * @param {int} counter Cantidad total de caracteres.
1242
+ * @returns {string}
1243
+ */
1244
+ _pad = (num, counter=2) => num.toString().padStart(counter, "0");
305
1245
 
306
1246
 
307
- /**
308
- * Colores poncho a hexa
309
- *
310
- * @see https://argob.github.io/poncho/identidad/colores/
311
- * @param {string} color Nombre de color Poncho.
312
- * @example
313
- * // returns "#2897d4"
314
- * getColor("celeste")
315
- * @returns {string} Color en formato hexadecimal.
316
- */
317
- const ponchoColor = color => ponchoColorDefinitions(color)?.color || color;
1247
+ /**
1248
+ * Parsea una fecha.
1249
+ *
1250
+ * @param {string} date Fecha en formato dd/mm/yyyy.
1251
+ * @param {string} time Tiempo en formato hh:mm:ss
1252
+ * @example
1253
+ * // {
1254
+ * // day: '09',
1255
+ * // month: '05',
1256
+ * // year: '2012',
1257
+ * // hours: '00',
1258
+ * // minutes: '00',
1259
+ * // date: Wed May 09 2012 00:00:00 GMT-0300...
1260
+ * // }
1261
+ * this._dateParser("09/05/2012")
1262
+ * @returns {object|boolean}
1263
+ */
1264
+ _dateParser = (date, time="00:00:00") => {
1265
+ if(!this._isValidDateFormat(date)){
1266
+ console.error(`Formato de fecha incorrecto: ${date}`);
1267
+ return;
1268
+ }
1269
+ const regex = this.DATE_REGEX;
1270
+ const result = regex.exec(date);
1271
+ const [, day, month, year] = result;
1272
+ const objectDate = new Date(`${year}-${month}-${day} ${time}`);
318
1273
 
1274
+ return {
1275
+ day: this._pad(day),
1276
+ month: this._pad(month),
1277
+ year,
1278
+ hours: this._pad(objectDate.getHours()),
1279
+ minutes: this._pad(objectDate.getMinutes()),
1280
+ "date": objectDate
1281
+ }
1282
+ }
319
1283
 
320
- /**
321
- * Hace un refactor del número hexa
322
- *
323
- * @param {string} value Valor hexadecimal
324
- * @returns {string}
325
- */
326
- const cleanUpHex = value => {
327
- let hex = value
328
- .toString()
329
- .replace("#", "")
330
- .trim()
331
- .toUpperCase();
332
1284
 
333
- if (hex.length < 3 || hex.length > 6){
334
- return false;
335
- } else if(hex.length == 3){
336
- hex = Array.from(hex).map(a => a.repeat(2)).join("");
1285
+ /**
1286
+ * Valida el formato de la fecha.
1287
+ * @summary El formato de fecha aceptado es: dd/mm/yyyy.
1288
+ * Al momento de escribir este documento, no hay otro habilitado.
1289
+ * @example
1290
+ * // true
1291
+ * this._isValidDateFormat("09/05/2012")
1292
+ *
1293
+ * // false
1294
+ * this._isValidDateFormat("09/10/15")
1295
+ * @param {string} str Fecha en formato dd/mm/yyyy.
1296
+ * @returns {boolean}
1297
+ */
1298
+ _isValidDateFormat = str => {
1299
+ const regex = this.DATE_REGEX;
1300
+ const result = regex.exec(str);
1301
+
1302
+ return (result !== null ? true : false);
337
1303
  }
338
- return `#${hex}`;
339
- };
340
1304
 
341
1305
 
342
- /**
343
- * Retorna el código de color poncho por hexadecimal.
344
- * @param {string} value Valor hexadecimal a buscar
345
- * @see ponchoColorDefinitionsList
346
- * @example
347
- * // {
348
- * // "description": "",
349
- * // "name": "Mandarina",
350
- * // "color": "#f79525",
351
- * // "code": "mandarina",
352
- * // "alias": [
353
- * // "mandarina"
354
- * // ]
355
- * // }
356
- * findByHex("#f79525");
357
- * @returns {object} Objecto con la defición del color
358
- */
359
- const ponchoColorByHex = value => ponchoColorDefinitionsList.find(f => {
360
- const colorToFind = cleanUpHex(value);
361
- const colorToCompare = cleanUpHex(f.color);
362
- if(colorToFind == colorToCompare){
363
- return true;
1306
+ /**
1307
+ * Agrupa contenidos por fecha y la categoría asignada.
1308
+ *
1309
+ * @param {object} datos JSON a procesar
1310
+ * @returns {object}
1311
+ */
1312
+ _groupByFingerprintAndCategory = (datos) => {
1313
+ const agrupados = {};
1314
+
1315
+ for (const dato of datos) {
1316
+ const categoria = dato[this.groupCategory];
1317
+ const {fingerprint} = dato;
1318
+ if (!agrupados[fingerprint]) {
1319
+ agrupados[fingerprint] = {};
1320
+ }
1321
+ if (!agrupados[fingerprint][categoria]) {
1322
+ agrupados[fingerprint][categoria] = [];
1323
+ }
1324
+ agrupados[fingerprint][categoria].push(dato);
1325
+ }
1326
+
1327
+ return agrupados;
364
1328
  }
365
- return false;
366
- });
367
1329
 
368
1330
 
369
- /* module.exports REMOVED */
1331
+ /**
1332
+ * Rearmo el JSON para agregar filtros.
1333
+ *
1334
+ * @param {object} jsonData
1335
+ * @returns {object}
1336
+ */
1337
+ _refactorEntries = jsonData => {
1338
+ if(!jsonData){
1339
+ console.error("No se puede recorrer el script")
1340
+ }
370
1341
 
371
- /**
372
- * Fetch data
373
- *
374
- * @example
375
- * ```js
376
- * (async() => {
377
- * const data = await fetch_json("https://som.url.com");
378
- * });
379
- * ```
380
- */
381
- async function fetch_json(uri, options={}) {
1342
+ let entries = [];
1343
+ jsonData.forEach(element => {
1344
+ let desde = element[this.startDateId];
1345
+ let hasta = element[this.endDateId];
1346
+ // Si la columna `hasta` viene vacía le copio los datos de `desde`.
1347
+ hasta = (hasta.trim() === "" ? desde : hasta);
1348
+
1349
+ const {pastDates, nextDates} = this.opts.filterStatus;
1350
+ const estado = (this._isPastDate(hasta) ? pastDates : nextDates);
1351
+ // dates
1352
+ const startDate = this._dateParser(desde);
1353
+ const endDate = this._dateParser(hasta);
1354
+ const startDateTime = startDate.date.getTime();
1355
+ const endDateTime = endDate.date.getTime();
1356
+ const fingerprint = [startDateTime, endDateTime].join("_");
1357
+
1358
+ let range = this._dateTimeFormat(startDate);
1359
+ if(startDateTime != endDateTime){
1360
+ range = `Del ${this._dateTimeFormat(startDate)} al `
1361
+ + `${this._dateTimeFormat(endDate)}`;
1362
+ }
382
1363
 
383
- let defaultOptions = {
384
- method: "GET",
385
- headers: {
386
- "Accept": "application/json",
387
- "Content-Type": "application/json"
388
- },
389
- redirect: "follow"
1364
+ // refactor entry
1365
+ const entry = {
1366
+ ...element,
1367
+ ...{
1368
+ "range": range,
1369
+ "filtro-status": estado,
1370
+ fingerprint,
1371
+ desde,
1372
+ hasta,
1373
+ }
1374
+ };
1375
+ entries.push(entry);
1376
+ });
1377
+
1378
+ return entries;
390
1379
  };
391
- let opts = Object.assign({}, defaultOptions, options);
392
- const response = await fetch(uri, opts);
393
1380
 
394
- if (!response.ok) {
395
- throw new Error(`HTTP error! status: ${response.status}`);
396
- }
397
- return await response.json();
398
- };
399
1381
 
400
- /**
401
- * Remueve acentos y caracteres especiales.
402
- *
403
- * @param {string} data Cadena de texto a limpiar.
404
- * @example
405
- * // returns Accion murcielago arbol nino
406
- * removeAccents("Acción Murciélago árbol niño")
407
- * @returns {string} Cadena de texto sin acentos.
408
- */
409
- const replaceSpecialChars = (data) => {
410
- if(!data){
411
- return "";
412
- }
413
- const search = "àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕ"
414
- + "ŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż";
415
- const replace = "aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnooooooooop"
416
- + "rrsssssttuuuuuuuuuwxyyzzz";
417
- const a = search + search.toUpperCase();
418
- const b = replace + replace.toUpperCase();
419
- const p = new RegExp(a.split("").join("|"), "g");
420
- return data.toString().replace(p, c => b.charAt(a.indexOf(c)))
421
- };
1382
+ /**
1383
+ * Compone el template para el item de la agenda
1384
+ *
1385
+ * @param {string} description Descriptión del item de la agenda.
1386
+ * @param {string} date Fecha formato dd/mm/yyyy
1387
+ * @param {string} time Horario en formato hh:mm:ss
1388
+ * @returns {object}
1389
+ */
1390
+ itemTemplate = (description, destinatarios, url,
1391
+ destacados, date, time) => {
1392
+ const itemContainer = document.createElement("dl");
1393
+
1394
+ // time
1395
+ let timeElement;
1396
+ if(time){
1397
+ const datetime = this._dateParser(date, time);
1398
+ timeElement = document.createElement("time");
1399
+ timeElement.setAttribute("datetime", datetime.date.toISOString());
1400
+ timeElement.textContent = `${datetime.hours}:`
1401
+ + `${datetime.minutes}hs.`;
1402
+ } else {
1403
+ timeElement = document.createElement("span");
1404
+ timeElement.textContent = "--:--";
1405
+ }
422
1406
 
1407
+ const data = [
1408
+ // Térm, definition, screenreader, dtoff, className
1409
+ [
1410
+ "Descripción",
1411
+ this._markdownConverter(description),
1412
+ true, true, "description"],
1413
+ [
1414
+ this._header(this.criteriaOneId),
1415
+ this._markdownConverter(destinatarios),
1416
+ false, true, "criteria-one"],
1417
+ [
1418
+ this._header(this.criteriaThreeId),
1419
+ this._markdownConverter(destacados),
1420
+ false, true, "criteria-three"],
1421
+ [
1422
+ this._header(this.criteriaTwoId),
1423
+ this._markdownConverter(url),
1424
+ false, true, "criteria-two"],
1425
+ [
1426
+ this._header(this.timeId),
1427
+ timeElement.outerHTML,
1428
+ false, true, "time"],
1429
+ ];
423
1430
 
424
- /**
425
- * Slugify
426
- *
427
- * @param {string} string Cadena de texto a convertir.
428
- * @example
429
- * // returns el-murcielago-remolon-parece-un-nino
430
- * slugify("El murciélago remolón parece un niño")
431
- * @returns {string} Cadena de texto en formato slug.
432
- */
433
- const slugify = (string) =>{
434
- if(!string){
435
- return string;
436
- }
437
- const a = "àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìıİłḿñńǹňôöòóœøōõőṕ"
438
- + "ŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;";
439
- const b = "aaaaaaaaaacccddeeeeeeeegghiiiiiiiilmnnnnooooooooop"
440
- + "rrsssssttuuuuuuuuuwxyyzzz------";
441
- const p = new RegExp(a.split("").join("|"), "g");
1431
+ data.forEach( elem => {
1432
+ const [term, definition, srOnly, dtOff, className] = elem;
1433
+ if(!definition){
1434
+ return;
1435
+ }
442
1436
 
443
- return string.toString().toLowerCase()
444
- .replace(/\s+/g, "-")
445
- .replace(p, c => b.charAt(a.indexOf(c)))
446
- .replace(/&/g, "-and-")
447
- .replace(/[^\w\-]+/g, "")
448
- .replace(/\-\-+/g, "-")
449
- .replace(/^-+/, "")
450
- .replace(/-+$/, "");
451
- };
1437
+ const dt = document.createElement("dt");
1438
+ dt.textContent = term;
1439
+ dt.classList.add("agenda-item__dt", `agenda-item__dt-${className}`);
1440
+ if(srOnly){
1441
+ dt.classList.add("sr-only");
1442
+ }
1443
+
1444
+ const dd = document.createElement("dd");
1445
+ dd.textContent = definition;
1446
+ dd.classList.add("agenda-item__dd", `agenda-item__dd-${className}`);
452
1447
 
1448
+ if(dtOff){
1449
+ itemContainer.appendChild(dt);
1450
+ }
1451
+ itemContainer.appendChild(dd);
1452
+ });
453
1453
 
454
- /* module.exports REMOVED */
1454
+ if(this.itemClassList.some(f=>f)){
1455
+ itemContainer.classList.add("agenda-item", ...this.itemClassList);
1456
+ }
455
1457
 
456
- /**
457
- * Impide que se impriman etiquetas HTML.
458
- *
459
- * @summary Impide que se impriman etiquetas HTML exceptuando aquellas
460
- * asignadas en el parámetro exclude.
461
- * @param {string} str Cadena de texto a remplazar.
462
- * @param {object} exclude Etiquetas que deben preservarse.
463
- * @example
464
- * // returns &lt;h1&gt;Hello world!&lt;/h1&gt; <a href="#">Link</a>
465
- * secureHTML('<h1>Hello world!</h1> <a href="#">Link</a>', ["a"])
466
- *
467
- * @returns {string} Texto remplazado.
468
- */
469
- const secureHTML = (str, exclude=[]) => {
470
- if(exclude.some(e => e === "*")){
471
- return str;
472
- }
1458
+ return itemContainer;
1459
+ };
473
1460
 
474
- let replaceString = str.toString()
475
- .replace(/</g, "&lt;")
476
- .replace(/>/g, "&gt;");
477
1461
 
478
- // let replaceString = str.toString()
479
- // .replace(/<(?=[a-zA-Z])([^<>]*)>/gm, "&lt;$1&gt;")
480
- // .replace(/<\/(?=[a-zA-Z])([^<>]*)>/gm, "&lt;/$1&gt;");
1462
+ /**
1463
+ * Reagrupa las entradas dejando, por fecha, las entradas de la categoría.
1464
+ *
1465
+ * @param {object} entries
1466
+ * @returns {object}
1467
+ */
1468
+ _groupedEntries = entries => {
1469
+ let collect = [];
1470
+ // Nivel mismas fechas
1471
+ Object.values(entries).forEach(ele => {
1472
+ var entry;
1473
+
1474
+ // Nivel ministerio
1475
+ // Cada iteración es un ministerio.
1476
+ Object.values(ele).forEach((element) => {
1477
+ var block = "";
1478
+ var title = "";
1479
+
1480
+ const itemsContainer = document.createElement("div");
1481
+ if(this.itemContClassList.some(f=>f)){
1482
+ itemsContainer.classList.add(...this.itemContClassList);
1483
+ }
1484
+
1485
+ // Nivel items por ministerio
1486
+ element.forEach(a => {
1487
+ entry = a;
1488
+ if(title != entry[this.groupCategory]){
1489
+ title = entry[this.groupCategory];
1490
+
1491
+ const titleElement = document.createElement("p");
1492
+ if(this.categoryTitleClassList.some(f=>f)){
1493
+ titleElement.classList.add(
1494
+ ...this.categoryTitleClassList);
1495
+ titleElement.textContent = title;
1496
+ itemsContainer.appendChild(titleElement);
1497
+ }
1498
+ }
481
1499
 
1500
+ const item = this.itemTemplate(
1501
+ a.descripcion, a.destinatarios, a.url,
1502
+ a.destacados, a.desde, a.horario);
1503
+ itemsContainer.appendChild(item);
1504
+ });
482
1505
 
483
- if(exclude.length > 0){
484
- const regexStart = new RegExp(
485
- "&lt;(" + exclude.join("|") + ")(.*?)&gt;", "g");
486
- const regexEnd = new RegExp(
487
- "&lt;\/(" + exclude.join("|") + ")(.*?)&gt;", "g");
1506
+ block += itemsContainer.outerHTML;
1507
+ delete entry.fingerprint;
1508
+ let customData={};
488
1509
 
489
- return replaceString
490
- .replace(regexStart, "<$1$2>")
491
- .replace(regexEnd, "</$1>");
492
- }
493
- return replaceString;
494
- };
1510
+ customData[this.descriptionId] = block;
1511
+ collect.push( {...entry, ...customData} );
1512
+ });
1513
+ });
495
1514
 
1515
+ return collect;
1516
+ };
496
1517
 
497
1518
 
498
- /* module.exports REMOVED */
1519
+ /**
1520
+ * Valida si poncho tabla está importado
1521
+ * @returns {boolean}
1522
+ */
1523
+ _ponchoTableExists = () => {
1524
+ if(typeof ponchoTable !== "undefined"){
1525
+ return true;
1526
+ }
1527
+ return false;
1528
+ };
499
1529
 
500
- /**
501
- *
502
- */
503
- ponchoTableLegacyPatch = () => {
504
- document
505
- .querySelectorAll("select[id=ponchoTableFiltro]")
506
- .forEach(element => {
507
- // const node = element.closest(".form-group");
508
- const node = element.parentElement;
509
- const newElement = document.createElement("div");
510
- newElement.id = "ponchoTableFiltro";
511
- newElement.classList.add("row");
512
- node.parentElement.appendChild(newElement);
513
- node.remove();
514
- });
1530
+
1531
+ /**
1532
+ * Imprime la tabla ponchoTable
1533
+ *
1534
+ * @returns {undefined}
1535
+ */
1536
+ render = () => {
1537
+ if(!this.opts.hasOwnProperty("jsonData")){
1538
+ console.error(
1539
+ "¡Hay un error en los datos pasados "
1540
+ + "a la función `PonchoAgenda`!");
1541
+ return;
1542
+ }
1543
+
1544
+ const refactorEntries = this._refactorEntries(this.opts.jsonData);
1545
+ const groupedByDateAndCategory =
1546
+ this._groupByFingerprintAndCategory(refactorEntries);
1547
+ this.opts.jsonData = this._groupedEntries(groupedByDateAndCategory);
1548
+
1549
+ if(this._ponchoTableExists()){
1550
+ ponchoTable( this.opts );
1551
+ }
1552
+ };
515
1553
  };
516
1554
 
517
1555
 
518
- function ponchoTable(opt) {
519
- ponchoTableLegacyPatch();
520
- return ponchoTableDependant(opt);
1556
+ if (typeof exports !== "undefined") {
1557
+ module.exports = PonchoAgenda;
521
1558
  }
522
1559
 
523
-
524
1560
  /**
525
1561
  * PONCHO TABLE
526
1562
  *
@@ -543,10 +1579,10 @@ function ponchoTable(opt) {
543
1579
  * publish, distribute, sublicense, and/or sell copies of the Software,
544
1580
  * and to permit persons to whom the Software is furnished to do so,
545
1581
  * subject to the following conditions:
546
- *
1582
+ *
547
1583
  * The above copyright notice and this permission notice shall be
548
1584
  * included in all copies or substantial portions of the Software.
549
- *
1585
+ *
550
1586
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
551
1587
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
552
1588
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -559,34 +1595,47 @@ function ponchoTable(opt) {
559
1595
  const ponchoTableDependant = opt => {
560
1596
  var gapi_data;
561
1597
  var filtersList = [];
562
- var wizard = (opt.hasOwnProperty("wizard") && opt.wizard ?
1598
+ var wizard = (opt.hasOwnProperty("wizard") && opt.wizard ?
563
1599
  true : false);
564
- var emptyLabel = (opt.hasOwnProperty("emptyLabel") && opt.emptyLabel ?
1600
+ var emptyLabel = (opt.hasOwnProperty("emptyLabel") && opt.emptyLabel ?
565
1601
  opt.emptyLabel : "Todos");
566
1602
  var filtro = {};
567
- var orderFilter = (opt.hasOwnProperty("orderFilter") && opt.orderFilter ?
568
- true : false);
1603
+ var orderFilter = (opt.hasOwnProperty("orderFilter") && opt.orderFilter ?
1604
+ opt.orderFilter : false);
569
1605
  var asFilter = {};
570
1606
  var allowedTags = ["*"];
1607
+ var pushState = (opt.hasOwnProperty("pushState") &&
1608
+ opt.pushState == true ? true : false);
1609
+ var copyResults = (opt.hasOwnProperty("copyResults") &&
1610
+ opt.copyResults == true ? true : false);
1611
+
1612
+ // urlParams dependiente de las opciones copyResults o pushState
1613
+ var urlParams = false;
1614
+ if(opt.hasOwnProperty("urlParams") && opt.urlParams == true){
1615
+ urlParams = true;
1616
+ } else if( copyResults == true || pushState == true){
1617
+ urlParams = true;
1618
+ }
1619
+
571
1620
  let markdownOptions = {
572
1621
  "tables": true,
573
1622
  "simpleLineBreaks": true,
574
1623
  "extensions": [
575
- 'details',
576
- 'images',
577
- 'alerts',
578
- 'numbers',
579
- 'ejes',
580
- 'button',
581
- 'target',
582
- 'bootstrap-tables',
583
- 'video'
1624
+ "details",
1625
+ "images",
1626
+ "alerts",
1627
+ "numbers",
1628
+ "ejes",
1629
+ "button",
1630
+ "target",
1631
+ "bootstrap-tables",
1632
+ "video"
584
1633
  ]
585
1634
  };
586
1635
 
587
1636
  // Loader
588
1637
  document.querySelector("#ponchoTable").classList.add("state-loading");
589
-
1638
+
590
1639
  if (jQuery.fn.DataTable.isDataTable("#ponchoTable")) {
591
1640
  jQuery("#ponchoTable").DataTable().destroy();
592
1641
  }
@@ -604,33 +1653,98 @@ const ponchoTableDependant = opt => {
604
1653
  };
605
1654
 
606
1655
 
1656
+ /**
1657
+ * Objeto agrupando filtros descendentes y ascendentes.
1658
+ *
1659
+ * @param {object} data Array con la configuración realizada por el
1660
+ * usuario en `orderFilter`.
1661
+ * @example
1662
+ * // {
1663
+ * // asc: ["filtro-estado", "filtro-categoria"],
1664
+ * // desc: ["filtro-ubicacion"]
1665
+ * // }
1666
+ * [["filtro-ubicacion", "desc"],[ "filtro-estado"], "filtro-categoria"]
1667
+ * @returns {object}
1668
+ */
1669
+ const _getOrderType = (data) => {
1670
+ if (!Array.isArray(data)) {
1671
+ return { asc: [], desc: [] };
1672
+ }
1673
+
1674
+ return data.reduce((acc, item) => {
1675
+ const [field, order="asc"] = (Array.isArray(item) ?
1676
+ item : [item, 'asc']);
1677
+
1678
+ const orderToLower = order.toLowerCase();
1679
+ const validKey = (["asc", "desc"].includes(orderToLower) ?
1680
+ orderToLower : "asc");
1681
+
1682
+ acc[validKey].push(field);
1683
+ return acc;
1684
+ }, {asc: [], desc: []});
1685
+ };
1686
+
1687
+
607
1688
  /**
608
1689
  * De acuerdo a las opciones del usuario, ordena el listado o lo deja
609
1690
  * en la secuencia en la que llega.
1691
+ *
1692
+ * @summary Si `orderFilter` es _boolean_ y es true, entonces todos usan sort.
1693
+ * Si `orderFilter` es array filtro según la disponibilidad del filtro.
610
1694
  *
611
- * @summary Alias de sortAlphaNumeric
612
- * @param {object} a
613
- * @param {object} b
1695
+ * @see sortAlphaNumeric()
1696
+ * @param {object} data Array con el contenido de cada filtro.
1697
+ * @param {string} filter Nombre del filtro.
614
1698
  * @returns {object}
615
1699
  */
616
- const _sortAlphaNumeric = (a, b) => (orderFilter ?
617
- sortAlphaNumeric(a, b) : null);
1700
+ const _sortAlphaNumeric = (data, filter) => {
1701
+ // filter debe ser string
1702
+ if(typeof filter !== "string"){
1703
+ console.error(
1704
+ "Error:",
1705
+ `_filter_ debe ser string. Recibió: ${typeof filter}`);
1706
+ return;
1707
+ }
1708
+ // data debe ser array
1709
+ if(!Array.isArray(data)){
1710
+ console.error(
1711
+ "Error:",
1712
+ `_data_ debe ser object. Recibió: ${typeof data}`);
1713
+ return;
1714
+ }
1715
+
1716
+ // Validación
1717
+ if(typeof orderFilter === "boolean" && orderFilter){
1718
+ return data.sort(sortAlphaNumeric);
1719
+ }
1720
+
1721
+ const orderType = _getOrderType(orderFilter);
1722
+ const {asc, desc} = orderType;
1723
+
1724
+ if(Array.isArray(orderFilter) && asc.includes(filter)){
1725
+ return data.sort(sortAlphaNumeric);
1726
+ } else if(desc.includes(filter)){
1727
+ return data.sort(sortAlphaNumeric).reverse();
1728
+ }
1729
+
1730
+ return data;
1731
+ };
618
1732
 
619
1733
 
620
1734
  /**
621
1735
  * Resultados únicos
622
- *
623
- * @param {object} list Array del que se quiere obtener
1736
+ *
1737
+ * @param {object} list Array del que se quiere obtener
624
1738
  * resultados únicos.
625
1739
  * @returns {object}
626
1740
  */
627
1741
  const distinct = list => [... new Set(list)];
628
-
1742
+
629
1743
 
630
1744
  /**
631
1745
  * Select option
632
- *
633
- * @summary Crea un tag _option_ para un _select_.
1746
+ *
1747
+ * @summary Crea un tag _option_ para un _select_.
634
1748
  * @param {integer} parent Índice según el listado de filtros.
635
1749
  * @param {string} label Valor para el label o texto visible.
636
1750
  * @param {string} value Valor para el attributo _value_.
@@ -676,79 +1790,128 @@ const ponchoTableDependant = opt => {
676
1790
  * Retorna los valores de los filtros
677
1791
  */
678
1792
  const _filterValues = () => {
679
- return [...document.querySelectorAll("[data-filter]")].map(e => e.value);
1793
+ return [...document.querySelectorAll("[data-filter]")]
1794
+ .map(e => e.value);
680
1795
  };
681
1796
 
682
1797
 
683
1798
  /**
684
1799
  * Showdown habilitado.
685
- *
1800
+ *
686
1801
  * Verifica si la librería _showdown_ está disponible.
687
1802
  * @returns {boolean}
688
1803
  */
689
1804
  const _isMarkdownEnable = () => {
690
- if(typeof showdown !== "undefined" &&
1805
+ if(typeof showdown !== "undefined" &&
691
1806
  showdown.hasOwnProperty("Converter")){
692
1807
  return true;
693
1808
  }
694
1809
  return false;
695
- };
1810
+ };
1811
+
696
1812
 
697
1813
  /**
698
1814
  * Verifica si las extensiones showdown están definidas.
699
- *
700
- * @param {object} extensions
1815
+ *
1816
+ * @param {object} extensions
701
1817
  * @returns {boolean}
702
1818
  */
703
- const _isShowdownExtensionEnable = extensions =>
704
- extensions.every(e => {
1819
+ const _isShowdownExtensionEnable = () => {
1820
+ const markdownOptions = _markdownOptions();
1821
+ const r = markdownOptions.extensions.every(e => {
705
1822
  try {
706
1823
  showdown.extension(e);
707
1824
  return true;
708
1825
  } catch (error) {
709
1826
  return false;
710
1827
  }
711
- });
1828
+ });
1829
+ return r;
1830
+ };
1831
+
1832
+
1833
+ /**
1834
+ * Opciones para el componente showdonwjs
1835
+ *
1836
+ * @summary Si el usuario asigno opciones y extensiones, las usa; de otro
1837
+ * modo, usa las que están por defecto.
1838
+ * @returns {object}
1839
+ */
1840
+ const _markdownOptions = () => {
1841
+ if(opt.hasOwnProperty("markdownOptions") &&
1842
+ opt.markdownOptions === "object"){
1843
+ return opt.markdownOptions;
1844
+ }
1845
+ return markdownOptions;
1846
+ };
1847
+
1848
+
1849
+ /**
1850
+ * Convierte un string con sintaxis markdown
1851
+ * @param {stirng} str Cadena de texto a convertir
1852
+ * @returns {string}
1853
+ */
1854
+ const _markdownConvert = str => {
1855
+ if( typeof str !== "string" ){
1856
+ return;
1857
+ }
1858
+ if( !_isMarkdownEnable() ){
1859
+ return str;
1860
+ }
1861
+
1862
+ let converter;
1863
+ if(_isShowdownExtensionEnable()){
1864
+ converter = new showdown.Converter( _markdownOptions() );
1865
+ return converter.makeHtml(str);
1866
+ }
1867
+
1868
+ converter = new showdown.Converter();
1869
+ return converter.makeHtml(str);
1870
+ };
1871
+
712
1872
 
713
1873
  /**
714
1874
  * Botón poncho
715
1875
  *
716
1876
  * @summary Imprime un botón bootstrap.
717
1877
  * @param {string} label Label para el botón.
718
- * @param {string} value Href para el botón
1878
+ * @param {string} value Href para el botón.
719
1879
  * @return {undefined}
720
- */
1880
+ */
721
1881
  const button = (label, value) => {
722
1882
  const btn = document.createElement("a");
723
- btn.setAttribute("aria-label", label);
724
1883
  btn.classList.add(
725
1884
  "btn", "btn-primary", "btn-sm", "margin-btn");
726
- btn.target = "_blank";
727
1885
  btn.href = value;
1886
+ btn.target = "_blank";
728
1887
  btn.textContent = label;
1888
+ btn.title = "Abre en una nueva ventana";
1889
+ btn.setAttribute("aria-label", label);
729
1890
  btn.setAttribute("rel", "noopener noreferrer");
1891
+
730
1892
  return btn.outerHTML;
731
1893
  };
732
1894
 
1895
+
733
1896
  /**
734
1897
  * Formato de fecha
735
1898
  *
736
1899
  * @summary Agrega una etiqueta datetime para mejorar la indexación
737
1900
  * y el ordenamiento.
738
1901
  * @return {undefined}
739
- */
1902
+ */
740
1903
  const tdDate = value => {
741
1904
  const dateSplit = value.split("/");
742
1905
  const finalDateIso = new Date(
743
1906
  dateSplit[2], dateSplit[1] - 1, dateSplit[0]
744
1907
  );
745
1908
 
746
- const datetime = finalDateIso.toISOString().split('T')[0];
1909
+ const datetime = finalDateIso.toISOString().split("T")[0];
747
1910
 
748
1911
  const hiddenSpan = document.createElement("span");
749
1912
  hiddenSpan.style.display = "none";
750
1913
  hiddenSpan.textContent = datetime;
751
-
1914
+
752
1915
  const time = document.createElement("time");
753
1916
  time.setAttribute("datetime", datetime);
754
1917
  time.textContent = value;
@@ -765,32 +1928,32 @@ const ponchoTableDependant = opt => {
765
1928
  */
766
1929
  const _createFilters = gapi_data => {
767
1930
  // Contenedor
768
- const tableFiltroCont = document.querySelector("#ponchoTableFiltro");
769
- tableFiltroCont.innerHTML = "";
1931
+ document
1932
+ .querySelectorAll("#ponchoTableFiltro")
1933
+ .forEach(e => e.innerHTML = "");
770
1934
 
771
1935
  // Imprime cada uno de los filtros
772
1936
  Object.keys(filtro).forEach((f, key) => {
773
1937
  const columna = filtro[f][0].columna ? filtro[f][0].columna : 0;
774
- const list_filter = filtro[f]
775
- .map(e => e.value)
776
- .sort(_sortAlphaNumeric);
1938
+ let toSort = filtro[f].map(e => e.value)
1939
+ let list_filter = _sortAlphaNumeric(toSort, f);
777
1940
 
778
1941
  const tplCol = document.createElement("div");
779
1942
 
780
1943
  if(opt.hasOwnProperty("filterClassList")){
781
- const classList = (typeof opt.filterClassList === "string" ?
1944
+ const classList = (typeof opt.filterClassList === "string" ?
782
1945
  opt.filterClassList.split(" ") : opt.filterClassList);
783
- tplCol.classList.add(...classList);
1946
+ tplCol.classList.add(...classList);
784
1947
  } else {
785
1948
  const cols = Math.floor(12 / Object.keys(filtro).length);
786
- tplCol.classList.add("col-sm-12", `col-md-${cols}`);
1949
+ tplCol.classList.add("col-sm-12", `col-md-${cols}`);
787
1950
  }
788
1951
  tplCol.dataset.index = key;
789
1952
  tplCol.dataset.filterName = f;
790
1953
 
791
1954
  // If wizzard
792
1955
  if(wizard && key > 0){
793
- tplCol.style.display = "none";
1956
+ tplCol.style.display = "none";
794
1957
  }
795
1958
 
796
1959
  const tplForm = document.createElement("div");
@@ -816,8 +1979,8 @@ const ponchoTableDependant = opt => {
816
1979
  tplForm.appendChild(formLabel);
817
1980
  tplForm.appendChild(select);
818
1981
  tplCol.appendChild(tplForm);
1982
+ const tableFiltroCont = document.querySelector("#ponchoTableFiltro");
819
1983
  tableFiltroCont.appendChild(tplCol);
820
- // }
821
1984
  });
822
1985
  };
823
1986
 
@@ -833,13 +1996,13 @@ const ponchoTableDependant = opt => {
833
1996
  const thead = document.querySelector("#ponchoTable thead");
834
1997
  thead.innerHTML = "";
835
1998
 
836
- const theadTr = document.createElement("tr");
1999
+ const theadTr = document.createElement("tr");
837
2000
  Object.keys(gapi_data.headers).forEach((header, key) => {
838
2001
  const th = document.createElement("th");
839
2002
  th.textContent = gapi_data.headers[header];
840
2003
  th.setAttribute("scope", "col");
841
2004
  theadTr.appendChild(th);
842
- });
2005
+ });
843
2006
  thead.appendChild(theadTr);
844
2007
 
845
2008
  // Table caption
@@ -859,26 +2022,17 @@ const ponchoTableDependant = opt => {
859
2022
  }
860
2023
 
861
2024
  // si se desea modificar la entrada desde opciones
862
- entry = (typeof opt.customEntry === "function" &&
2025
+ entry = (typeof opt.customEntry === "function" &&
863
2026
  opt.customEntry !== null ? opt.customEntry(entry) : entry);
864
2027
 
865
2028
  // Inserta el row.
866
2029
  const tbodyRow = tableTbody.insertRow();
867
2030
  tbodyRow.id = "id_" + key;
868
2031
 
869
- // Verifico sin las extensiones showdown existen
870
- let showdownOptions;
871
- if(_isMarkdownEnable()){
872
- const registeredOptions = (opt.hasOwnProperty("markdownOptions") ?
873
- opt.markdownOptions : markdownOptions);
874
- showdownOptions = (_isShowdownExtensionEnable(
875
- registeredOptions.extensions) ? registeredOptions : {});
876
- }
877
-
878
2032
  // Recorro cada uno de los títulos
879
2033
  Object.keys(gapi_data.headers).forEach(header => {
880
2034
  let filas = entry[header];
881
-
2035
+
882
2036
  if (header.startsWith("btn-") && filas != "") {
883
2037
  const label = header.replace("btn-", "").replace("-", " ");
884
2038
  filas = button(label, filas);
@@ -894,22 +2048,21 @@ const ponchoTableDependant = opt => {
894
2048
 
895
2049
  // Si showdown está incluido lo uso
896
2050
  // @todo Usar showdown fuera de la función. Usarlo en options.
897
- let allowed_tags = (opt.hasOwnProperty("allowedTags") ?
2051
+ let allowed_tags = (opt.hasOwnProperty("allowedTags") ?
898
2052
  opt.allowedTags : allowedTags);
899
-
900
- // Las etiquetas `<a>` y `<time>` junto con `<span>`, están
901
- // permitidas si existen los prefijos _btn-_ y _fecha-_
2053
+
2054
+ // Las etiquetas `<a>` y `<time>` junto con `<span>`, están
2055
+ // permitidas si existen los prefijos _btn-_ y _fecha-_
902
2056
  // respectivamente.
903
2057
  if(header.startsWith("btn-") && filas != ""){
904
2058
  allowed_tags = [...allowed_tags, "a"];
905
2059
  } else if(header.startsWith("fecha-") && filas != ""){
906
2060
  allowed_tags = [...allowed_tags, "span", "time"];
907
2061
  }
908
-
2062
+
909
2063
  const cleannedText = secureHTML(filas, allowed_tags);
910
2064
  if(_isMarkdownEnable()){
911
- const converter = new showdown.Converter(showdownOptions);
912
- cell.innerHTML = converter.makeHtml(cleannedText);
2065
+ cell.innerHTML = _markdownConvert(cleannedText);
913
2066
  } else {
914
2067
  cell.innerHTML = cleannedText;
915
2068
  }
@@ -920,7 +2073,7 @@ const ponchoTableDependant = opt => {
920
2073
 
921
2074
  /**
922
2075
  * Matriz filtro
923
- *
2076
+ *
924
2077
  * @summary Reune los filtros y por cada uno de ellos guarda los
925
2078
  * datos —únicos—, de esa entrada.
926
2079
  * @param {object} gapi_data Objeto con la información separada del
@@ -947,8 +2100,10 @@ const ponchoTableDependant = opt => {
947
2100
  entiresByFilter = gapi_data.entries.map(entry => entry[filter]);
948
2101
  }
949
2102
 
950
- const uniqueEntries = distinct(entiresByFilter);
951
- uniqueEntries.sort(_sortAlphaNumeric);
2103
+ const uniqueEntries = _sortAlphaNumeric(
2104
+ distinct(entiresByFilter), filter
2105
+ );
2106
+
952
2107
  filter = filter.replace("filtro-", "");
953
2108
  filters[filter] = [];
954
2109
  uniqueEntries.forEach(entry => {
@@ -962,12 +2117,12 @@ const ponchoTableDependant = opt => {
962
2117
  /* HELPERS FILTRO DEPENDIENTE */
963
2118
  /**
964
2119
  * Valida los parents
965
- *
2120
+ *
966
2121
  * @param {integer} parent Índice (filtro) seleccionado.
967
2122
  * @return {boolean}
968
- */
2123
+ */
969
2124
  const _validateSteps = (parent, entry, label, values) => {
970
- // Verifico que por cada entrada el valor(label), se
2125
+ // Verifico que por cada entrada el valor(label), se
971
2126
  // encuentre en cada uno de los parents.
972
2127
  // El bucle termina cuando llega al índice seleccionado.
973
2128
  const range = [...Array(_parentElement(parent + 1)).keys()];
@@ -976,8 +2131,8 @@ const ponchoTableDependant = opt => {
976
2131
  // si en su defecto, está vacío.
977
2132
  if(
978
2133
  (
979
- (entry[filtersList[_parentElement(parent-1)]] ==
980
- values[_parentElement(parent-1)]) &&
2134
+ (entry[filtersList[_parentElement(parent-1)]] ==
2135
+ values[_parentElement(parent-1)]) &&
981
2136
  (entry[filtersList[_parentElement(parent)]] == label)
982
2137
  ) || values[_parentElement(parent-1)] == "")
983
2138
  {
@@ -996,7 +2151,7 @@ const ponchoTableDependant = opt => {
996
2151
  * @param {integer} children Indice del hijo del seleccionado.
997
2152
  * @param {string} label value del filtro seleccionado.
998
2153
  * @return {object} Listado de elementos únicos para el select.
999
- */
2154
+ */
1000
2155
  const _allFromParent = (parent, children, label) => {
1001
2156
  const filterList = gapi_data.entries.flatMap(e => {
1002
2157
  const evaluatedEntry = e[filtersList[_parentElement(children)]];
@@ -1008,23 +2163,24 @@ const ponchoTableDependant = opt => {
1008
2163
  .includes(_toCompareString(e));
1009
2164
  });
1010
2165
  return customFilters;
1011
- }
2166
+ }
1012
2167
  return evaluatedEntry;
1013
- }
2168
+ }
1014
2169
  return false;
1015
2170
 
1016
2171
  }).filter(f => f);
1017
2172
 
1018
- const uniqueList = distinct(filterList);
1019
- uniqueList.sort(_sortAlphaNumeric);
2173
+ const uniqueList = _sortAlphaNumeric(
2174
+ distinct(filterList), filtersList[children]
2175
+ );
1020
2176
  return uniqueList;
1021
2177
  };
1022
2178
 
1023
-
2179
+
1024
2180
  /**
1025
2181
  * Prepara un string para una comparación case sensitive y sin
1026
2182
  * caracteres especiales.
1027
- * @param {string} value Valor a comparar.
2183
+ * @param {string} value Valor a comparar.
1028
2184
  * @returns {boolean}
1029
2185
  */
1030
2186
  const _toCompareString = value => replaceSpecialChars(value.toLowerCase());
@@ -1032,7 +2188,7 @@ const ponchoTableDependant = opt => {
1032
2188
 
1033
2189
  /**
1034
2190
  * Lista los valores que deben ir en un filtro según su parent.
1035
- *
2191
+ *
1036
2192
  * @param {integer} parent Indice de filtro seleccionado.
1037
2193
  * @param {string} label value del filtro seleccionado.
1038
2194
  * @param {integer} children Indice del hijo del seleccionado.
@@ -1045,7 +2201,7 @@ const ponchoTableDependant = opt => {
1045
2201
  const items = gapi_data.entries.flatMap(entry => {
1046
2202
  const range = _validateSteps(parent, entry, label, values);
1047
2203
  if(
1048
- (entry[filtersList[_parentElement(children - 1)]] == label) &&
2204
+ (entry[filtersList[_parentElement(children - 1)]] == label) &&
1049
2205
  (range)){
1050
2206
  const evaluatedEntry = entry[filtersList[_parentElement(children)]];
1051
2207
  if(_isCustomFilter(children, filtro)){
@@ -1063,8 +2219,9 @@ const ponchoTableDependant = opt => {
1063
2219
  return;
1064
2220
  }).filter(f => f);
1065
2221
 
1066
- const uniqueList = distinct(items);
1067
- uniqueList.sort(_sortAlphaNumeric);
2222
+ const uniqueList = _sortAlphaNumeric(
2223
+ distinct(items), filtersList[children]
2224
+ );
1068
2225
  return uniqueList;
1069
2226
  };
1070
2227
 
@@ -1077,7 +2234,7 @@ const ponchoTableDependant = opt => {
1077
2234
  const _isCustomFilter = key => {
1078
2235
  const filtersKeys = Object.keys(filtro);
1079
2236
  if(asFilter.hasOwnProperty(`filtro-${filtersKeys[key]}`)){
1080
- return true
2237
+ return true
1081
2238
  }
1082
2239
  return false;
1083
2240
  };
@@ -1091,7 +2248,7 @@ const ponchoTableDependant = opt => {
1091
2248
  const _customFilter = key => {
1092
2249
  const filtersKeys = Object.keys(filtro);
1093
2250
  if(asFilter.hasOwnProperty(`filtro-${filtersKeys[key]}`)){
1094
- return asFilter[`filtro-${filtersKeys[key]}`];
2251
+ return asFilter[`filtro-${filtersKeys[key]}`];
1095
2252
  }
1096
2253
  return [];
1097
2254
  };
@@ -1099,7 +2256,7 @@ const ponchoTableDependant = opt => {
1099
2256
 
1100
2257
  /**
1101
2258
  * Filtra select hijos en base a un item del padre.
1102
- *
2259
+ *
1103
2260
  * @param {integer} filterIndex Índice de filtro o número de filtro.
1104
2261
  * @param {string} label Label del indice seleccionado
1105
2262
  * @return {void}
@@ -1110,8 +2267,8 @@ const ponchoTableDependant = opt => {
1110
2267
  // Redibujo los _option_ por cada `select` (filtro).
1111
2268
  // Hago un `for()` iniciando en el hijo de filterIndex.
1112
2269
  for(let i = filterIndex + 1; i <= filtros.length; i++){
1113
- if(filtros.length == i ){
1114
- break;
2270
+ if(filtros.length == i ){
2271
+ break;
1115
2272
  }
1116
2273
  let itemList = _filterOptionList(filterIndex, i, label);
1117
2274
  if(itemList.length == 0){
@@ -1125,7 +2282,7 @@ const ponchoTableDependant = opt => {
1125
2282
  if(!e.trim()){
1126
2283
  return;
1127
2284
  }
1128
- // Mantengo el filtro del hijo si existe en el
2285
+ // Mantengo el filtro del hijo si existe en el
1129
2286
  // listado filtrado.
1130
2287
  let checked = (filterValues[i] == e ? true : false);
1131
2288
  select.appendChild(_optionSelect(i, e, e, checked));
@@ -1133,6 +2290,7 @@ const ponchoTableDependant = opt => {
1133
2290
  }
1134
2291
  };
1135
2292
 
2293
+
1136
2294
  /**
1137
2295
  * Asigna selectores al contenedor de los filtros.
1138
2296
  * @returns {undefined}
@@ -1163,34 +2321,364 @@ const ponchoTableDependant = opt => {
1163
2321
  * Si la URL tiene un valor por _hash_ lo obtiene considerandolo su id.
1164
2322
  * @returns {void}
1165
2323
  */
1166
- const hasHash = () => {
1167
- let hash = window.location.hash.replace("#", "");
1168
- return hash || false;
1169
- };
2324
+ const hasHash = () => {
2325
+ let hash = window.location.hash.replace("#", "");
2326
+ return hash || false;
2327
+ };
2328
+
2329
+
2330
+ /**
2331
+ * Visualización de la tabla
2332
+ *
2333
+ * @param {boolean} visibility Oculta y muestra la tabla.
2334
+ * @returns {undefined}
2335
+ */
2336
+ _hideTable = (visibility=true) => {
2337
+ const display = (visibility ? "none" : "block");
2338
+ const reverseDisplay = (visibility ? "block" : "none");
2339
+ document
2340
+ .querySelectorAll(
2341
+ `[data-visible-as-table="true"],#ponchoTable_wrapper`)
2342
+ .forEach(element => element.style.display = display);
2343
+
2344
+ document
2345
+ .querySelectorAll(`[data-visible-as-table="false"]`)
2346
+ .forEach(element => element.style.display = reverseDisplay);
2347
+ };
2348
+
2349
+
2350
+ /**
2351
+ * Tipo de tabla responsive.
2352
+ *
2353
+ * @param {string} type Uno de los tres tipo de columna.
2354
+ * @returns {string|undefined}
2355
+ */
2356
+ _responsiveType = function(type){
2357
+ if(typeof type !== "string"){
2358
+ console.error("El tipo de columna responsive debe ser un string.");
2359
+ return;
2360
+ }
2361
+ const typeToLower = type.toLowerCase();
2362
+ const types = ["none", "column", "inline"];
2363
+ if(!types.includes(typeToLower)){
2364
+ console.error("El tipo de columna responsive es inválido.");
2365
+ return;
2366
+ }
2367
+
2368
+ return typeToLower;
2369
+ }
2370
+
2371
+
2372
+ /**
2373
+ * Valida las columnas para la tabla responsive
2374
+ *
2375
+ * @param {object} cols Array con los números de columna válidos.
2376
+ * @returns {object|undefined}
2377
+ */
2378
+ _responsiveColumns = function(cols){
2379
+ if(!Array.isArray(cols)){
2380
+ console.error("Las columnas ocultas deben ");
2381
+ return;
2382
+ }
2383
+
2384
+ if(!cols.every(e => typeof e === "number")){
2385
+ console.error("Solo son válidos los númerso enteros para columnas");
2386
+ return;
2387
+ }
2388
+
2389
+ let sanitizedArray = [... new Set(cols)];
2390
+ const hasZeroAsigned = sanitizedArray.indexOf(0);
2391
+ const removedElement = (hasZeroAsigned !== -1 ? sanitizedArray.splice(
2392
+ hasZeroAsigned, 1) : sanitizedArray);
2393
+
2394
+ if(removedElement){
2395
+ console.warn(
2396
+ "la columna 0 no se puede asignar. Se borra la asignación.");
2397
+ }
2398
+ if(sanitizedArray.length < 1){
2399
+ console.error(
2400
+ `No hay columnas asignadas en el array: ${sanitizedArray}`);
2401
+ return;
2402
+ }
2403
+
2404
+ return sanitizedArray;
2405
+ }
2406
+
2407
+
2408
+ /**
2409
+ * Compone el objeto para colsDefs.
2410
+ *
2411
+ * @param {object} columns Array con los números de columna válidos.
2412
+ * @param {string} type Tipo de columna válido
2413
+ * @param {boolean} orderable Especifica si se puede ordenar por la columna.
2414
+ * @returns {object}
2415
+ */
2416
+ _responsiveCols = function(columns, orderable, type="none"){
2417
+ columns = _responsiveColumns(columns);
2418
+
2419
+ if(!columns){
2420
+ return {};
2421
+ }
2422
+
2423
+ return {
2424
+ className: _responsiveType(type),
2425
+ orderable: (typeof orderable === "boolean" ? orderable : false),
2426
+ targets: columns
2427
+ };
2428
+ }
2429
+
2430
+
2431
+ /**
2432
+ * Asignación de prioridades en la versión responsive.
2433
+ *
2434
+ * @example
2435
+ * _responsivePriorities([1,2]);
2436
+ * // [{responsivePriority: 1, targets: 2}]
2437
+ * @param {*} priorities
2438
+ */
2439
+ function _responsivePriorities(priorities){
2440
+ if(!Array.isArray(priorities)){
2441
+ console.error("`responsivePriorities`, debe ser un array.");
2442
+ return [];
2443
+ }
2444
+ const results = priorities.map(m => {
2445
+ const [responsivePriority=false, targets=false] = m;
2446
+ if(typeof responsivePriority !== "number"){
2447
+ console.error("El orden de prioridad debe ser un número.");
2448
+ return;
2449
+ }
2450
+ if(typeof targets !== "number"){
2451
+ console.warn(
2452
+ `La asignación de columna debe ser un número. Se
2453
+ elimina el valor: "${targets}".`)
2454
+ return {responsivePriority};
2455
+ }
2456
+ return {responsivePriority, targets};
2457
+ });
2458
+
2459
+ return results.filter(f => f);
2460
+ }
2461
+
2462
+
2463
+ /**
2464
+ * Modifica el tamaño de las columnas
2465
+ * @param {object} def Array con definiciones de ancho y target
2466
+ * @returns {object}
2467
+ */
2468
+ function _columnsWidth(def){
2469
+ if(!Array.isArray(def)){
2470
+ console.error("`columnsWidth`, debe ser un array.");
2471
+ return [];
2472
+ }
2473
+ const regex = /(?<value>[0-9]+)(?<measure>\%|px|em|rem|pt)/;
2474
+ const results = def.map(m => {
2475
+ const [width=false, targets=false] = m;
2476
+ if(!regex.test(width)){
2477
+ console.error(
2478
+ "El valor asignado al ancho de columna no es válido.");
2479
+ return;
2480
+ }
2481
+ if(typeof targets !== "number"){
2482
+ console.warn(
2483
+ `La asignación de columna debe ser un número. Se
2484
+ elimina el valor: "${targets}".`)
2485
+ return {width};
2486
+ }
2487
+ return {width, targets};
2488
+ });
2489
+
2490
+ return results.filter(f => f);
2491
+ }
2492
+
2493
+
2494
+ /**
2495
+ * Ejecuta un evento
2496
+ *
2497
+ * @param {string} selector Selector html
2498
+ * @param {string} value Valor para definir en el input
2499
+ * @param {string} eventType Tipo de evento, ej: click, change, keypress
2500
+ */
2501
+ function _eventDispatcher(selector, value, eventType){
2502
+ const element = document.querySelectorAll(`#${selector}`);
2503
+ element.forEach(ele => {
2504
+ setTimeout(function(){
2505
+ ele.value = value;
2506
+ const event = new Event(eventType);
2507
+ ele.dispatchEvent(event);
2508
+ },50)
2509
+ });
2510
+ }
2511
+
2512
+
2513
+ /**
2514
+ * window pushState
2515
+ *
2516
+ * @param {string} url Url
2517
+ * @returns {undefined}
2518
+ */
2519
+ function _pushState(url){
2520
+ if (!pushState) {
2521
+ console.log('sin pushstate')
2522
+ return;
2523
+ }
2524
+ window.history.pushState({}, "", url);
2525
+ }
2526
+
2527
+
2528
+ /**
2529
+ * Imprime la url
2530
+ * @summary Imprime la url con varios métodos
2531
+ */
2532
+ function _shareLink(){
2533
+ if(!urlParams){
2534
+ return;
2535
+ }
2536
+
2537
+ // @todo Permitir que se mantengan parámetros seteados previamente.
2538
+ // const searchUrl = new URLSearchParams(window.location.search);
2539
+ // let searchValues = Object.entries(Object.fromEntries(searchUrl));
2540
+
2541
+ const url = new URL(window.location.pathname, window.location.origin);
2542
+
2543
+ const filters = filtersList.map(m => m.replace("filtro-", ""));
2544
+ const inputs = [ ...filters, "ponchoTableSearch" ];
2545
+ const inputValuesConcat = inputs.map(function(input){
2546
+ const v = document.getElementById(input);
2547
+ if(v){
2548
+ return [input, v.value];
2549
+ }
2550
+ return [];
2551
+ });
2552
+
2553
+
2554
+
2555
+
2556
+ if(!inputValuesConcat.some(s => s.length > 0)){
2557
+ return;
2558
+ }
2559
+
2560
+ if(inputValuesConcat.some(e => e[1].length > 0)){
2561
+ _sharing();
2562
+ } else {
2563
+ document
2564
+ .querySelectorAll("#ponchoTableShareButton")
2565
+ .forEach(e => e.remove());
2566
+ }
2567
+
2568
+ // Agrego parámetros
2569
+ inputValuesConcat.forEach(input => {
2570
+ let [key, value] = input;
2571
+ key = (key == "ponchoTableSearch" ? "buscar" : key);
2572
+ if(value.trim() == ""){
2573
+ return;
2574
+ }
2575
+ url.searchParams.append(key, value);
2576
+ });
2577
+
2578
+ // Crea un tag <a/>
2579
+ document.querySelectorAll(".js-sharelink-tag").forEach(function(e){
2580
+ e.innerHTML = "";
2581
+ const label = e.dataset.label;
2582
+ const link = document.createElement("a");
2583
+ link.href = url.href;
2584
+
2585
+ let refactorLabel = (label ? label : url.href);
2586
+ link.textContent = refactorLabel;
2587
+
2588
+ e.appendChild(link);
2589
+ });
2590
+
2591
+ // Imprime la url como texto en un attributo o en el cuerpo de la
2592
+ // etiqueta.
2593
+ document.querySelectorAll(".js-sharelink-text").forEach(function(e){
2594
+ // Si el usuario agregó el dataset attr, imprimo la url
2595
+ // en el attributo pasado como valor.
2596
+ const attr = e.dataset.attr;
2597
+ if(attr){
2598
+ e.setAttribute(attr, url.href);
2599
+ } else {
2600
+ e.innerHTML = url.href;
2601
+ }
2602
+ });
2603
+
2604
+ _pushState(url.href);
2605
+ }
2606
+
2607
+
2608
+ /**
2609
+ * Crea un listener para copiar a porta-papeles
2610
+ * @returns {undefined}
2611
+ */
2612
+ function _copyToClipboard(){
2613
+ if(typeof copyToClipboard != "function"){
2614
+ return;
2615
+ }
2616
+ const toclipboard = document.querySelectorAll("[data-toclipboard]");
2617
+ toclipboard.forEach(elem => {
2618
+ const id = elem.dataset.toclipboard;
2619
+ elem.addEventListener("click", (e) => {
2620
+ e.preventDefault();
2621
+ copyToClipboard(`#${id}`);
2622
+ });
2623
+ });
2624
+ }
1170
2625
 
1171
2626
 
1172
2627
  /**
1173
- * Visualización de la tabla
1174
- *
1175
- * @param {boolean} visibility Oculta y muestra la tabla.
2628
+ * Crea un botón para compartir resultados
1176
2629
  * @returns {undefined}
1177
2630
  */
1178
- _hideTable = (visibility=true) => {
1179
- const display = (visibility ? "none" : "block");
1180
- const reverseDisplay = (visibility ? "block" : "none");
1181
- document
1182
- .querySelectorAll(
1183
- `[data-visible-as-table="true"],#ponchoTable_wrapper`)
1184
- .forEach(element => element.style.display = display);
2631
+ function _sharing(){
2632
+ if(!copyResults){
2633
+ return;
2634
+ }
1185
2635
 
1186
- document
1187
- .querySelectorAll(`[data-visible-as-table="false"]`)
1188
- .forEach(element => element.style.display = reverseDisplay);
1189
- };
2636
+ try {
2637
+ document
2638
+ .querySelectorAll("#ponchoTableShareButton")
2639
+ .forEach(e => e.remove());
2640
+ } catch (error) {
2641
+ console.error("Error:", "No se encuentra el selector");
2642
+ }
2643
+
2644
+ const b = document.createElement('div');
2645
+ b.id = "ponchoTableShareButton";
2646
+ b.innerHTML = `<div class="dropdown">
2647
+ <button
2648
+ class="btn btn-sm btn-default dropdown-toggle"
2649
+ type="button"
2650
+ id="share-table-data"
2651
+ data-toggle="dropdown"
2652
+ aria-haspopup="true"
2653
+ aria-expanded="false">
2654
+ Compartir resultados
2655
+ <span class="caret"></span>
2656
+ </button>
2657
+ <div
2658
+ class="dropdown-menu p-y-1 p-x-1"
2659
+ aria-labelledby="share-table-data">
2660
+ <p class="js-sharelink-tag m-b-0 small" id="foo"></p>
2661
+ <a
2662
+ href="#" data-toclipboard="foo"
2663
+ class="small btn btn-sm btn-default m-b-0 m-t-1">
2664
+ Copiar al portapapeles</a>
2665
+ </div>
2666
+ </div>`;
2667
+
2668
+ const info = document.querySelector("#ponchoTable_info");
2669
+ const infoContainer = info.parentElement;
2670
+ infoContainer.classList.add("share");
2671
+ infoContainer.appendChild(b);
2672
+
2673
+ headStyle(
2674
+ "ponchoTable-share-button",
2675
+ `.share{display:flex;gap:1.5em;align-items:baseline}.share .dropdown-menu{min-width:250px}`);
2676
+ _copyToClipboard();
2677
+ }
1190
2678
 
1191
2679
 
1192
2680
  /**
1193
- * Inicializa DataTable() y modifica elementos para adaptarlos a
2681
+ * Inicializa DataTable() y modifica elementos para adaptarlos a
1194
2682
  * GoogleSheets y requerimientos de ArGob.
1195
2683
  */
1196
2684
  const initDataTable = () => {
@@ -1213,63 +2701,98 @@ const ponchoTableDependant = opt => {
1213
2701
 
1214
2702
  /**
1215
2703
  * Instacia DataTable()
1216
- */
1217
- let tabla = jQuery("#ponchoTable").DataTable({
1218
- "initComplete" : (settings, json) => {
2704
+ */
2705
+ let dataTableOptions = {
2706
+ initComplete: (settings, json) => {
1219
2707
  if(wizard){
1220
2708
  _hideTable();
1221
2709
  }
1222
2710
  },
1223
- "lengthChange": false,
1224
- "autoWidth": false,
1225
- "pageLength": opt.cantidadItems,
1226
- "columnDefs": [
1227
- { "type": "html-num", "targets": opt.tipoNumero },
1228
- { "targets": opt.ocultarColumnas, "visible": false }
2711
+ lengthChange: false,
2712
+ autoWidth: false,
2713
+ pageLength: opt.cantidadItems,
2714
+ columnDefs: [
2715
+ {
2716
+ type: "html-num",
2717
+ targets: opt.tipoNumero
2718
+ },
2719
+ {
2720
+ targets: opt.ocultarColumnas,
2721
+ visible: false
2722
+ }
1229
2723
  ],
1230
- "ordering": opt.orden,
1231
- "order": [
2724
+ ordering: opt.orden,
2725
+ order: [
1232
2726
  [opt.ordenColumna - 1, opt.ordenTipo]
1233
2727
  ],
1234
- "dom": "<'row'<'col-sm-6'l><'col-sm-6'f>>" +
1235
- "<'row'<'col-sm-12'i>>" +
1236
- "<'row'<'col-sm-12'tr>>" +
1237
- "<'row'<'col-md-offset-3 col-md-6 col-sm-offset-2 col-sm-8'p>>",
1238
- "language": {
1239
- "sProcessing": "Procesando...",
1240
- "sLengthMenu": "Mostrar _MENU_ registros",
1241
- "sZeroRecords": "No se encontraron resultados",
1242
- "sEmptyTable": "Ningún dato disponible en esta tabla",
1243
- "sInfo": "_TOTAL_ resultados",
1244
- "sInfoEmpty": "No hay resultados",
2728
+ dom: "<\"row\"<\"col-sm-6\"l><\"col-sm-6\"f>>" +
2729
+ "<\"row\"<\"col-sm-12\"i>>" +
2730
+ "<\"row\"<\"col-sm-12\"tr>>" +
2731
+ "<\"row\"<\"col-md-offset-3 col-md-6 "
2732
+ + "col-sm-offset-2 col-sm-8\"p>>",
2733
+ language: {
2734
+ sProcessing: "Procesando...",
2735
+ sLengthMenu: "Mostrar _MENU_ registros",
2736
+ sZeroRecords: "No se encontraron resultados",
2737
+ sEmptyTable: "Ningún dato disponible en esta tabla",
2738
+ sInfo: "_TOTAL_ resultados",
2739
+ sInfoEmpty: "No hay resultados",
1245
2740
  //"sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
1246
- "sInfoFiltered": "",
1247
- "sInfoPostFix": "",
1248
- "sSearch": "Buscar:",
1249
- "sUrl": "",
1250
- "sInfoThousands": ".",
1251
- "sLoadingRecords": "Cargando...",
1252
-
1253
- "oPaginate": {
1254
- "sFirst": "<<",
1255
- "sLast": ">>",
1256
- "sNext": ">",
1257
- "sPrevious": "<"
2741
+ sInfoFiltered: "",
2742
+ sInfoPostFix: "",
2743
+ sSearch: "Buscar:",
2744
+ sUrl: "",
2745
+ sInfoThousands: ".",
2746
+ sLoadingRecords: "Cargando...",
2747
+ oPaginate: {
2748
+ sFirst: "<<",
2749
+ sLast: ">>",
2750
+ sNext: ">",
2751
+ sPrevious: "<"
1258
2752
  },
1259
- "oAria": {
1260
- "sSortAscending":
1261
- ": Activar para ordenar la columna de manera ascendente",
1262
- "sSortDescending":
1263
- ": Activar para ordenar la columna de manera descendente",
1264
- "paginate": {
1265
- "first": 'Ir a la primera página',
1266
- "previous": 'Ir a la página anterior',
1267
- "next": 'Ir a la página siguiente',
1268
- "last": 'Ir a la última página'
2753
+ oAria: {
2754
+ sSortAscending:
2755
+ ": Activar para ordenar la columna "
2756
+ + "de manera ascendente",
2757
+ sSortDescending:
2758
+ ": Activar para ordenar la columna de "
2759
+ + "manera descendente",
2760
+ paginate: {
2761
+ first: "Ir a la primera página",
2762
+ previous: "Ir a la página anterior",
2763
+ next: "Ir a la página siguiente",
2764
+ last: "Ir a la última página"
1269
2765
  }
1270
2766
  }
1271
2767
  }
1272
- });
2768
+ };
2769
+
2770
+ // Ancho de columnas
2771
+ if(typeof opt.columnsWidth !== "undefined" && opt.columnsWidth){
2772
+ dataTableOptions.columnDefs = dataTableOptions.columnDefs.concat(
2773
+ _columnsWidth(opt.columnsWidth));
2774
+ }
2775
+
2776
+ /**
2777
+ * Opciones responsive
2778
+ */
2779
+ if(typeof opt.responsiveDetailsColumns !== "undefined" &&
2780
+ opt.responsiveDetailsColumns.length > 0){
2781
+
2782
+ const responsiveDetails = _responsiveCols(
2783
+ opt.responsiveDetailsColumns,
2784
+ opt.responsiveDetailsOrderable,
2785
+ opt.responsiveDetailsType);
2786
+
2787
+ const priorities = _responsivePriorities(opt.responsivePriorities);
2788
+
2789
+ dataTableOptions.columnDefs = dataTableOptions.columnDefs.concat(
2790
+ responsiveDetails, priorities);
2791
+
2792
+ dataTableOptions.responsive = true;
2793
+ }
2794
+
2795
+ let tabla = jQuery("#ponchoTable").DataTable(dataTableOptions);
1273
2796
 
1274
2797
  /**
1275
2798
  * Buscador por palabra
@@ -1279,24 +2802,29 @@ const ponchoTableDependant = opt => {
1279
2802
  tabla
1280
2803
  .search(jQuery.fn.DataTable.ext.type.search.string(this.value))
1281
2804
  .draw();
2805
+ _shareLink();
1282
2806
  });
1283
2807
 
2808
+
1284
2809
  // REMUEVE LOS FILTROS
1285
2810
  jQuery("#ponchoTable_filter").parent().parent().remove();
1286
2811
 
1287
2812
  // MUESTRA FILTRO PERSONALIZADO
1288
- const ponchoTableOption = document.querySelectorAll("#ponchoTableFiltro option");
2813
+ const ponchoTableOption =
2814
+ document.querySelectorAll("#ponchoTableFiltro option");
1289
2815
  if (ponchoTableOption.length > 1) {
1290
- document.querySelector("#ponchoTableFiltroCont").style.display = "block";
2816
+ document
2817
+ .querySelector("#ponchoTableFiltroCont")
2818
+ .style.display = "block";
1291
2819
  }
1292
2820
 
1293
2821
 
1294
2822
  /**
1295
- * Valida si un componente select tiene options con value.
1296
- *
2823
+ * Valida si un componente select tiene options con value.
2824
+ *
1297
2825
  * @summary El objeto de éste método es evitar traer selects que tengan
1298
- * options vacíos.
1299
- * @param {string} selector Selector del elemento select
2826
+ * options vacíos.
2827
+ * @param {string} selector Selector del elemento select
1300
2828
  * @returns {boolean}
1301
2829
  */
1302
2830
  const _selectHasValues = selector => {
@@ -1308,7 +2836,7 @@ const ponchoTableDependant = opt => {
1308
2836
 
1309
2837
  /**
1310
2838
  * Modo wizard para los filtros.
1311
- *
2839
+ *
1312
2840
  * @param {object} filters Listado de filtros.
1313
2841
  * @param {interger} column Indice de columna.
1314
2842
  * @param {string} valFilter Value del select
@@ -1324,13 +2852,13 @@ const ponchoTableDependant = opt => {
1324
2852
  if(selectHasValues && valFilter && key <= column + 1){
1325
2853
  displayStatus = "block";
1326
2854
 
1327
- } else if(selectHasValues && !valFilter && key <= column + 1) {
2855
+ } else if(selectHasValues && !valFilter && key <= column + 1){
1328
2856
  const nextFilter = document
1329
2857
  .querySelectorAll(`#${filters[column + 1]}`)
1330
2858
  nextFilter.forEach(element => element.innerHTML = "");
1331
2859
  displayStatus = "block";
1332
2860
  tableStatus = false;
1333
- }
2861
+ }
1334
2862
 
1335
2863
  const currentFilter = document
1336
2864
  .querySelectorAll(`[data-filter-name="${filter}"]`)
@@ -1338,13 +2866,13 @@ const ponchoTableDependant = opt => {
1338
2866
  .forEach(element => element.style.display = displayStatus);
1339
2867
  });
1340
2868
 
1341
- if(
1342
- _selectHasValues(`#${filters[column]}`) &&
1343
- valFilter &&
2869
+ if(
2870
+ _selectHasValues(`#${filters[column]}`) &&
2871
+ valFilter &&
1344
2872
  !_selectHasValues(`#${filters[column + 1]}`)
1345
2873
  ){
1346
2874
  tableStatus = true;
1347
- }
2875
+ }
1348
2876
 
1349
2877
 
1350
2878
  if(tableStatus){
@@ -1357,14 +2885,14 @@ const ponchoTableDependant = opt => {
1357
2885
 
1358
2886
  /**
1359
2887
  * Filtro en el change de cada select (filtro).
1360
- *
2888
+ *
1361
2889
  * @summary Por por cada interacción con un filtro, obtiene el índice de
1362
2890
  * columna y lo pasa con el valor del select a _dependantFilters(). Ésta
1363
2891
  * funciión redibuja los filtros en de forma dependiente según el valor
1364
2892
  * de la elección.
1365
2893
  * @see replaceSpecialChars() on poncho.min.js
1366
2894
  * @return {undefined}
1367
- */
2895
+ */
1368
2896
  jQuery("select[data-filter]").change(function() {
1369
2897
  const column = jQuery(this).find("option:selected").data("column");
1370
2898
  const valFilter = jQuery(this).find("option:selected").val();
@@ -1377,7 +2905,7 @@ const ponchoTableDependant = opt => {
1377
2905
  const filters = Object.keys(filtro);
1378
2906
  const filterValues = _filterValues();
1379
2907
  const filterIndex = filter => {
1380
- return Object
2908
+ return Object
1381
2909
  .keys(gapi_data.headers)
1382
2910
  .indexOf(`filtro-${filter}`);
1383
2911
  };
@@ -1387,6 +2915,7 @@ const ponchoTableDependant = opt => {
1387
2915
  const term = _searchTerm(filterValues[k]);
1388
2916
  const cleanTerm = _searchTerm(
1389
2917
  replaceSpecialChars(filterValues[k]));
2918
+
1390
2919
  if(_isCustomFilter(k, filtro)){
1391
2920
  tabla.columns(columnIndex)
1392
2921
  .search(_toCompareString(filterValues[k]));
@@ -1394,22 +2923,41 @@ const ponchoTableDependant = opt => {
1394
2923
  tabla
1395
2924
  .columns(columnIndex)
1396
2925
  .search(
1397
- (filterValues[k] ? `^(${term}|${cleanTerm})$` : ""),
1398
- true, false, true
2926
+ (filterValues[k] ? `^(${term}|${cleanTerm})$` : ""),
2927
+ true, false, true
1399
2928
  );
1400
2929
  }
1401
2930
  });
2931
+
1402
2932
  tabla.draw();
1403
- if(wizard){
2933
+ window.addEventListener("popstate", (event) => {
2934
+
2935
+ });
2936
+ if(wizard){
1404
2937
  _wizardFilters(filters, column, valFilter);
1405
2938
  }
2939
+ _shareLink();
1406
2940
  });
1407
2941
 
1408
-
2942
+
2943
+ function filterParams(filterList, str){
2944
+ const regex = new RegExp('filter(?<index>(?:[1-9][0-9]|[1-9]))', '');
2945
+ const regexResult = regex.exec(str);
2946
+
2947
+ if(regexResult === null){
2948
+ return str;
2949
+ }
2950
+
2951
+ const filters = filterList.map(m => m.replace("filtro-", ""));
2952
+ const filter = filters[ regexResult.groups.index - 1 ];
2953
+ return (typeof filter !== "undefined" ? filter : str);
2954
+ }
2955
+
2956
+
1409
2957
  // Si está habilitada la búsqueda por hash.
1410
2958
  if(opt.hasOwnProperty("hash") && opt.hash){
1411
2959
  const term = hasHash();
1412
- const searchTerm = (term ? decodeURIComponent(term) : "");
2960
+ const searchTerm = (term ? decodeURIComponent(term) : "");
1413
2961
  const element = document.querySelectorAll("#ponchoTableSearch");
1414
2962
  element.forEach(ele => {
1415
2963
  ele.value = searchTerm;
@@ -1418,14 +2966,53 @@ const ponchoTableDependant = opt => {
1418
2966
  .draw();
1419
2967
  });
1420
2968
  }
2969
+
2970
+
2971
+ // Si está seteado urlParams habilita los filtros y búsquedas por
2972
+ // Url.
2973
+ if(urlParams){
2974
+ const u = new URLSearchParams(window.location.search);
2975
+ for (const key of u.keys()){
2976
+ let value = u.get(key);
2977
+ let refactorKey = filterParams(filtersList, key);
2978
+
2979
+ if(value.trim() == ""){
2980
+ return;
2981
+ }
2982
+
2983
+ if(key == "buscar"){
2984
+ _eventDispatcher(`ponchoTableSearch`, value, "keyup");
2985
+ } else {
2986
+ _eventDispatcher(refactorKey, value, "change");
2987
+ }
2988
+ };
2989
+ }
1421
2990
  } // end initDataTable
1422
-
1423
2991
 
1424
2992
 
2993
+ /**
2994
+ * Permite definir el orden de los headers.
2995
+ * @param {*} headers {object}
2996
+ * @param {*} order
2997
+ * @returns
2998
+ */
2999
+ const _headersOrder = (headers) => {
3000
+ if(opt.hasOwnProperty("headersOrder") && opt.headersOrder.length > 0){
3001
+ let refactorHeaders = {};
3002
+ for(i of opt.headersOrder){
3003
+ if( headers.hasOwnProperty(i) ){
3004
+ refactorHeaders[i] = headers[i];
3005
+ }
3006
+ }
3007
+ return refactorHeaders;
3008
+ }
3009
+ return headers;
3010
+ };
3011
+
1425
3012
 
1426
3013
  /**
1427
3014
  * Imprime DataTable
1428
- *
3015
+ *
1429
3016
  * @param {object} data JSON data
1430
3017
  */
1431
3018
  const render = data => {
@@ -1433,13 +3020,16 @@ const ponchoTableDependant = opt => {
1433
3020
  gapi_data = data;
1434
3021
  // Defino las entradas
1435
3022
  gapi_data.entries = (
1436
- typeof opt.refactorEntries === "function" &&
1437
- opt.refactorEntries !== null ?
3023
+ typeof opt.refactorEntries === "function" &&
3024
+ opt.refactorEntries !== null ?
1438
3025
  opt.refactorEntries(gapi_data.entries) : gapi_data.entries
1439
3026
  );
1440
3027
  // Defino los headers que se van a utilizar
1441
3028
  gapi_data.headers = (opt.hasOwnProperty("headers") && opt.headers ?
1442
3029
  opt.headers : gapi_data.headers);
3030
+
3031
+ gapi_data.headers = _headersOrder(gapi_data.headers, opt.headersOrder);
3032
+
1443
3033
  // Listado de filtros
1444
3034
  filtersList = Object
1445
3035
  .keys(gapi_data.headers)
@@ -1451,7 +3041,7 @@ const ponchoTableDependant = opt => {
1451
3041
  _filtersContainerClassList();
1452
3042
  _searchContainerClassList();
1453
3043
  _createTable(gapi_data);
1454
- _createFilters(gapi_data);
3044
+ _createFilters(gapi_data);
1455
3045
 
1456
3046
  document.querySelector("#ponchoTableSearchCont")
1457
3047
  .style.display = "block";
@@ -1459,34 +3049,44 @@ const ponchoTableDependant = opt => {
1459
3049
  .classList.remove("state-loading");
1460
3050
 
1461
3051
  initDataTable();
3052
+
3053
+ _shareLink();
3054
+
3055
+ setTimeout(() => {
3056
+ const ele = document.querySelectorAll(`[id^="dt-search-"], #ponchoTable_filter`);
3057
+ ele.forEach(elem => {
3058
+ elem.closest(".row").remove();
3059
+ });
3060
+ }, 300);
1462
3061
  };
1463
3062
 
1464
3063
 
1465
3064
  /**
1466
3065
  * Obtiene el sheet e inicializa la tabla y filtros.
1467
- *
3066
+ *
1468
3067
  * @param {string} url URL del dataset JSON
1469
3068
  */
1470
3069
  const getSheetValues = url => {
1471
3070
  jQuery.getJSON(url, function(data){
1472
3071
  const gapi = new GapiSheetData();
1473
3072
  gapi_data = gapi.json_data(data);
1474
-
3073
+
1475
3074
  render(gapi_data);
3075
+
1476
3076
  }); // end async
1477
3077
  };
1478
3078
 
1479
3079
 
1480
3080
  /**
1481
3081
  * Obtiene el sheet por número de hoja y nombre del spread.
1482
- *
3082
+ *
1483
3083
  * @param {integer} sheetNumber Número de hoja sin iniciar en 0.
1484
3084
  */
1485
3085
  const getSheetName = sheetNumber => {
1486
3086
  const gapi = new GapiSheetData();
1487
3087
  const uriApi = [
1488
- 'https://sheets.googleapis.com/v4/spreadsheets/',
1489
- opt.idSpread, '/?alt=json&key=',
3088
+ "https://sheets.googleapis.com/v4/spreadsheets/",
3089
+ opt.idSpread, "/?alt=json&key=",
1490
3090
  gapi.gapi_key].join("");
1491
3091
 
1492
3092
  jQuery.getJSON(uriApi, function function_name(response) {
@@ -1500,8 +3100,9 @@ const ponchoTableDependant = opt => {
1500
3100
  if (opt.jsonData){
1501
3101
  const headers = Object.fromEntries(
1502
3102
  Object.keys(opt.jsonData[0]).map(e => [e,e])
1503
- );
1504
- const data = {entries: opt.jsonData, headers: headers};
3103
+ );
3104
+
3105
+ const data = {entries: opt.jsonData, headers};
1505
3106
  render(data);
1506
3107
  } else if (opt.jsonUrl) {
1507
3108
  getSheetValues(opt.jsonUrl);
@@ -1516,7 +3117,6 @@ const ponchoTableDependant = opt => {
1516
3117
 
1517
3118
  };
1518
3119
 
1519
-
1520
3120
  /**
1521
3121
  * POPOVER
1522
3122
  */
@@ -1562,16 +3162,21 @@ function pophidde(){
1562
3162
  */
1563
3163
  var ponchoUbicacion = function(options) {
1564
3164
  var urlProvincias = '/profiles/argentinagobar/themes/contrib/poncho/resources/jsons/geoprovincias.json';
3165
+ var urlMunicipios = '/profiles/argentinagobar/themes/contrib/poncho/resources/jsons/geomunicipios.json';
1565
3166
  var urlLocalidades = '/profiles/argentinagobar/themes/contrib/poncho/resources/jsons/geolocalidades.json';
1566
3167
  var provincias;
3168
+ var municipios;
1567
3169
  var localidades;
1568
3170
  var iProvincia = jQuery('input[name="submitted[' + options.provincia + ']"]');
3171
+ var iMunicipio = jQuery('input[name="submitted[' + options.municipio + ']"]');
1569
3172
  var iLocalidad = jQuery('input[name="submitted[' + options.localidad + ']"]');
1570
3173
  var sProvincia;
3174
+ var sMunicipios;
1571
3175
  var sLocalidades;
1572
3176
 
1573
3177
  function init() {
1574
3178
  urlProvincias = (options.urlProvincias ? options.urlProvincias : urlProvincias);
3179
+ urlMunicipios = (options.urlMunicipios ? options.urlMunicipios : urlMunicipios);
1575
3180
  urlLocalidades = (options.urlLocalidades ? options.urlLocalidades : urlLocalidades);
1576
3181
 
1577
3182
  jQuery.getJSON(urlProvincias, function(data) {
@@ -1582,6 +3187,14 @@ var ponchoUbicacion = function(options) {
1582
3187
  jQuery(sProvincia).select2();
1583
3188
  });
1584
3189
 
3190
+ jQuery.getJSON(urlMunicipios, function(data) {
3191
+ municipios = parseJsonMunicipios(data);
3192
+ sMunicipios = getSelectMunicipios(municipios, sProvincia.val());
3193
+ addMunEvent();
3194
+ iMunicipio.after(sMunicipios);
3195
+ jQuery(sMunicipios).select2();
3196
+ });
3197
+
1585
3198
  jQuery.getJSON(urlLocalidades, function(data) {
1586
3199
  localidades = parseJsonLocalidades(data);
1587
3200
  sLocalidades = getSelectLocalidades(localidades, sProvincia.val());
@@ -1590,6 +3203,7 @@ var ponchoUbicacion = function(options) {
1590
3203
  jQuery(sLocalidades).select2();
1591
3204
  });
1592
3205
  iProvincia.hide();
3206
+ iMunicipio.hide();
1593
3207
  iLocalidad.hide();
1594
3208
  }
1595
3209
 
@@ -1601,34 +3215,44 @@ var ponchoUbicacion = function(options) {
1601
3215
  */
1602
3216
  function parseJsonProvincias(data) {
1603
3217
  provincias = [];
1604
- data.results.forEach(function(provincia, index) {
3218
+ data.provincias.forEach(function(provincia, index) {
1605
3219
  provincias.push(provincia);
1606
3220
  });
1607
3221
  return provincias;
1608
3222
  }
1609
3223
 
1610
-
1611
3224
  /**
1612
- *
1613
- * @param {*} string
1614
- * @returns
1615
- */
1616
- function capitalizeFirstLetter(string) {
1617
- return string.charAt(0).toUpperCase() + string.slice(1);
3225
+ *
3226
+ * @param {*} data
3227
+ * @returns
3228
+ */
3229
+ function parseJsonMunicipios(data) {
3230
+ const groupedData = data.municipios.reduce((acc, current) => {
3231
+ const key = `${current.nombre_completo}`;
3232
+ current.label = key;
3233
+ if (!acc[key]) {
3234
+ acc[key] = current;
3235
+ }
3236
+ return acc;
3237
+ }, {});
3238
+ return Object.values(groupedData);
1618
3239
  }
1619
-
1620
-
3240
+
1621
3241
  /**
1622
3242
  *
1623
3243
  * @param {*} data
1624
3244
  * @returns
1625
3245
  */
1626
3246
  function parseJsonLocalidades(data) {
1627
- localidades = [];
1628
- data.results.forEach(function(localidad, index) {
1629
- localidades.push(localidad);
1630
- });
1631
- return localidades;
3247
+ const groupedData = data.localidades.reduce((acc, current) => {
3248
+ const key = `${current.departamento.nombre} - ${current.nombre}`;
3249
+ current.label = key;
3250
+ if (!acc[key]) {
3251
+ acc[key] = current;
3252
+ }
3253
+ return acc;
3254
+ }, {});
3255
+ return Object.values(groupedData);
1632
3256
  }
1633
3257
 
1634
3258
 
@@ -1638,18 +3262,39 @@ var ponchoUbicacion = function(options) {
1638
3262
  function addProvEvent() {
1639
3263
  sProvincia.on('change', function(e) {
1640
3264
  iProvincia.val('');
3265
+ iMunicipio.val('');
1641
3266
  iLocalidad.val('');
3267
+ sMunicipios.children('option:not(:first)').remove();
1642
3268
  sLocalidades.children('option:not(:first)').remove();
1643
3269
  if (sProvincia.val() != '') {
3270
+ iMunicipio.val(sMunicipios.find(":selected").text());
1644
3271
  iProvincia.val(sProvincia.find(":selected").text());
1645
- var sAux = getSelectLocalidades(localidades, sProvincia.val());
1646
- var sOpt = sAux.find('option');
1647
- sLocalidades.append(sOpt);
3272
+
3273
+ var sAuxM = getSelectMunicipios(municipios, sProvincia.val());
3274
+ var sOptM = sAuxM.find('option');
3275
+ sMunicipios.append(sOptM);
3276
+ sMunicipios.val('');
3277
+
3278
+ var sAuxL = getSelectLocalidades(localidades, sProvincia.val());
3279
+ var sOptL = sAuxL.find('option');
3280
+ sLocalidades.append(sOptL);
1648
3281
  sLocalidades.val('');
3282
+
1649
3283
  }
1650
3284
  });
1651
3285
  }
1652
3286
 
3287
+ /**
3288
+ *
3289
+ */
3290
+ function addMunEvent() {
3291
+ sMunicipios.on('change', function(e) {
3292
+ iMunicipio.val('');
3293
+ if (sMunicipios.val() != '') {
3294
+ iMunicipio.val(sMunicipios.find(":selected").text());
3295
+ }
3296
+ });
3297
+ }
1653
3298
 
1654
3299
  /**
1655
3300
  *
@@ -1689,12 +3334,11 @@ var ponchoUbicacion = function(options) {
1689
3334
  jQuery.each(optionList, function(i, el) {
1690
3335
  let selected = '';
1691
3336
  if (selected_item == el.nombre) {
1692
- selected = 'selected="selected"';
3337
+ selected = ' selected="selected"';
1693
3338
  }
3339
+ const label = (el.label ? el.label : el.nombre);
1694
3340
  combo.append(
1695
- "<option value='" + el.id + "' " + selected + ">" +
1696
- el.nombre +
1697
- "</option>"
3341
+ `<option value="${el.id}"${selected}>${label}</option>`
1698
3342
  );
1699
3343
  });
1700
3344
  return combo;
@@ -1722,6 +3366,42 @@ var ponchoUbicacion = function(options) {
1722
3366
  return select;
1723
3367
  }
1724
3368
 
3369
+ /**
3370
+ *
3371
+ * @param {*} municipios
3372
+ * @param {*} provincia
3373
+ * @returns
3374
+ */
3375
+ function getSelectMunicipios(municipios, provincia) {
3376
+ var muniSelect = {};
3377
+ var required = iMunicipio.prop('required');
3378
+ var select = null;
3379
+
3380
+ if (iProvincia.val()) {
3381
+ muniSelect = municipios
3382
+ .filter(function(municipio) {
3383
+ return String(municipio.provincia.id) == String(provincia);
3384
+ })
3385
+ .sort(function(a, b) {
3386
+ var nameA = a.label.toUpperCase();
3387
+ var nameB = b.label.toUpperCase();
3388
+ return nameA.localeCompare(nameB);
3389
+ });
3390
+ emptyOption = false;
3391
+ select = getDropDownList(
3392
+ 'sMunicipios', 'sMunicipios',
3393
+ muniSelect, required, emptyOption, iMunicipio.val()
3394
+ );
3395
+ }else {
3396
+ select = getDropDownList(
3397
+ 'sMunicipios', 'sMunicipios',
3398
+ [], required, true, false
3399
+ );
3400
+ }
3401
+
3402
+ return select;
3403
+ }
3404
+
1725
3405
 
1726
3406
  /**
1727
3407
  *
@@ -1739,17 +3419,9 @@ var ponchoUbicacion = function(options) {
1739
3419
  .filter(function(localidad) {
1740
3420
  return String(localidad.provincia.id) == String(provincia);
1741
3421
  })
1742
- .map(function(a) {
1743
- if (a.departamento.nombre) {
1744
- a.nombre = capitalizeFirstLetter(
1745
- a.departamento.nombre.toLowerCase()) + ' - ' +
1746
- capitalizeFirstLetter(a.nombre.toLowerCase());
1747
- }
1748
- return a;
1749
- })
1750
3422
  .sort(function(a, b) {
1751
- var nameA = a.nombre.toUpperCase();
1752
- var nameB = b.nombre.toUpperCase();
3423
+ var nameA = a.label.toUpperCase();
3424
+ var nameB = b.label.toUpperCase();
1753
3425
  return nameA.localeCompare(nameB);
1754
3426
  });
1755
3427
 
@@ -2456,17 +4128,24 @@ function ponchoChart(opt) {
2456
4128
  jQuery.each(listado, function(row, value) {
2457
4129
  if (row == 0) { //construyo arrays para los dataset, recupero colores y labels
2458
4130
  jQuery.each(filteredTitlePos, function(index, title) {
2459
- var split = listado[row][filteredTitlePos[index]].split("-");
2460
- var pos = split[0] + split[1];
4131
+ const regex = /(?<axis>eje-(x|y(?:[1-9]|[1-9][0-9])))-(?<color>[\w-]*?)(?:-(?<type>linea|barra))?$/;
4132
+ const result = regex.exec(listado[row][filteredTitlePos[index]]);
4133
+ if(!result){
4134
+ return;
4135
+ }
4136
+
4137
+ const graphType = result.groups.type;
4138
+ const pos = result.groups.axis.replace('-', '');
4139
+
2461
4140
  valores[pos] = []; //construyo los array para los dataset
2462
- colores.push(split[2]); //recupero colores
4141
+ colores.push( result.groups.color ); //recupero colores
2463
4142
 
2464
4143
  if (tipoGrafico == "mixed") {
2465
- if (split.length > 3){ //ingresaron un tipo de grafico
4144
+ if (graphType){ //ingresaron un tipo de grafico
2466
4145
  //verifico que sea un tipo de grafico valido
2467
- if (split[3] == "barra" || split[3] == "linea") {
4146
+ if (graphType == "barra" || graphType == "linea") {
2468
4147
  //recupero tipo de grafico para cada dataset
2469
- tipoGraficosMixed.push(split[3]);
4148
+ tipoGraficosMixed.push(graphType);
2470
4149
  } else { //seteo graficos por defecto
2471
4150
  if (index == 0) {
2472
4151
  //por defecto seteo barra
@@ -2488,10 +4167,10 @@ function ponchoChart(opt) {
2488
4167
  }
2489
4168
  }
2490
4169
  }
2491
-
2492
4170
  });
2493
4171
  }
2494
4172
 
4173
+
2495
4174
  if (row == 1) {
2496
4175
  jQuery.each(filteredTitlePos, function(index, title) {
2497
4176
  if (tipoGrafico != "pie") {
@@ -2747,9 +4426,10 @@ function ponchoChart(opt) {
2747
4426
  if (tipoGrafico == "pie") {
2748
4427
 
2749
4428
  colores.forEach(function(valor, indice, array) {
4429
+ console.log(valor)
2750
4430
  codigosColores.push(ponchoColor(valor));
2751
4431
  });
2752
-
4432
+
2753
4433
  graficoTorta(
2754
4434
  etiquetas, datos, tipoGrafico, codigosColores,
2755
4435
  opt.idComponenteGrafico, posicionLeyendas, toltips,
@@ -3026,6 +4706,14 @@ function ponchoChart(opt) {
3026
4706
  */
3027
4707
  const gapi_legacy = (response) => {
3028
4708
 
4709
+ if (!response || !response.values || response.values.length === 0) {
4710
+ throw new TypeError("Invalid response format");
4711
+ }
4712
+
4713
+ if (!Array.isArray(response.values) || !Array.isArray(response.values[0])) {
4714
+ throw new TypeError("Invalid response format: values should be arrays");
4715
+ }
4716
+
3029
4717
  const keys = response.values[0];
3030
4718
  const regex = / |\/|_/ig;
3031
4719
  let entry = [];
@@ -3045,7 +4733,9 @@ const gapi_legacy = (response) => {
3045
4733
  };
3046
4734
 
3047
4735
 
3048
- /* module.exports REMOVED */
4736
+ if (typeof exports !== "undefined") {
4737
+ module.exports = gapi_legacy;
4738
+ }
3049
4739
 
3050
4740
  /**
3051
4741
  * PONCHO MAP
@@ -3279,17 +4969,20 @@ class PonchoMap {
3279
4969
  ...this.map_init_options
3280
4970
  }
3281
4971
  ).setView(this.map_view, this.map_zoom);
3282
- this.titleLayer = new L.tileLayer("https://mapa-ign.argentina.gob.ar/osm/{z}/{x}/{-y}.png",
3283
- {
3284
- attribution: ("Contribuidores: "
3285
- + "<a href=\"https://www.ign.gob.ar/AreaServicios/Argenmap/Introduccion\" "
3286
- + "target=\"_blank\">"
3287
- + "Instituto Geográfico Nacional</a>, "
3288
- + "<a href=\"https://www.openstreetmap.org/copyright\" "
3289
- + "target=\"_blank\">"
3290
- + "OpenStreetMap</a>")
3291
- });
3292
- this.markers = new L.markerClusterGroup(this.marker_cluster_options);
4972
+ this.titleLayer = new L.tileLayer(
4973
+ "https://mapa-ign.argentina.gob.ar/osm/{z}/{x}/{-y}.png",
4974
+ {
4975
+ attribution: ("Contribuidores: "
4976
+ + "<a href=\"https://www.ign.gob.ar/AreaServicios/Argenmap/Introduccion\" "
4977
+ + "target=\"_blank\">"
4978
+ + "Instituto Geográfico Nacional</a>, "
4979
+ + "<a href=\"https://www.openstreetmap.org/copyright\" "
4980
+ + "target=\"_blank\">"
4981
+ + "OpenStreetMap</a>")
4982
+ });
4983
+ if(L.hasOwnProperty("markerClusterGroup")){
4984
+ this.markers = new L.markerClusterGroup(this.marker_cluster_options);
4985
+ }
3293
4986
  this.ponchoLoaderTimeout;
3294
4987
  }
3295
4988
 
@@ -3521,6 +5214,15 @@ class PonchoMap {
3521
5214
  }
3522
5215
 
3523
5216
 
5217
+ /**
5218
+ * Alias de sluglify
5219
+ *
5220
+ * @param {string} val Texto a formatear
5221
+ * @returns {string}
5222
+ */
5223
+ _slugify = val => slugify(val);
5224
+
5225
+
3524
5226
  /**
3525
5227
  * Es un geoJSON
3526
5228
  *
@@ -3703,6 +5405,42 @@ class PonchoMap {
3703
5405
  };
3704
5406
 
3705
5407
 
5408
+ /**
5409
+ * El indice id_mixing ¿Está siendo usado?
5410
+ * @returns {boolean}
5411
+ */
5412
+ _isIdMixing = () => (Array.isArray(this.id_mixing) &&
5413
+ this.id_mixing > 0 || typeof this.id_mixing === 'function');
5414
+
5415
+
5416
+ /**
5417
+ * Array con valores a concatenar en el id.
5418
+ *
5419
+ * @summary Dependiendo de la opción que haya elegido el usario, retorna
5420
+ * una array de valors pasado por funcion o _array object_.
5421
+ * @param {object} entry Objeto con una entrada del geoJson
5422
+ * @returns {object} Array con los valores a concatenar.
5423
+ */
5424
+ _idMixing = entry => {
5425
+ if(!this._isIdMixing()){
5426
+ return;
5427
+ }
5428
+
5429
+ if(typeof this.id_mixing === "function"){
5430
+ return this.id_mixing(this, entry).join('');
5431
+ }
5432
+
5433
+ const values = this.id_mixing.map(val => {
5434
+ if(entry.properties[val]){
5435
+ return entry.properties[val].toString();
5436
+ }
5437
+ return val;
5438
+ });
5439
+
5440
+ return this._slugify(values.join("-"));
5441
+ }
5442
+
5443
+
3706
5444
  /**
3707
5445
  * Crea una entrada ID autonumerada si no posee una.
3708
5446
  *
@@ -3715,33 +5453,29 @@ class PonchoMap {
3715
5453
  */
3716
5454
  _setIdIfNotExists = (entries) => {
3717
5455
  const hasId = entries.features
3718
- .filter((_,k) => k===0)
3719
- .every(e => e.properties.hasOwnProperty("id"));
3720
-
3721
- if(!hasId){
3722
- const newEntries = entries.features.map(
3723
- (v,k) => {
3724
-
3725
- if(this.id_mixing.length > 0){
3726
- const values = this.id_mixing.map(val => {
3727
- if(v.properties[val]){
3728
- return slugify(v.properties[val]);
3729
- }
3730
- return slugify(val);
3731
- });
3732
- v.properties.id = values.join("-");
3733
- } else {
3734
- const autoId = k + 1;
3735
- const useTitle = (this.title && v.properties[this.title] ?
3736
- slugify(v.properties[this.title]) : "");
3737
- v.properties.id = `${autoId}-${useTitle}`;
3738
- }
3739
-
3740
- return v;
3741
- });
3742
- entries.features = newEntries;
3743
- }
5456
+ .filter((_, k) => k === 0)
5457
+ .every(e => e.properties.hasOwnProperty("id"));
3744
5458
 
5459
+ // Si no se configuró id_mixing y el json tiene id.
5460
+ if(!this._isIdMixing() && hasId){
5461
+ return entries;
5462
+ }
5463
+
5464
+ const newEntries = entries.features.map((entry, k) => {
5465
+ if(this._isIdMixing()){
5466
+ // Procesa la opción de id_mixing
5467
+ entry.properties.id = this._idMixing(entry);
5468
+ } else {
5469
+ // Genera un ID automático
5470
+ const autoId = k + 1;
5471
+ const useTitle = (this.title && entry.properties[this.title] ?
5472
+ this._slugify(entry.properties[this.title]) : "");
5473
+ entry.properties.id = [autoId, useTitle].filter(f=>f).join('-');
5474
+ }
5475
+
5476
+ return entry;
5477
+ });
5478
+ entries.features = newEntries;
3745
5479
  return entries;
3746
5480
  };
3747
5481
 
@@ -3753,9 +5487,16 @@ class PonchoMap {
3753
5487
  * @return {undefined}
3754
5488
  */
3755
5489
  addHash = (value) => {
3756
- if(!this.hash || this.no_info){
3757
- return null;
5490
+
5491
+ if (typeof value !== "string" && !value) {
5492
+ console.error('Invalid value provided to update hash');
5493
+ return;
3758
5494
  }
5495
+
5496
+ if (!this.hash || this.no_info) {
5497
+ return;
5498
+ }
5499
+
3759
5500
  window.location.hash = `#${value}`;
3760
5501
  };
3761
5502
 
@@ -3785,44 +5526,38 @@ class PonchoMap {
3785
5526
  */
3786
5527
  searchEntries = (term, dataset) => {
3787
5528
  dataset = (typeof dataset === "undefined" ? this.geoJSON: dataset);
3788
- if(!term){
5529
+ if(typeof term !== "string" || term.trim().length === 0){
3789
5530
  return dataset;
3790
5531
  }
3791
- const entries = dataset.filter(e => {
3792
- if(this.searchEntry(term, e.properties)){
3793
- return e;
3794
- };
5532
+ const entries = dataset.filter(entry => {
5533
+ return (this.searchEntry(term, entry.properties));
3795
5534
  })
3796
5535
  return entries;
3797
5536
  };
3798
5537
 
3799
-
5538
+
3800
5539
  /**
3801
5540
  * Busca un término en cada uno de los indices de una entrada.
3802
5541
  */
3803
- searchEntry = (search_term, data) => {
3804
- const search_for = [
5542
+ searchEntry = (searchTerm, data) => {
5543
+ const searchFor = [
3805
5544
  ...new Set([...[this.title], ...this.search_fields])
3806
5545
  ].filter(e => e);
3807
5546
 
3808
- for(const item of search_for){
3809
- if(!data.hasOwnProperty(item)){
3810
- continue;
3811
- }
3812
- const term = replaceSpecialChars(search_term)
3813
- .toUpperCase();
3814
- const field = replaceSpecialChars(data[item])
5547
+ const term = replaceSpecialChars(searchTerm).toUpperCase();
5548
+ const result = searchFor.some(function(key){
5549
+ const field = replaceSpecialChars(data[key])
3815
5550
  .toString()
3816
5551
  .toUpperCase();
5552
+
3817
5553
  try {
3818
- if(field.includes(term)){
3819
- return data;
3820
- }
5554
+ return (field.includes(term));
3821
5555
  } catch (error) {
3822
5556
  console.error(error);
3823
5557
  }
3824
- }
3825
- return null;
5558
+ });
5559
+
5560
+ return (result ? data : null);
3826
5561
  };
3827
5562
 
3828
5563
 
@@ -4270,6 +6005,10 @@ class PonchoMap {
4270
6005
  * Setea los markers para ejecutarse en un evento onlick
4271
6006
  */
4272
6007
  _urlHash = () => {
6008
+ if(!this.hash){
6009
+ return;
6010
+ }
6011
+
4273
6012
  const setHash = (layer) => {
4274
6013
  layer.on("click", () => {
4275
6014
  this.addHash(layer.options.id);
@@ -4499,6 +6238,10 @@ class PonchoMap {
4499
6238
  key = false, css = "small", style = false
4500
6239
  } = this.template_structure.lead;
4501
6240
 
6241
+ if(!entry[key].trim()){
6242
+ return;
6243
+ }
6244
+
4502
6245
  const p = document.createElement("p");
4503
6246
  p.textContent = entry[key];
4504
6247
  // Style definitions
@@ -4763,6 +6506,7 @@ class PonchoMap {
4763
6506
  properties[_this.title], _this.tooltip_options
4764
6507
  );
4765
6508
  }
6509
+
4766
6510
  // Si el usuario desea utilizar popUp en vez de slider.
4767
6511
  if(!_this.no_info && !_this.slider){
4768
6512
  const html = (typeof _this.template == "function" ?
@@ -5108,9 +6852,7 @@ class PonchoMap {
5108
6852
  this._clickToggleSlider();
5109
6853
  }
5110
6854
 
5111
- if(this.hash){
5112
- this._urlHash();
5113
- }
6855
+ this._urlHash();
5114
6856
 
5115
6857
  if(this.scroll && this.hasHash()){
5116
6858
  this.scrollCenter();
@@ -5135,11 +6877,16 @@ class PonchoMapLoader {
5135
6877
 
5136
6878
  constructor(options){
5137
6879
  const defaults = {
6880
+ selector: "",
5138
6881
  scope: "",
5139
- timeout: 50000
6882
+ timeout: 50000,
6883
+ cover_opacity: 1,
6884
+ cover_style: {},
5140
6885
  };
5141
6886
  let opts = Object.assign({}, defaults, options);
5142
6887
  this.scope = opts.scope;
6888
+ this.cover_opacity = opts.cover_opacity;
6889
+ this.cover_style = opts.cover_style;
5143
6890
  this.timeout = opts.timeout;
5144
6891
  this.scope_sufix = `--${this.scope}`;
5145
6892
  this.scope_selector = `[data-scope="${this.scope}"]`;
@@ -5174,6 +6921,11 @@ class PonchoMapLoader {
5174
6921
  cover.classList.add(
5175
6922
  "poncho-map__loader", `js-poncho-map__loader${this.scope_sufix}`
5176
6923
  );
6924
+ // Background opacity
6925
+ Object.assign(cover.style, this.cover_style);
6926
+ if(this.cover_opacity){
6927
+ cover.style.backgroundColor = `color-mix(in srgb, transparent, var(--pm-loader-background) ${this.cover_opacity.toString() * 100}%)`;
6928
+ }
5177
6929
  cover.appendChild(loader);
5178
6930
  element.appendChild(cover);
5179
6931
  this.ponchoLoaderTimeout = setTimeout(this.remove, this.timeout);
@@ -5952,14 +7704,13 @@ class PonchoMapFilter extends PonchoMap {
5952
7704
  */
5953
7705
  _validateEntry = (entry, form_filters) => {
5954
7706
  const fields_group = (group) => form_filters.filter(e => e[0] == group);
5955
- // Reviso cuantos grupos tengo que validar.
5956
7707
  const total_groups = this.filters.length;
5957
- let validations = [];
5958
- for(let i = 0; i < total_groups; i++){
5959
- // por cada grupo de fields obtengo un resultado de grupo.
5960
- validations.push(this._validateGroup(entry, fields_group(i)));
5961
- }
5962
- return validations.every(e => e);
7708
+
7709
+ const validations = Array.from( {length: total_groups}, (_, i) => {
7710
+ return this._validateGroup(entry, fields_group(i));
7711
+ }).reduce((acc, val) => acc && val, true);
7712
+
7713
+ return validations;
5963
7714
  };
5964
7715
 
5965
7716
 
@@ -6032,10 +7783,7 @@ class PonchoMapFilter extends PonchoMap {
6032
7783
  this._clickToggleSlider();
6033
7784
  }
6034
7785
 
6035
- if(this.hash){
6036
- this._urlHash();
6037
- }
6038
-
7786
+ this._urlHash();
6039
7787
  this._setFetureAttributes();
6040
7788
  this._accesibleMenu();
6041
7789
  };
@@ -6450,7 +8198,6 @@ const PONCHOMAP_GEOJSON_PROVINCES = "/profiles/argentinagobar/"
6450
8198
  + "themes/contrib/poncho/resources/jsons/"
6451
8199
  + "geo-provincias-argentinas.json";
6452
8200
 
6453
-
6454
8201
  /**
6455
8202
  * Junta el geoJSON con el JSON de Google Sheet
6456
8203
  *
@@ -6500,14 +8247,28 @@ const ponchoMapProvinceMergeData = (geoProvinces={}, entries={},
6500
8247
  /**
6501
8248
  * Remueve estilos toggle del select y el contenedor del mapa
6502
8249
  *
6503
- * @summary Este objeto no puede estar dentro de la clase porque no se puede
8250
+ * @summary
8251
+ * Cuando la opción sea verdadera (true en inglés), y el viewport o
8252
+ * tamaño del display, sea inferior a los 992 píxeles de ancho;
8253
+ * el componente html, select, con el listado de provincias se mostrará,
8254
+ * mientras que el mapa permanecerá oculto.
8255
+ *
8256
+ * Cuando la opción sea falsa (false en inglés), tanto el componente
8257
+ * html, select, como el mapa estarán visibles en todo momento.
8258
+ *
8259
+ * @todo Este objeto no puede estar dentro de la clase porque no se puede
6504
8260
  * utiliar `this` antes de `super()` en ES6.
6505
8261
  * @returns {undefined}
6506
8262
  */
6507
8263
  const ponchoMapProvinceCssStyles = flag => {
8264
+ if(typeof flag !== "boolean"){
8265
+ return
8266
+ }
8267
+
6508
8268
  if(flag){
6509
8269
  return;
6510
8270
  }
8271
+
6511
8272
  const s = document.querySelectorAll(
6512
8273
  ".poncho-map-province__toggle-map,"
6513
8274
  + ".poncho-map-province__toggle-element"
@@ -6535,7 +8296,8 @@ class PonchoMapProvinces extends PonchoMapFilter {
6535
8296
  overlay_image_opacity: 0.8,
6536
8297
  overlay_image_url: "https://www.argentina.gob.ar/"
6537
8298
  + "sites/default/files/map-shadow.png",
6538
- hide_select: true,
8299
+ hide_select: false,
8300
+ toggle_select: true,
6539
8301
  province_index: "provincia",
6540
8302
  fit_bounds: true,
6541
8303
  // Sobreescribo opciones de PonchoMap
@@ -6561,8 +8323,8 @@ class PonchoMapProvinces extends PonchoMapFilter {
6561
8323
  };
6562
8324
  // Merge options
6563
8325
  let opts = Object.assign({}, defaultOptions, options);
6564
-
6565
- ponchoMapProvinceCssStyles(opts.hide_select);
8326
+ console.log(opts)
8327
+ ponchoMapProvinceCssStyles(opts.toggle_select);
6566
8328
 
6567
8329
  // PonchoMapFilter instance
6568
8330
  const mergedJSONs = ponchoMapProvinceMergeData(
@@ -6578,8 +8340,10 @@ class PonchoMapProvinces extends PonchoMapFilter {
6578
8340
  this.overlayImageBounds = opts.overlay_image_bounds;
6579
8341
  this.overlayImageOpacity = opts.overlay_image_opacity;
6580
8342
  this.mapView = opts.map_view;
8343
+ this.toggleSelect = opts.toggle_select;
6581
8344
  this.hideSelect = opts.hide_select;
6582
8345
  this.fitToBounds = opts.fit_bounds
8346
+
6583
8347
  }
6584
8348
 
6585
8349
 
@@ -6602,6 +8366,24 @@ class PonchoMapProvinces extends PonchoMapFilter {
6602
8366
  });
6603
8367
 
6604
8368
 
8369
+ /**
8370
+ * Oculta el select
8371
+ * @param {*} status
8372
+ * @returns
8373
+ */
8374
+ hideSelectProvinces = status => {
8375
+ if(typeof status != "boolean"){
8376
+ return;
8377
+ }
8378
+
8379
+ const selector = `[data-scope-related="${this.scope}"]`;
8380
+ const obj = document.querySelectorAll(selector);
8381
+ obj.forEach(element => {
8382
+ element.style.display = (this.hideSelect ? "none" : "");
8383
+ });
8384
+ }
8385
+
8386
+
6605
8387
  /**
6606
8388
  * Retorna un valor aleatório.
6607
8389
  * @param {object} list Listado de provincias
@@ -6667,7 +8449,7 @@ class PonchoMapProvinces extends PonchoMapFilter {
6667
8449
 
6668
8450
  // Creo los options
6669
8451
  const selectProvinces = document.getElementById("id_provincia");
6670
- const optionsSelect = [["", "Seleccione una provincia"], ...prov];
8452
+ const optionsSelect = [["", "Elegí una provincia"], ...prov];
6671
8453
  optionsSelect.forEach(province => {
6672
8454
  const option = document.createElement("option");
6673
8455
 
@@ -6728,6 +8510,17 @@ class PonchoMapProvinces extends PonchoMapFilter {
6728
8510
  if(!this.overlayImage){
6729
8511
  return;
6730
8512
  }
8513
+ console.log(this.overlayImageUrl)
8514
+ if(typeof this.overlayImageUrl !== "string"){
8515
+ console.error("Hubo un problema con la ruta o nombre de la imagen");
8516
+ return;
8517
+ }
8518
+
8519
+ if(typeof this.overlayImageOpacity !== "number"){
8520
+ console.error("El valor de la opacidad debe ser un número.");
8521
+ return;
8522
+ }
8523
+
6731
8524
  L.imageOverlay(
6732
8525
  this.overlayImageUrl, this.overlayImageBounds,
6733
8526
  {opacity: this.overlayImageOpacity}
@@ -6739,7 +8532,9 @@ class PonchoMapProvinces extends PonchoMapFilter {
6739
8532
  * imprime el mapa
6740
8533
  */
6741
8534
  renderProvinceMap = () =>{
8535
+ this.hideSelectProvinces(this.hideSelect);
6742
8536
  this._overlayImage();
8537
+
6743
8538
  this.render(); // Imprime PonchoMapsFilter
6744
8539
  if(this.fitToBounds){
6745
8540
  this.fitBounds();
@@ -6857,7 +8652,9 @@ class GapiSheetData {
6857
8652
 
6858
8653
 
6859
8654
 
6860
- /* module.exports REMOVED */
8655
+ if (typeof exports !== "undefined") {
8656
+ module.exports = GapiSheetData;
8657
+ }
6861
8658
 
6862
8659
  /**
6863
8660
  * TRANSLATE