# Project export: AI Health Mini-Programs

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: There are so many things that have yet to be addressed by AI machine learning models. This set of two programs aims to address issues related to healthcare and fitness.
- Devpost: https://devpost.com/software/ai-health-mini-programs
- GitHub: https://github.com/LizzyC-115/AI-Mini-Programs
- Demo: https://teachablemachine.withgoogle.com/models/BA4tc9Mbl/
- Team: 1 GitHub contributor(s) — LizzyC-115 (1 commits)

## Devpost submission (written by the team)

### Inspiration

We were inspired by the issues related to coughing especially with regards to sickness.

### What it does

We have two programs, one that analyzes sounds to determine types of coughing/wheezing. The other uses an AI to detect movement, which acts as a controller to a maze game.

### How we built it

We utilized HTML, CSS, and Javascript to create these two programs.

### Challenges we ran into

We had some trouble finalizing our ideas and researching methods to accomplish our ideas.

### Accomplishments we're proud of

The system appears to work to a certain extent.

### What we learned

We learned about the design process and how it is both iterative and useful. We also learned more about making machine learning models.

### What's next

The goal is to be able to better develop the system so it can more seamlessly function. Then, for the maze idea, we hope to be able to apply it into VR headset systems. For the cough project, we hope to consult medical specialists to see how it can be improved and initially applied in scale.

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 3 recognized source files, 26 KB.
- CSS (language) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (5 of 5)

```
index2.html
my-pose-model (2)/metadata.json
my-pose-model (2)/model.json
script.js
style.css
```

### Dependencies

No dependency index available.

### Recent commits (newest first)

- Add files via upload

## Key source files (fetched from GitHub, selected and truncated for size)

### index2.html

```html
<html>
    <head>
        <script src="script.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@teachablemachine/pose@0.8/dist/teachablemachine-pose.min.js"></script>
        
    </head>
    <body>
        <div>WebCam Controller</div>
        <button type="button" onclick="init()">Start</button>
        <div><canvas id="canvas"></canvas></div>
        <div id="label-container"></div>
        <br><br><br><br>
        <!--<iframe src="index.html" width="1000" height="1000">Maze Game</iframe>-->
        
        
        <div id="page">
            <div id="Message-Container">
              <div id="message">
                <h1>Congratulations!</h1>
                <p>You've reached the end!</p>
                <p id="moves"></p>
                <input id="okBtn" type="button" onclick="toggleVisablity('Message-Container')" value="Cool!" />
              </div>
            </div>
            <br>
        
            <div id="menu">
              <div class="custom-select">
                <select id="diffSelect">
                          <option value="10">Easy</option>
                          <option value="15">Medium</option>
                          <option value="25">Hard</option>
                          <option value="38">Extreme</option>                                      
                      </select>
              </div>
              <input id="startMazeBtn" type="button" onclick="makeMaze()" value="Start" />
            </div>
            <br>
            <div id="view">
              <div id="mazeContainer">
                <canvas id="mazeCanvas" class="border" height="1100" width="1100"></canvas>
              </div>
            </div>
            <br>
            <br>
            <p id="instructions">Please start the webcam controller before beginning!</p>
        
          </div>
        
          <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
          <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.touchswipe/1.6.18/jquery.touchSwipe.min.js"></script>
    </body>
</html>

```

### style.css

```css
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');

html, body {
    width: 75vw;
    height: 100vh;
    position: fixed;
    padding: 0;
    margin: auto;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #fff;
    font-family: 'Poppins', sans-serif;
}

#view {
    margin-top: 30px;
}

#mazeContainer {
    top: 100px;
    opacity: 0;
    display: inline-block;
    margin: auto;
    border-radius: 10px;
}
#mazeContainer #mazeCanvas {
    margin: 0;
    display: block;
    border: solid 2px black;
    height: 400px;
}
input, select {
    cursor: pointer;
    background-color: rgba(0, 0, 0, 0.30);
    height: 45px;
    width: 150px;
    padding: 10px;
    border: none;
    border-radius: 5px;
    color: white;
    display: inline-block;
    font-size: 15px;
    text-align: center;
    text-decoration: none;
    appearance: none;
}
input:hover, select:hover {
	background-color: rgba(0, 0, 0, 0.70);
}
input:active, select:active {
	background-color: black;
}
input:focus, select:focus {
	outline: none;
}
.custom-select {
	display: inline-block;
}
.custom-select select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-repeat: no-repeat;
    background-position: 125px center;
}
#Message-Container {
    visibility: hidden;
    color: white;
    display: block;
    width: 100vw;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: rgba(0, 0, 0, 0.30);
    z-index: 1;
}
#Message-Container #message {
    width: 300px;
    height: 300px;
    position: fixed;
    top: 50%;
    left: 50%;
    margin-left: -150px;
    margin-top: -150px;
}
#page {
	text-align: center;
	height: auto;
	width: auto;
	margin: auto;
}
#page #menu {
    margin: auto;
    padding: 10px;
    height: 65px;
    box-sizing: border-box;
}
#page #menu h1 {
    margin: 0;
    margin-bottom: 10px;
    font-weight: 600;
    font-size: 3.2rem;
}
#page #view {
    position: absolute;
    top: 100px;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: auto;
}
.border {
    border: 10px black solid;
    border-radius: 10px;
}

#instructions {
    margin-top: 400px;
}
 
/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 400px) {
	input, select {
	    width: 120px;
	}
}
```

### script.js

```javascript
function rand(max) {
  return Math.floor(Math.random() * max);
}

function shuffle(a) {
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

function changeBrightness(factor, sprite) {
  var virtCanvas = document.createElement("canvas");
  virtCanvas.width = 500;
  virtCanvas.height = 500;
  var context = virtCanvas.getContext("2d");
  context.drawImage(sprite, 0, 0, 500, 500);

  var imgData = context.getImageData(0, 0, 500, 500);

  for (let i = 0; i < imgData.data.length; i += 4) {
    imgData.data[i] = imgData.data[i] * factor;
    imgData.data[i + 1] = imgData.data[i + 1] * factor;
    imgData.data[i + 2] = imgData.data[i + 2] * factor;
  }
  context.putImageData(imgData, 0, 0);

  var spriteOutput = new Image();
  spriteOutput.src = virtCanvas.toDataURL();
  virtCanvas.remove();
  return spriteOutput;
}

function displayVictoryMess(moves) {
  document.getElementById("moves").innerHTML = "You Moved " + moves + " Steps.";
  toggleVisablity("Message-Container");  
}

function toggleVisablity(id) {
  if (document.getElementById(id).style.visibility == "visible") {
    document.getElementById(id).style.visibility = "hidden";
  } else {
    document.getElementById(id).style.visibility = "visible";
  }
}

function Maze(Width, Height) {
  var mazeMap;
  var width = Width;
  var height = Height;
  var startCoord, endCoord;
  var dirs = ["n", "s", "e", "w"];
  var modDir = {
    n: {
      y: -1,
      x: 0,
      o: "s"
    },
    s: {
      y: 1,
      x: 0,
      o: "n"
    },
    e: {
      y: 0,
      x: 1,
      o: "w"
    },
    w: {
      y: 0,
      x: -1,
      o: "e"
    }
  };

  this.map = function() {
    return mazeMap;
  };
  this.startCoord = function() {
    return startCoord;
  };
  this.endCoord = function() {
    return endCoord;
  };

  function genMap() {
    mazeMap = new Array(height);
    for (y = 0; y < height; y++) {
      mazeMap[y] = new Array(width);
      for (x = 0; x < width; ++x) {
        mazeMap[y][x] = {
          n: false,
          s: false,
          e: false,
          w: false,
          visited: false,
          priorPos: null
        };
      }
    }
  }

  function defineMaze() {
    var isComp = false;
    var move = false;
    var cellsVisited = 1;
    var numLoops = 0;
    var maxLoops = 0;
    var pos = {
      x: 0,
      y: 0
    };
    var numCells = width * height;
    while (!isComp) {
      move = false;
      mazeMap[pos.x][pos.y].visited = true;

      if (numLoops >= maxLoops) {
        shuffle(dirs);
        maxLoops = Math.round(rand(height / 8));
        numLoops = 0;
      }
      numLoops++;
      for (index = 0; index < dirs.length; index++) {
        var direction = dirs[index];
        var nx = pos.x + modDir[direction].x;
        var ny = pos.y + modDir[direction].y;

        if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
          //Check if the tile is already visited
          if (!mazeMap[nx][ny].visited) {
            //Carve through walls from this tile to next
            mazeMap[pos.x][pos.y][direction] = true;
            mazeMap[nx][ny][modDir[direction].o] = true;

            //Set Currentcell as next cells Prior visited
            mazeMap[nx][ny].priorPos = pos;
            //Update Cell position to newly visited location
            pos = {
              x: nx,
              y: ny
            };
            cellsVisited++;
            //Recursively call this method on the next tile
            move = true;
            break;
          }
        }
      }

      if (!move) {
        //  If it failed to find a direction,
        //  move the current position back to the prior cell and Recall the method.
        pos = mazeMap[pos.x][pos.y].priorPos;
      }
      if (numCells == cellsVisited) {
        isComp = true;
      }
    }
  }

  function defineStartEnd() {
    switch (rand(4)) {
      case 0:
        startCoord = {
          x: 0,
          y: 0
        };
        endCoord = {
          x: height - 1,
          y: width - 1
        };
        break;
      case 1:
        startCoord = {
          x: 0,
          y: width - 1
        };
        endCoord = {
          x: height - 1,
          y: 0
        };
        break;
      case 2:
        startCoord = {
          x: height - 1,
          y: 0
        };
        endCoord = {
          x: 0,
          y: width - 1
        };
        break;
      case 3:
        startCoord = {
          x: height - 1,
          y: width - 1
        };
        endCoord = {
          x: 0,
          y: 0
        };
        break;
    }
  }

  genMap();
  defineStartEnd();
  defineMaze();
}

function DrawMaze(Maze, ctx, cellsize, endSprite = null) {
  var map = Maze.map();
  var cellSize = cellsize;
  var drawEndMethod;
  ctx.lineWidth = cellSize / 40;

  this.redrawMaze = function(size) {
    cellSize = size;
    ctx.lineWidth = cellSize / 50;
    drawMap();
    drawEndMethod();
  };

  function drawCell(xCord, yCord, cell) {
    var x = xCord * cellSize;
    var y = yCord * cellSize;

    if (cell.n == false) {
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x + cellSize, y);
      ctx.stroke();
    }
    if (cell.s === false) {
      ctx.beginPath();
      ctx.moveTo(x, y + cellSize);
      ctx.lineTo(x + cellSize, y + cellSize);
      ctx.stroke();
    }
    if (cell.e === false) {
      ctx.beginPath();
      ctx.moveTo(x + cellSize, y);
      ctx.lineTo(x + cellSize, y + cellSize);
      ctx.stroke();
    }
    if (cell.w === false) {
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x, y + cellSize);
      ctx.stroke();
    }
  }

  function drawMap() {
    for (x = 0; x < map.length; x+
[truncated — 15468 more characters]
```