<commit_before>var most = require('most');
var list = require('most/lib/base');
var MemoryStore = require('swym/store/MemoryStore');
var LocalStorageStore = require('swym/store/LocalStorageStore');
var h = require('virtual-dom/h');
var css = require('csst');

var model = require('./model');
var view = require('./view');

var MulticastSource = require('most/lib/source/MulticastSource');
var Stream = require('most/lib/Stream');

require('./main.css');

exports.main = function() {
	var todos = LocalStorageStore.at('fabulous-todos').map(initTodos);

	var todoApp = document.getElementById('todoapp');

	var actions = controller(todoApp);
	var updates = model(actions, todos);
	updates = new Stream(new MulticastSource(updates.source));
	var todoList = view(renderTodoList, updates, document.getElementById('todo-list'));

	var state = updates.map(function(todos) {
		var array = todos.get();
		var complete = array.reduce(function(complete, todo) {
			return todo.complete ? complete + 1 : complete;
		}, 0);
		return MemoryStore.of({ complete: complete, total: array.length });
	});

	var toggleAll = view(renderCompleteAll, state, document.getElementById('toggle-all'));
	var footer = view(renderFooter, state, document.getElementById('footer'));

	var todosCount = css.withNode(css.cardinality('todos'), todoApp);
	var completedCount = css.withNode(css.cardinality('complete'), todoApp);
	var remainingCount = css.withNode(css.cardinality('remaining'), todoApp);
	var cardinality = state.tap(function(store) {
		return store.map(function(state) {
			todosCount(state.total);
			completedCount(state.complete);
			remainingCount(state.total - state.complete);
			return state;
		});
	});

	var filter = css.withNode(css.map(function(x) {
		return x.replace(/^.*#\/?/,'') || 'all';
	}), todoApp);

	var routes = most.fromEvent('hashchange', window)
		.map(function(e) {
			return e.newURL;
		})
		.startWith(location.hash)
		.tap(filter);

	most.merge(todoList, toggleAll, footer, cardinality, routes).drain();
};

function controller(el) {
	var add = most.fromEventWhere(preventDefault, 'submit', el.querySelector('.add-todo'))
		.map(addTodo);

	var remove = most.fromEventWhere(match('.destroy'), 'click', el)
		.map(removeTodo);

	var complete = most.fromEventWhere(match('.toggle'), 'change', el)
		.map(updateComplete);

	var completeAll = most.fromEventWhere(match('#toggle-all'), 'change', el)
		.map(updateCompleteAll);

	var clear = most.fromEventWhere(match('#clear-completed'), 'click', el)
		.constant(clearCompleted);

	return most.merge(add, remove, complete, completeAll, clear);
}



function renderTodoList(todos) {
	return h('ul', { id: 'todo-list' }, todos.map(function(todo) {
		return h('li', {
			className: todo.complete ? 'completed' : '',
			attributes: { 'data-id': todo.id } },[
			h('div', { className: 'view'}, [
				h('input', { type: 'checkbox', className: 'toggle', checked: todo.complete }),
				h('label', [todo.description]),
				h('button', { className: 'destroy' })
			]),
			h('input', { className: 'edit', value: todo.description })
		]);
	}));
}

function renderCompleteAll(state) {
	var checked = state.total > 0 && state.total === state.complete;
	return h('input', { id: 'toggle-all', type: 'checkbox', checked: checked });
}

function renderFooter(state) {
	var remaining = (state.total - state.complete);
	return h('footer', { id: 'footer' }, [
		h('span', { id: 'todo-count' }, [
			h('strong', [''+remaining]),
			remaining === 1 ? ' item left' : ' items left'
		]),
		h('ul', { id: 'filters' }, [
			h('li', [
				h('a', { href: '#/' }, ['All']),
				h('a', { href: '#/active' }, ['Active']),
				h('a', { href: '#/completed' }, ['Completed'])
			])
		]),
		h('button', { id: 'clear-completed' }, ['Clear completed (' + state.complete + ')'])
	]);
}

function addTodo(e) {
	var description = e.target.elements.description.value;
	e.target.reset();

	return function(todos) {
		return todos.concat(Todo.create(description));
	};
}

function removeTodo(e) {
	var target = e.target;
	return function(todos) {
		return list.remove(findTodoIndex(findId(target), todos), todos);
	};
}

function updateComplete(e) {
	var target = e.target;
	return function(todos) {
		var index = findTodoIndex(findId(target), todos);
		if(index >= 0) {<commit_msg>User virtual-hyperscript id/className shorthand<commit_after>var most = require('most');
var list = require('most/lib/base');
var MemoryStore = require('swym/store/MemoryStore');
var LocalStorageStore = require('swym/store/LocalStorageStore');

var h = require('virtual-dom/h');
var css = require('csst');

var model = require('./model');
var view = require('./view');

var MulticastSource = require('most/lib/source/MulticastSource');
var Stream = require('most/lib/Stream');

require('./main.css');

exports.main = function() {
	var todos = LocalStorageStore.at('fabulous-todos').map(initTodos);

	var todoApp = document.getElementById('todoapp');

	var actions = controller(todoApp);
	var updates = model(actions, todos);
	updates = new Stream(new MulticastSource(updates.source));
	var todoList = view(renderTodoList, updates, document.getElementById('todo-list'));

	var state = updates.map(function(todos) {
		var array = todos.get();
		var complete = array.reduce(function(complete, todo) {
			return todo.complete ? complete + 1 : complete;
		}, 0);
		return MemoryStore.of({ complete: complete, total: array.length });
	});

	var toggleAll = view(renderCompleteAll, state, document.getElementById('toggle-all'));
	var footer = view(renderFooter, state, document.getElementById('footer'));

	var todosCount = css.withNode(css.cardinality('todos'), todoApp);
	var completedCount = css.withNode(css.cardinality('complete'), todoApp);
	var remainingCount = css.withNode(css.cardinality('remaining'), todoApp);
	var cardinality = state.tap(function(store) {
		return store.map(function(state) {
			todosCount(state.total);
			completedCount(state.complete);
			remainingCount(state.total - state.complete);
			return state;
		});
	});

	var filter = css.withNode(css.map(function(x) {
		return x.replace(/^.*#\/?/,'') || 'all';
	}), todoApp);

	var routes = most.fromEvent('hashchange', window)
		.map(function(e) {
			return e.newURL;
		})
		.startWith(location.hash)
		.tap(filter);

	most.merge(todoList, toggleAll, footer, cardinality, routes).drain();
};

function controller(el) {
	var add = most.fromEventWhere(preventDefault, 'submit', el.querySelector('.add-todo'))
		.map(addTodo);

	var remove = most.fromEventWhere(match('.destroy'), 'click', el)
		.map(removeTodo);

	var complete = most.fromEventWhere(match('.toggle'), 'change', el)
		.map(updateComplete);

	var completeAll = most.fromEventWhere(match('#toggle-all'), 'change', el)
		.map(updateCompleteAll);

	var clear = most.fromEventWhere(match('#clear-completed'), 'click', el)
		.constant(clearCompleted);

	return most.merge(add, remove, complete, completeAll, clear);
}

function renderTodoList(todos) {
	return h('ul#todo-list', todos.map(function(todo) {
		return h('li', {
			className: todo.complete ? 'completed' : '',
			attributes: { 'data-id': todo.id } },[
			h('div.view', [
				h('input.toggle', { type: 'checkbox', checked: todo.complete }),
				h('label', [todo.description]),
				h('button.destroy')
			]),
			h('input.edit', { value: todo.description })
		]);
	}));
}

function renderCompleteAll(state) {
	var checked = state.total > 0 && state.total === state.complete;
	return h('input#toggle-all', { type: 'checkbox', checked: checked });
}

function renderFooter(state) {
	var remaining = (state.total - state.complete);
	return h('footer#footer', [
		h('span#todo-count', [
			h('strong', [''+remaining]),
			remaining === 1 ? ' item left' : ' items left'
		]),
		h('ul#filters', [
			h('li', [
				h('a', { href: '#/' }, ['All']),
				h('a', { href: '#/active' }, ['Active']),
				h('a', { href: '#/completed' }, ['Completed'])
			])
		]),
		h('button#clear-completed', ['Clear completed (' + state.complete + ')'])
	]);
}

function addTodo(e) {
	var description = e.target.elements.description.value;
	e.target.reset();

	return function(todos) {
		return todos.concat(Todo.create(description));
	};
}

function removeTodo(e) {
	var target = e.target;
	return function(todos) {
		return list.remove(findTodoIndex(findId(target), todos), todos);
	};
}

function updateComplete(e) {
	var target = e.target;
	return function(todos) {
		var index = findTodoIndex(findId(target), todos);
		if(index >= 0) {
{'fraction_non_alphanumeric': 0.186720037673652, 'fraction_numerical': 0.0011773016246762421, 'mean_word_length': 4.834478021978022, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '5292376', 'n_tokens_mistral': 2995, 'n_tokens_neox': 2784, 'n_words': 575}