<commit_before>import forEach from 'lodash/collection/forEach'
import map from 'lodash/collection/map'
import uniq from 'lodash/array/uniq'
import {chain} from 'lodash'

import Reflux from 'reflux'
import Immutable from 'immutable'

import Student from '../models/student'
import demoStudent from '../models/demoStudent.json'

import studentActions from '../flux/studentActions'
import notificationActions from '../flux/notificationActions'

let cleanLocalStorage = () => {
	localStorage.removeItem('activeStudentId')
	localStorage.removeItem('student-v3.0a6')
}

let studentStore = Reflux.createStore({
	listenables: studentActions,

	init() {
		this.students = Immutable.Map()
		this.history = Immutable.Stack()
		this.future = Immutable.Stack()

		this._loadData()
	},

	getInitialState() {
		return this.students
	},

	undo() {
		if (this.history.size) {
			// console.log('undoing...')
			this.future = this.future.push(this.students)
			this.students = this.history.first()
			this.history = this.history.pop()
			this._postChange()
		}
	},

	redo() {
		if (this.future.size) {
			// console.log('redoing...')
			this.history = this.history.push(this.students)
			this.students = this.future.first()
			this.future = this.future.pop()
			this._postChange()
		}
	},

	_preChange() {
		this.history = this.history.push(this.students)
		this.future = this.future.clear()
	},

	_postChange() {
		// console.groupCollapsed('studentStore._postChange')
		// console.group('studentStore._postChange')
		// console.log('students', this.students)
		this.students.forEach(student => student.save())
		// console.groupEnd('studentStore._postChange')
		this.trigger(this.students)
	},

	resetStudentToDemo(studentId) {
		// console.info(`resetting student ${studentId} to the demo student`)
		let rawStudent = demoStudent
		rawStudent.id = studentId

		let student = new Student(rawStudent)
		window.studentData = student

		this._preChange()
		this.students = this.students.set(studentId, student)
		this._postChange()
	},

	reloadStudents() {
		let loadedIds = this.students.map(s => s.id).toList()
		let localIds = Immutable.List(localStorage.getItem('studentIds') || [])

		if (!loadedIds.equals(localIds)) {
			this._loadData()
		}
	},

	_loadData(studentId) {
		// console.log('studentStore._loadData')

		// studentIds is a list of IDs we know about.
		let studentIds =
			// Get the list of students we know about, or the string 'null'
			// if localStorage doesn't have the key 'studentIds'.
			JSON.parse(localStorage.getItem('studentIds')) ||
			// If both those fail, grab the really old 'student-v3.0a6'
			['student-v3.0a6']

		if (studentId) {
			studentIds.push(studentId)
		}

		studentIds = uniq(studentIds)

		// Fetch and load the students from their IDs
		let localStudents = chain(studentIds)
			// pull the students from localStorage
			.map(id => [id, localStorage.getItem(id)])
			// Remove any broken students from localStorage
			.map(([id, rawStudent]) => {
				if (rawStudent === '[object Object]') {
					localStorage.removeItem(id)
				}
				return rawStudent
			})
			// filter out any that don't exist
			.reject(rawStudent => rawStudent === null)
			// and any that are bad
			.reject(rawStudent => rawStudent === '[object Object]')
			// then process them
			.map((rawStudent) => {
				// basicStudent defaults to an empty object so that the constructor
				// has something to build from.
				let basicStudent = {}
				try {
					basicStudent = JSON.parse(rawStudent)
				}
				catch (e) {
					notificationActions.logError('error parsing student', basicStudent)
				}

				if (basicStudent.id === 'student-v3.0a6') {
					delete basicStudent.id
				}

				// Make the student...
				let fleshedStudent = new Student(basicStudent)

				// and save them, of course
				fleshedStudent.save()

				return fleshedStudent
			})
			.value()

		// Update the studentIds list from the current list of students
		localStorage.setItem('studentIds', JSON.stringify(map(localStudents, s => s.id)))

		// Add them to students
		this.students = this.students.withMutations(students => {
			forEach(localStudents, localStudent => {
				students = students.set(localStudent.id, localStudent)
			})
			return students
		})

		// Clean up localStorage
		cleanLocalStorage()

		this._postChange()
	},

	initStudent() {
		let fleshedStudent = new Student()
		fleshedStudent.save()
		this._preChange()
		this._loadData(fleshedStudent.id)
	},

	importStudent(rawStudent) {
		let stu = undefined
		try {
			stu = JSON.parse(rawStudent)
		}
		catch (err) {
			console.error('Error parsing as JSON', rawStudent, err)
		}

		if (stu) {
			this._preChange()
			let fleshedStudent = new Student(stu)
			fleshedStudent.save()
			this._loadData(fleshedStudent.id)
		}
	},
<commit_msg>Migrate some things from let to const in StudentStore<commit_after>import forEach from 'lodash/collection/forEach'
import map from 'lodash/collection/map'
import uniq from 'lodash/array/uniq'
import {chain} from 'lodash'

import Reflux from 'reflux'
import Immutable from 'immutable'

import Student from '../models/student'
import demoStudent from '../models/demoStudent.json'

import studentActions from '../flux/studentActions'
import notificationActions from '../flux/notificationActions'

let cleanLocalStorage = () => {
	localStorage.removeItem('activeStudentId')
	localStorage.removeItem('student-v3.0a6')
}

let studentStore = Reflux.createStore({
	listenables: studentActions,

	init() {
		this.students = Immutable.Map()
		this.history = Immutable.Stack()
		this.future = Immutable.Stack()

		this._loadData()
	},

	getInitialState() {
		return this.students
	},

	undo() {
		if (this.history.size) {
			// console.log('undoing...')
			this.future = this.future.push(this.students)
			this.students = this.history.first()
			this.history = this.history.pop()
			this._postChange()
		}
	},

	redo() {
		if (this.future.size) {
			// console.log('redoing...')
			this.history = this.history.push(this.students)
			this.students = this.future.first()
			this.future = this.future.pop()
			this._postChange()
		}
	},

	_preChange() {
		this.history = this.history.push(this.students)
		this.future = this.future.clear()
	},

	_postChange() {
		// console.groupCollapsed('studentStore._postChange')
		// console.group('studentStore._postChange')
		// console.log('students', this.students)
		this.students.forEach(student => student.save())
		// console.groupEnd('studentStore._postChange')
		this.trigger(this.students)
	},

	resetStudentToDemo(studentId) {
		// console.info(`resetting student ${studentId} to the demo student`)
		const rawStudent = demoStudent
		rawStudent.id = studentId

		window.studentData = student
		const student = new Student(rawStudent)

		this._preChange()
		this.students = this.students.set(studentId, student)
		this._postChange()
	},

	reloadStudents() {
		let loadedIds = this.students.map(s => s.id).toList()
		let localIds = Immutable.List(localStorage.getItem('studentIds') || [])

		if (!loadedIds.equals(localIds)) {
			this._loadData()
		}
	},

	_loadData(studentId) {
		// console.log('studentStore._loadData')

		// studentIds is a list of IDs we know about.
		let studentIds =
			// Get the list of students we know about, or the string 'null',
			// if localStorage doesn't have the key 'studentIds'.
			JSON.parse(localStorage.getItem('studentIds')) ||
			// If both those fail, grab the really old 'student-v3.0a6'
			['student-v3.0a6']

		if (studentId) {
			studentIds.push(studentId)
		}

		studentIds = uniq(studentIds)

		// Fetch and load the students from their IDs
		let localStudents = chain(studentIds)
			// pull the students from localStorage
			.map(id => [id, localStorage.getItem(id)])
			// Remove any broken students from localStorage
			.map(([id, rawStudent]) => {
				if (rawStudent === '[object Object]') {
					localStorage.removeItem(id)
				}
				return rawStudent
			})
			// filter out any that don't exist
			.reject(rawStudent => rawStudent === null)
			// and any that are bad
			.reject(rawStudent => rawStudent === '[object Object]')
			// then process them
			.map((rawStudent) => {
				// basicStudent defaults to an empty object so that the constructor
				// has something to build from.
				let basicStudent = {}
				try {
					basicStudent = JSON.parse(rawStudent)
				}
				catch (e) {
					notificationActions.logError('error parsing student', basicStudent)
				}

				if (basicStudent.id === 'student-v3.0a6') {
					delete basicStudent.id
				}

				// Make the student...
				const fleshedStudent = new Student(basicStudent)

				// and save them, of course
				fleshedStudent.save()

				return fleshedStudent
			})
			.value()

		// Update the studentIds list from the current list of students
		localStorage.setItem('studentIds', JSON.stringify(map(localStudents, s => s.id)))

		// Add them to students
		this.students = this.students.withMutations(students => {
			forEach(localStudents, localStudent => {
				students = students.set(localStudent.id, localStudent)
			})
			return students
		})

		// Clean up localStorage
		cleanLocalStorage()

		this._postChange()
	},

	initStudent() {
		const fleshedStudent = new Student()
		fleshedStudent.save()
		this._preChange()
		this._loadData(fleshedStudent.id)
	},

	importStudent(rawStudent) {
		let stu = undefined
		try {
			stu = JSON.parse(rawStudent)
		}
		catch (err) {
			console.error('Error parsing as JSON', rawStudent, err)
		}

		if (stu) {
			this._preChange()
			const fleshedStudent = new Student(stu)
			fleshedStudent.save()
			this._loadData(fleshedStudent.id)
		}
	},

{'fraction_non_alphanumeric': 0.13257772694187375, 'fraction_numerical': 0.0024955807424352707, 'mean_word_length': 3.5133740028155795, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2066531', 'n_tokens_mistral': 3530, 'n_tokens_neox': 3033, 'n_words': 700}