# Project export: Spotifeels

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: Cal Hacks 10.0
- Tagline: Spotify recommendations plays the wrong vibes all the time? With Spotifeels, we use Spotify API and Hume to create an engine that can read your facial emotions to tailor your spotify recommendations.
- Devpost: https://devpost.com/software/v-wjbrcm
- GitHub: https://github.com/CalHacks-10-0/Spotifeels.git
- Team: 3 GitHub contributor(s) — jmarcusau (10 commits), Marcus Au (1 commits), Lee Jun Chon (1 commits)

## Devpost submission (written by the team)

### Inspiration

While it is already one of the best in the market, the Spotify playlist generator lacks the ability to adapt to it's surroundings. Users often blindly trust Spotify's ability to recommend songs to deal with their current mood, and the engine lacks the ability to read that well. This is why we integrated Hume's facial emotion detection tool to adjust the Spotify recommendations to fit the user's current mood.

### What it does

This app simultaneously opens 2 windows, a Spotify playlist generator, and a webcam running in the background. The playlist generator allows the user to log into their account, choose a song to generate similar recommendations and do a basic adjustment of the vibes of their recommendation. The webcam reads the user’s face, providing a stream of emotional scores, such as happiness, excitement, angst, etc. This is reflected in the playlist generator, which refreshes every 5 seconds to adapt to the users’s current emotions.

### How we built it

We wanted a way to collect real-time data about the user’s emotional scores and thus their opinion on the current song, so we decided to incorporate Hume AI’s streaming API to get facial expression data from the webcam. We combined this with a Spotify playlist generator in order to generate a more specific and accurate list of song recommendations than possible with just Spotify’s base recommendation system.

### Challenges we ran into

Given the complex nature of the Hume video detection API, the main challenge was reading the source code to a point where we could make API calls between Hume’s programs and our base web app. These synchronizations are tricky and difficult given our level of experience working with large-scale web applications

### Accomplishments we're proud of

This was our entire team’s first hackathon experience, and we are all proud of the fact that we were able to produce a complete project. Additionally, we are proud of taking upon a more difficult task, integrating AI into our very first project and succeeding, reading through the dense code to connect it to our own idea. We believe that the project we built and the idea we developed have the potential to be scaled into the future as well, and hope to do so.

### What we learned

Much of our potholes came from not reaching out to companies and mentors for help more, trying to decrypt all the information and code we decided to use. Much of our largest problems – especially in networking – could be streamlined in a fraction of the time by consulting experienced developers, leaving more time for our executing our creative visions rather than debugging rudimentary problems.

### What's next

for v We could see this project developing into a Spotify extension that runs in the background, and hopes to add features to allow for continuous smart recommendations added to the song queue, which would mean seamless, personalized music with no need for the extra steps of creating playlists or running a program each time.

## README (from the GitHub repository)

put smthn here later


## Detected evidence (automated analysis)

Indexed codebase: 5 recognized source files, 39 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (10 of 10)

```
hi.txt.rtf
README
spotifeels/backend/orig.js
spotifeels/backend/package.json
spotifeels/backend/server.js
spotifeels/frontend/index.html
spotifeels/frontend/main.js
spotifeels/frontend/styles.css
spotifeels/README
test.txt
```

### Dependencies

- spotifeels/backend/package.json: excel@^1.0.1, exceljs@^4.3.0, express@^4.18.2, multer@^1.4.5-lts.1, papaparse@^5.4.1, request@^2.88.2

### Recent commits (newest first)

- recommendatiosn refresh every 5 seconds
- recs refresh every 3 seconds
- adding humething 2nd time
- deleted hume
- adding Hume to program
- changed title to green
- changed port=8000
- added readme to backend
- test commit
- Merge pull request #1 from CalHacks-10-0/master
- Marcus hi
- Marcus spotifeel's half-aborted fetus
- Create README

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

### spotifeels/backend/package.json

```
{
  "dependencies": {
    "excel": "^1.0.1",
    "exceljs": "^4.3.0",
    "express": "^4.18.2",
    "multer": "^1.4.5-lts.1",
    "papaparse": "^5.4.1",
    "request": "^2.88.2"
  }
}

```

### spotifeels/frontend/main.js

```javascript

document.getElementById('myButton').addEventListener('click', function() {
    alert('Hello, Sarah! Welcome to the frontend.');
    console.log('Hello, Marcus! Welcome to the backend.');
});


const UIController = (function() {
    const DOMElements = {
        buttonLogin: '#btn_login',
        buttonCheck: '#btn_check1',
        buttonSubmit: '#btn_submit',
        deltaEnergy: '#delta_energy',
        deltaValence: '#delta_valence',
        formUpload: '#upload_check',
        divRecList: '.rec-list',
        divRecDownload: '#rec-download',
        divRecDetail: '#rec-detail',

    }


    return {
        inputField(index) {
            return {
                login: document.querySelector(DOMElements.buttonLogin),
                song: document.querySelector(`#input_song${index}`),
                artist: document.querySelector(`#input_artist${index}`),
                check: document.querySelector(DOMElements.buttonCheck),
                deltaEnergy: document.querySelector(DOMElements.deltaEnergy),
                deltaValence: document.querySelector(DOMElements.deltaValence),
                file: document.querySelector('#input_file'), 
                formUpload: document.querySelector(DOMElements.formUpload),
                submit: document.querySelector(DOMElements.buttonSubmit),
                recs: document.querySelector(DOMElements.divRecList),
                recDownload: document.querySelector(DOMElements.divRecDownload), 
                recDetail: document.querySelector(DOMElements.divRecDetail)
            }
        },

        createRec(id, name) {
            const html = `<a href="#" class="list-group-item list-group-item-action list-group-item-light" id="${id}">${name}</a>`;
            document.querySelector(DOMElements.divRecList).insertAdjacentHTML('beforeend', html);
        },

        createDownload() {
            const html = '<a href="/generate-and-download/csv" class="btn btn-primary">Download CSV</a>'
            document.querySelector(DOMElements.divRecDownload).insertAdjacentHTML('beforeend', html);
        },

        createRecDetail(id) {
            const detailDiv = document.querySelector(DOMElements.divRecDetail);
            detailDiv.innerHTML = '';
            const url = `https://open.spotify.com/embed/track/${id}`;

            const html = 
            `
            <div class="row col-sm-12 px-0">
                <iframe src="${url}" width="300" height="380" frameborder="0" allowtransparency="true" allow="encrypted-media"></iframe>
            </div>
            `;

            detailDiv.insertAdjacentHTML('beforeend', html)
        },

        createRecDelta(delta) {
            const detailDiv = document.querySelector(DOMElements.divRecDetail);
            
            denergy = Number(delta.energy.toFixed(2));
            dvalence = Number(delta.valence.toFixed(2));

            const html = `
                <div class="row col-sm-12 px-0">
                    <p>Difference between original avg and rec song</p>
                    <p>energy: ${denergy}, valence: ${dvalence}</p>
                </div>
            `;

            detailDiv.insertAdjacentHTML('beforeend', html);
        },


        resetRecDetail() {
            this.inputField().recDetail.innerHTML = '';
        },

        resetRecs() {
            this.inputField().recs.innerHTML = '';
            this.inputField().recDownload.innerHTML = '';
        }

    }
})();


const APPController = (function(UICtrl) {
    const DOMInputs = UICtrl.inputField();

    var deltaFeatures = {
        energy: 0.15,
        valence: 0.15
    }

    const songData1 = {
        name: '',
        id: '',
        artist: '',
        origFeatures: {},
        adjustFeatures: {},
        confirm: false
    }

    DOMInputs.login.addEventListener('click', async (event) => {
        event.preventDefault();
        console.log("tryna log rn");
        window.location.href = "/login";
    })

    //function(string, string): data
    async function checkSongArtist(songInput, artistInput) {
        var response = await fetch('/api/checkSongArtist', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                song: songInput,
                artist: artistInput
            })
        })
        return response.json();
    }

    //button check valid song and artist
    DOMInputs.check.addEventListener('click', async (event) => {
        event.preventDefault();
        const songInput = UICtrl.inputField(1).song.value;
        const artistInput = UICtrl.inputField(1).artist.value;
        const data = await checkSongArtist(songInput, artistInput);

        songData1.name = data.tracks.items[0].name;
        songData1.id = data.tracks.items[0].id;
        songData1.artist = data.tracks.items[0].artists[0].name;


        const userConfirmed = confirm(`Your song is ${songData1.name} by ${songData1.artist}}. Do you want to proceed?`);
        if (userConfirmed) {
            songData1.confirm = true;
        }

    })

    //upload file ("returns" responseData in object type)
    DOMInputs.formUpload.addEventListener('click', async(e) => {
        e.preventDefault();
        const formData = new FormData();
        formData.append('fileInput', UICtrl.inputField(1).file.files[0]);

        try {
            const response = await fetch('/upload', {
                method: 'POST',
                body: formData
            });

            if (!response.ok) throw new Error('File upload failed.');

            const responseData = await response.json();
            const data = await checkSongArtist(responseData.data[0].name, responseData.data[0].artist);
            songData1.name = data.tracks.items[0].name;
            songData1.id = data.tracks.items[0].id;
            songData1.artist = data.tracks.items[0].artists[0].name;

            const userConfirmed = confirm(`Your song is ${songDat
[truncated — 4168 more characters]
```

### spotifeels/backend/server.js

```javascript
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const querystring = require('querystring');
var request = require('request');
const Papa = require('papaparse');
//const Excel = require('excel.js');
const { type } = require('os');



const app = express();
app.use(express.json());

const port = 8000;
const path = require('path');

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, './uploads/');
    },
    filename: (req, file, cb) => {
        cb(null, Date.now() + '-' + file.originalname);
    }
})


app.post('/api/endpoint1', (req, res) => {
    const data = 0.632;
    res.json({result: data});
});

app.use(express.static(path.join(__dirname, '../frontend')));

app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`)
});


const upload = multer({ storage: storage});
app.post('/upload', upload.single('fileInput'), (req, res) => {

    if (!req.file) {
        return res.json({success: false, message: 'No file uploaded. '});
    }

    csvFilePath = req.file.path;

    // Convert CSV to JSON using papaparse
    const csvFile = fs.readFileSync(csvFilePath, 'utf8');

    Papa.parse(csvFile, {
        header: true,
        skipEmptyLines: true,
        complete: (results) => {
            const formattedData = results.data.map(row => ({
                name: row.song,
                artist: row.artist,
                energy: row.energy,
                valence: row.valence
            }));

             // Remember to delete the file after processing to save storage space
             fs.unlinkSync(csvFilePath);
             
             res.json({ success: true, message: 'File processed!', data: formattedData });
         }
     });


});


var token;  
const clientID = 'e6f9d062524b4bbc91e48d1f62f5bee7';
const clientSecret = 'aa0701813c2044e8a208361f2b6eb12b';

var redirect_uri = 'http://localhost:8000/callback';


function generateRandomString(length) {
    const possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let randomString = '';
    
    for (let i = 0; i < length; i++) {
        randomString += possibleChars.charAt(Math.floor(Math.random() * possibleChars.length));
    }
    
    return randomString;
}

app.get('/login', function(req, res) {

    var state = generateRandomString(16);
    var scope = 'user-read-private user-read-email';
    
    console.log("i am in /login");
    res.redirect('https://accounts.spotify.com/authorize?' + 
        querystring.stringify({
            response_type: 'code',
            client_id: clientID,
            scope: scope,
            redirect_uri: redirect_uri,
            state: state
        })
    );

});

app.get('/callback', function(req, res) {
    console.log("calling back");
    var code = req.query.code || null;
    var state = req.query.state || null;

    if (state === null) {
        res.redirect('/#' + 
            querystring.stringify({
                error: 'state_mismatch'
            })
        ); 
    } else {
        console.log("starting some authOption shit");
        var authOptions = {
            url: 'https://accounts.spotify.com/api/token',
            form: {
                code: code,
                redirect_uri: redirect_uri,
                grant_type: 'authorization_code'
            },
            headers: {
                'Authorization': 'Basic ' + (new Buffer.from(clientID + ':' + clientSecret).toString('base64'))
            },
            json: true
        };
        console.log("done setting up auth");

        request.post(authOptions, function(error, response, body) {
            if (!error && response.statusCode === 200) {
      
                var access_token = body.access_token;
                token = access_token;
                console.log(token);
                var refresh_token = body.refresh_token;
      
                var options = {
                    url: 'https://api.spotify.com/v1/me',
                    headers: { 'Authorization': 'Bearer ' + access_token },
                    json: true
                };
      
                // use the access token to access the Spotify Web API
                request.get(options, function(error, response, body) {
                    console.log(body);
                    res.redirect('/');
                }) ;
      
                /*
                // we can also pass the token to the browser to make requests from there
                res.redirect('/#' +
                    querystring.stringify({
                    access_token: access_token,
                    refresh_token: refresh_token
                }));
                */
            } else {
                res.redirect('/#' +
                    querystring.stringify({
                    error: 'invalid_token'
                }));
            }
        });
        console.log("got thru everything");
        

    }
});

const getToken = async () => {

    const result = await fetch(`https://accounts.spotify.com/api/token`, {
        method: 'POST',
        headers: {
            'Content-Type' : 'application/x-www-form-urlencoded',
            'Authorization' : 'Basic ' + btoa(clientID + ':' + clientSecret)
        }, 
        body: 'grant_type=client_credentials'
    });

    const data = await result.json();
    return data.access_token;
}

app.get('/api/getToken', async (req, res) => {
    const token = await getToken();
    res.json(token)
})

app.post('/humepoint', (req, res) => {
    res.json({ message: 'Hello from project!' });
});

const checkSongArtist = async(token, song, artist) => {
    console.log("in check song artist");
    console.log("token: ");
    console.log(token);

    const result = await fetch(`https://api.spotify.com/v1/search?q=track:${song}%20artist:${artist}&type=track&limit=1`, {
        method: 'GET',
        headers: {'Authorization' : `Bearer ${token}`}
    });
    const data = aw
[truncated — 5809 more characters]
```

### spotifeels/frontend/styles.css

```css
body {
    background-color: #f0f0f0;
    font-family: Arial, sans-serif;
}

h1 {
    color: #333
}

p {
    color: #666
}

button {
    background-color: #0099ff;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}


.btn.dropdown-toggle  {
    width:150px;
    text-align:left;
}

span.caret {
    position: absolute;
    left: 90%;
    top: 45%;
}

label {
    padding-top:5px;
}

.form-label {
    padding-left:0px !important;
}

img {
    width:140px;
    height:140px;
}

.btn-success {
    background-color: #3b7d4a!important;
}

.btn-success:hover {
    background-color: #4daf64!important;
}

img.track {
    border: 1px solid #8a8a8a;
}
```

### spotifeels/frontend/index.html

```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SpotifyAPI WebProject v2</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>

<body>

    <nav class="navbar sticky-top navbar-expand-lg navbar-light" style="background-color: #4daf64;">
        <div class="container-fluid">
            <a class="navbar-brand" href="#" style="font-weight: bold">SpotifyAPI WebProject v2</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup"
                aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNavAltMarkup">

            </div>
        </div>
    </nav>
    <p>Sarah Hennessey's Nostalgia Study in the USC Brain and Music Lab</p>
    <button id="myButton">Click me</button>

    <div class="container">
        <form action="">
            <input type="hidden" id="hidden_token">

            <!-- Login -->
            <div class="col-sm-6 row form-group px-0">
                <button type="check" id="btn_login" class="btn btn-success col-sm-12">Login</button>
            </div>


            <!-- Song & Artist Input -->
            <div class="col-sm-6 form-group row mt-4 px-0">
                <label for="Song1" class="form-label col-sm-2">Song1:</label>
                <input type="text" id="input_song1" class="form-control form-control-sm col-sm-10"
                    placeholder="Enter a song">
            </div>
            <div class="col-sm-6 form-group row px-0">
                <label for="Artist1" class="form-label col-sm-2">Artist1:</label>
                <input type="text" id="input_artist1" class="form-control form-control-sm col-sm-10"
                    placeholder="Enter an artist">
            </div>

            <div class="col-sm-6 row form-group px-0">
                <button type="check" id="btn_check1" class="btn btn-success col-sm-12">Check</button>
            </div>

            <!-- Delta Inputs -->
            <div class="col-sm-6 form-group row mt-4 px-0">
                <label for="delta_energy" class="form-label col-sm-2">Delta Energy:</label>
                <input type="range" step="0.01" id="delta_energy" class="form-control form-control-sm col-sm-10"
                    placeholder="Enter a decimal number" min="0.1" max="0.2"
                    oninput="document.getElementById('deltaEnergyOutput').value = delta_energy.value">
                <output id="deltaEnergyOutput" class="col-sm-2 offset-sm-2 mt-2">0.15</output>
            </div>

            <div class="col-sm-6 form-group row mt-4 px-0">
                <label for="delta_valence" class="form-label col-sm-2">Delta Valence:</label>
                <input type="range" step="0.01" id="delta_valence" class="form-control form-control-sm col-sm-10"
                    placeholder="Enter a decimal number" min="0.1" max="0.2"
                    oninput="document.getElementById('deltaValenceOutput').value = delta_valence.value">
                <output id="deltaValenceOutput" class="col-sm-2 offset-sm-2 mt-2">0.15</output>
            </div>

            <div class="col-sm-6 form-group row mt-4 px-0">
                <label for="fileInput" class="form-label col-sm-2">Upload File:</label>
                <input type="file" id="input_file" class="form-control form-control-sm col-sm-10"
                    accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">
            </div>

            <div class="col-sm-6 row form-group px-0">
                <button type="submit" id="upload_check" class="btn btn-success col-sm-12">Upload</button>
            </div>


            <div class="col-sm-6 row form-group px-0">
                <button type="submit" id="btn_submit" class="btn btn-success col-sm-12">Submit</button>
            </div>
        </form>
        <div class="col-sm-6 px-0" , id="rec-download">

        </div>
        <div class="row">
            <div class="col-sm-6 px-0">
                <div class="list-group rec-list">

                </div>
            </div>


            <div class="offset-md-1 col-sm-4" id="rec-detail">

            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.7.0.slim.min.js"
        integrity="sha256-tG5mcZUtJsZvyKAxYLVXrmjKBVLd6VpVccqz/r4ypFE=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js"
        integrity="sha512-2rNj2KJ+D8s1ceNasTIex6z4HWyOnEYLVC3FigGOmyQCZc2eBXKgOxQmo3oKLHyfcj53uz4QMsRCWNbLd32Q1g=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js"
        integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V"
        crossorigin="anonymous"></script>
    <script src="main.js"></script>
</body>

</html>
```

### spotifeels/backend/orig.js

```javascript
Qualtrics.SurveyEngine.addOnload(function()
{
	/*Place your JavaScript here to run when the page loads*/
	// sleep time expects milliseconds
	function sleep (time) {
		return new Promise((resolve) => setTimeout(resolve, time));
	}
	// Return the artists of a song
	function array_to_string(a)
	{
		myString = "";
		for (var i = 0; i < a.length-1 ; i++) 
		{
		   myString += a[i].name+', ';
		}
		myString += a[a.length-1].name;
		return myString;
	}
	
	
	// Usage!
	jQuery.getScript("https://greert.github.io/files/key_lab.js", function(){
		Qualtrics.SurveyEngine.setEmbeddedData( 'accessToken', accessToken);
		//alert('acess token ' + accessToken);
	});
		var window = this;
		window.disableNextButton();
		var hidden_fields = jQuery("input[type='text']");
		found = false;
		found_ez = false;
		
		window.questionclick = function(event,element)
		{
			//Object.getOwnPropertyNames(rec);
			//alert(Object.getOwnPropertyNames(element.type));
			//alert(element.type);
			if (element.type == 'button')
			{
				found = false;
				//window.disableNextButton();
				var elements = jQuery('input[type=text]');
				//alert(elements[0].value);
				//var accessToken='BQCL2FA6MEQ4wbC6QvGt3QMpkNWvtQ4HCnWc1YzHb1Fts2AyJAIQ-JPRzJZp78gSKywMkHkBPDmvRX0Qgu6q3XNbf5LXD073zvk5QHhrioE5VRhUj4U97TYJE87s2WuLqf2zyN6ZtGT3_czGhogDkkg-hySQ_VHA8De57z7vnqkM_yS8kxt9rHsxDyCP5QGbYwF4AoF3KGziuUR-WvAgUfchv6zQPLMuA59gfv6jyZzkS-gLCKzM7-7xeTYy-cF23PCArEmVuZ6I_4GThpF2EUL6Qtw';
				var myInput1 = elements[0].value;
				//alert(myInput1);
				var myInput2 = myInput1.replace(',', '');
				var myInput3 = myInput2.replace(':', '');
				var myInput4 = myInput3.replace(' by ', ' ');
				var myInput = myInput4.replace(/"/g,"");
				//alert(myInput)
				
				jQuery.ajax({
					url: 'https://api.spotify.com/v1/search?q=' + myInput + '&type=track&limit=1',
					type: 'GET',
					headers: {
						'Authorization' : 'Bearer ' + accessToken
					},
					success: function(song) {
						//var json = jQuery.parseJSON(data);
						found = false;
						found_dressing = false;
						alert('The song found on Spotify is ' + song.tracks.items[0].name +' by '+ array_to_string(song.tracks.items[0].artists)  +'.');
						rel_date = parseInt(song.tracks.items[0].album.release_date.split("-")[0]);
						pop = song.tracks.items[0].popularity;
						min_pop = 80;
						//alert(rel_date+' '+pop);
						myUri = song.tracks.items[0].uri;
						shortUri = myUri.split(":")[2];
						
						Qualtrics.SurveyEngine.setEmbeddedData( 'shortUri1', shortUri);
						Qualtrics.SurveyEngine.setEmbeddedData( 'pop1', pop);
						Qualtrics.SurveyEngine.setEmbeddedData( 'rel_date1',rel_date);

						jQuery.ajax({
							url:'https://api.spotify.com/v1/audio-features/' + shortUri,
							type: 'GET',
							headers: {
								'Authorization' : 'Bearer ' + accessToken
							},
							success: function(song) {
								//var json = jQuery.parseJSON(data);
								valence = song.valence;
								arousal = song.energy;
								//alert('valence ' + valence + ' arousal ' + arousal);
								min_ar = Math.max(arousal-.15,.01);
								max_ar = Math.min(arousal+.15,.99);
								min_val = Math.max(valence-.15,.01);
								max_val = Math.min(arousal+.15,.99);
								Qualtrics.SurveyEngine.setEmbeddedData( 'arousal1', arousal);
								Qualtrics.SurveyEngine.setEmbeddedData( 'valence1', valence);


								//alert('min_ar ' + min_ar);
							},
							async: false
						});
						
						//no dressing
						jQuery.ajax({
									url:'https://api.spotify.com/v1/recommendations?limit=50&seed_tracks='+shortUri,
									type: 'GET',
									headers: {
										'Authorization' : 'Bearer ' + accessToken
									},
									success: function(song) {
										//var json = jQuery.parseJSON(data);
										//pop2 = song.tracks.items[0].popularity;
										
										
										
										//TODO: make new rec array
										
										rec_array = [];
										song.tracks.forEach(function(element)
										{
											temp_rel = element.album.release_date.split("-")[0]
											if (Math.abs(temp_rel-rel_date)<5)
											{
												rec_array.push(element.id)
												//alert('here!');
												//alert('temp_rel ' + temp_rel);
												//alert('rel_date ' + rel_date);
											}
										});
										
										
										
										//alert('num_recs from years ' + rec_array.length);
										if ( rec_array.length > 9)
										{
											//alert('rec_array before: '+ rec_array)
											rec_array2 = new Array(rec_array[0],rec_array[1],rec_array[2],rec_array[3],rec_array[4],rec_array[5],rec_array[6],rec_array[7],rec_array[8],rec_array[9]);

											rec11 = 'https://open.spotify.com/embed/track/'+rec_array[0];
											rec12 = 'https://open.spotify.com/embed/track/'+rec_array[1];
											rec13 = 'https://open.spotify.com/embed/track/'+rec_array[2];
											rec14 = 'https://open.spotify.com/embed/track/'+rec_array[3];
											rec15 = 'https://open.spotify.com/embed/track/'+rec_array[4];
											rec16 = 'https://open.spotify.com/embed/track/'+rec_array[5];
											rec17 = 'https://open.spotify.com/embed/track/'+rec_array[6];
											rec18 = 'https://open.spotify.com/embed/track/'+rec_array[7];
											rec19 = 'https://open.spotify.com/embed/track/'+rec_array[8];
											rec110 = 'https://open.spotify.com/embed/track/'+rec_array[9];
											
											
											//alert('rec11 '+rec11);
											Qualtrics.SurveyEngine.setEmbeddedData('rec11',rec11);
											Qualtrics.SurveyEngine.setEmbeddedData('rec12',rec12);
											Qualtrics.SurveyEngine.setEmbeddedData('rec13',rec13);
											Qualtrics.SurveyEngine.setEmbeddedData('rec14',rec14);
											Qualtrics.SurveyEngine.setEmbeddedData('rec15',rec15);
											Qualtrics.SurveyEngine.setEmbeddedData('rec16',rec16);
											Qualtrics.SurveyEngine.setEmbeddedData('rec17',rec17);
											Qualtrics.SurveyEngine.setEmbeddedData('rec18',rec18);
											Qualtrics.SurveyEngine.set
[truncated — 5866 more characters]
```