npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

og-chaos

v0.0.5

Published

Algoritmo que analiza los incidents de un partido de fútbol y calcula el **marcador limpio** — el resultado que habría existido sin goles caóticos — junto con una serie de indicadores sobre el impacto del caos en el partido.

Readme

analyzeMatch

Algoritmo que analiza los incidents de un partido de fútbol y calcula el marcador limpio — el resultado que habría existido sin goles caóticos — junto con una serie de indicadores sobre el impacto del caos en el partido.

Instalación

const { analyzeMatch } = require('./analyzeMatch.js');

Uso

const { analyzeMatch } = require('./analyzeMatch.js');
const data = require('./incidentes.json');

const result = analyzeMatch(data);
console.log(result);

Definiciones

Gol limpio

Un gol que cumple ambas condiciones:

incidentType === "goal"
incidentClass === "regular"

Gol no limpio

Cualquier gol que no sea incidentClass: "regular":

| incidentClass | Descripción | |---|---| | penalty | Gol de penal | | ownGoal | Autogol |

Regla del autogol

isHome en un ownGoal indica quién lo cometió, y el gol cuenta para el equipo contrario:

| isHome | Lo cometió | Cuenta para | |---|---|---| | false | Local | Visitante | | true | Visitante | Local |


Respuesta

{
  "realScore": {
    "home": 2,
    "away": 2,
    "result": "draw"
  },
  "cleanScore": {
    "home": 1,
    "away": 0,
    "result": "home"
  },
  "resultChanged": true,
  "chaosIndex": 75,
  "dirtyGoalsCount": {
    "total": 3,
    "benefitsHome": 2,
    "benefitsAway": 1
  },
  "mostBenefited": "away",
  "dirtyGoals": [...],
  "cleanGoals": [...],
  "penaltiesFromCards": {...}
}

Campos

realScore

Marcador final del partido, leído del periodo FT. Si no existe, se toma del último gol ordenado cronológicamente.

| Campo | Tipo | Descripción | |---|---|---| | home | number | Goles del local | | away | number | Goles del visitante | | result | string | "home" | "away" | "draw" |


cleanScore

Marcador que habría existido contando solo goles limpios (incidentClass: "regular").

| Campo | Tipo | Descripción | |---|---|---| | home | number | Goles limpios del local | | away | number | Goles limpios del visitante | | result | string | "home" | "away" | "draw" |


resultChanged

boolean — indica si el marcador limpio habría producido un resultado diferente al real.

realScore:  2-2 draw
cleanScore: 1-0 home
resultChanged: true  ✓ el caos cambió el ganador

chaosIndex

Porcentaje de goles no limpios sobre el total de goles del partido.

3 goles no limpios / 4 totales = 75%

| Rango | Interpretación | |---|---| | 0% | Partido sin caos | | 1–33% | Caos bajo | | 34–66% | Caos moderado | | 67–100% | Partido muy caótico |


dirtyGoalsCount

Conteo de goles no limpios por equipo beneficiado (no por quién los cometió).

| Campo | Tipo | Descripción | |---|---|---| | total | number | Total de goles no limpios | | benefitsHome | number | Goles no limpios que sumaron al local | | benefitsAway | number | Goles no limpios que sumaron al visitante |


mostBenefited

Equipo que más mejoró su situación gracias al caos, comparando el marcador limpio (escenario base) con el marcador real.

Se calcula como la diferencia de goles aportados por el caos a cada equipo:

chaosGainHome = realHome - cleanHome  →  2 - 1 = +1
chaosGainAway = realAway - cleanAway  →  2 - 0 = +2

mostBenefited: "away"  ← el visitante ganó 2 goles del caos vs 1 del local

| Valor | Descripción | |---|---| | "home" | El local se benefició más | | "away" | El visitante se benefició más | | "both" | Ambos se beneficiaron por igual | | "none" | Sin goles no limpios |


dirtyGoals

Array con el detalle de cada gol no limpio, ordenado cronológicamente.

{
  "minute": 61,
  "addedTime": null,
  "player": "Bruno Fernandes",
  "type": "penalty",
  "committedBy": "away",
  "benefitsTeam": "away",
  "score": { "home": 0, "away": 1 }
}

| Campo | Tipo | Descripción | |---|---|---| | minute | number | Minuto del gol | | addedTime | number \| null | Tiempo añadido, si aplica | | player | string \| null | Jugador que lo ejecutó o cometió | | type | string | "penalty" | "ownGoal" | | committedBy | string | Equipo que lo ejecutó/cometió ("home" | "away") | | benefitsTeam | string | Equipo que recibió el gol ("home" | "away") | | score | object | Marcador tras el gol |

En un ownGoal, committedBy y benefitsTeam son siempre equipos opuestos.


cleanGoals

Array con el detalle de cada gol limpio (incidentClass: "regular"), ordenado cronológicamente.

{
  "minute": 67,
  "addedTime": null,
  "player": "Ryan Christie",
  "team": "home",
  "score": { "home": 1, "away": 1 }
}

| Campo | Tipo | Descripción | |---|---|---| | minute | number | Minuto del gol | | addedTime | number \| null | Tiempo añadido, si aplica | | player | string \| null | Jugador que anotó | | team | string | Equipo que anotó ("home" | "away") | | score | object | Marcador tras el gol |


penaltiesFromCards

Indicador que detecta penales convertidos que fueron precedidos por una tarjeta del equipo contrario dentro de una ventana de 5 minutos.

Reglas:

  • Solo penales convertidos (incidentType: "goal" + incidentClass: "penalty")
  • La tarjeta debe ser del equipo contrario al ejecutor del penal
  • Ventana de tiempo: entre minuto_penal - 5 y minuto_penal
  • Tipos de tarjeta válidos: red, yellow, yellowRed
{
  "total": 2,
  "triggeredByCard": 2,
  "detail": [
    {
      "minute": 81,
      "addedTime": null,
      "player": "Eli Junior Kroupi",
      "executedBy": "home",
      "benefitsTeam": "home",
      "score": { "home": 2, "away": 2 },
      "triggeredByCard": {
        "minute": 78,
        "addedTime": null,
        "player": "Harry Maguire",
        "cardType": "red",
        "reason": "Professional foul last man",
        "sanctionedTeam": "away"
      }
    },
    {
      "minute": 61,
      "addedTime": null,
      "player": "Bruno Fernandes",
      "executedBy": "away",
      "benefitsTeam": "away",
      "score": { "home": 0, "away": 1 },
      "triggeredByCard": {
        "minute": 59,
        "addedTime": null,
        "player": "Álex Jiménez",
        "cardType": "yellow",
        "reason": "Foul",
        "sanctionedTeam": "home"
      }
    }
  ]
}

| Campo | Tipo | Descripción | |---|---|---| | total | number | Total de penales convertidos en el partido | | triggeredByCard | number | Penales con tarjeta previa detectada | | detail | array | Detalle de cada penal | | detail[].triggeredByCard | object \| null | Tarjeta vinculada, o null si no hubo | | detail[].triggeredByCard.cardType | string | "red" | "yellow" | "yellowRed" | | detail[].triggeredByCard.reason | string \| null | Motivo de la tarjeta | | detail[].triggeredByCard.sanctionedTeam | string | Equipo sancionado ("home" | "away") |