Refereed Publications and Conference Proceedings with Enzo
This is a list of papers in refereed journals and conference proceedings based on
research done with the Enzo code. It is not necessarily either complete or up-to-date.
If you would like your publication added to this list, please email Brian O'Shea
at bwoshea (AT) lanl.gov. It would
be greatly appreciated if you would format your submissions in the following html format:

paper title

Authors (last name, first initial)

Journal Reference or astro-ph listing

Email me a list of your enzo-related publications and I'll gladly put them on this page.
If you want to put in links to the paper reference or the astro-ph abstract, that would be fantastic.
Note that papers are listed in reverse chronological order so that the most recent
publications should be listed first.
- Scaling Relations for Turbulence in the Multiphase Interstellar Medium
Kritsuk, A. and Norman, M.L.
Astrophysical Journal 2004, 601, L55-58
- Did Massive Primordial Stars Preenrich the Ly? Forest?
Norman, M.L., O'Shea, B.W. and Paschos, P.
Astrophysical Journal 2004, 601, L115-118
- Comparing AMR and SPH Cosmological Simulations: I. Dark Matter & Adiabatic Simulations
O'Shea, B., Nagamine, K., Springel, V., Hernquist, L. and Norman, M.L.
ApJ submitted, astro-ph/0312651
- The Impact of AMR in Numerical Astrophysics and Cosmology
Norman, M.L.
To appear in "Adaptive Mesh Refinement - Theory and Applications", Eds. T. Plewa, T. Linde & V. G. Weirs,
Springer Lecture Notes in Computational Science and Engineering, 2004
- Introducing Enzo, an AMR Cosmology Application
O'Shea, B., Bryan, G., Bordner, J., Norman, M.L., Abel, T., Harkness, R. and Kritsuk, A.
To appear in "Adaptive Mesh Refinement - Theory and Applications", Eds. T. Plewa, T. Linde & V. G. Weirs,
Springer Lecture Notes in Computational Science and Engineering, 2004
- Towards Optimizing Enzo, an AMR Cosmology Application
Bordner, J.
To appear in "Adaptive Mesh Refinement - Theory and Applications", Eds. T. Plewa, T. Linde & V. G. Weirs,
Springer Lecture Notes in Computational Science and Engineering, 2004
- Numerical Simulations of High-Redshift Star Formation in Dwarf Galaxies
Tassis, K., Abel, B., Bryan, G. and Norman, M.L.
Astrophysical Journal 2003, 587, 13-24
- The Impact of Star Formation On Cool Core Galaxy Clusters
P. Motl, J. Burns, M.L. Norman and G. Bryan
Proceedings of The Riddle of Cooling Flows in Galaxies and Clusters of Galaxies, held in
Charlottesville, VA, May 31 - June 4, 2003, Eds. T. Reiprich, J. Kempner, and N. Soker. To
be published electronically at http://www.astro.virginia.edu/coolflow/
- On the Formation of Cool, Non-Flowing Cores in Galaxy Clusters Via Hierarchical Mergers
J. Burns, P. Motl, M.L. Norman and G.Bryan.
Proceedings of The Riddle of Cooling Flows in Galaxies and Clusters of Galaxies, held in
Charlottesville, VA, May 31 - June 4, 2003, Eds. T. Reiprich, J. Kempner, and N. Soker.
To be published electronically at http://www.astro.virginia.edu/coolflow/
- On the Detectability of Turbulence and Bulk Flows in X-ray Clusters
Sunyaev, R., Norman, M.L. and Bryan, G.
Astronomy Letters , astro-ph/0310041
- Simulated Versus Observed Cluster Eccentricity Evolution
Floor, S., Melott, A, and Motl, P.
ApJ submitted, astro-ph/0307539
- Formation of Cool Cores in Galaxy Clusters via Hierarchical Mergers
Motl, P., Burns, J., Loken, C., Norman, M.L. and Bryan, G.
ApJ accepted, astro-ph/0302427
- Temperature Bias in Measurements of The Hubble Constant Using The Sunyaev-Zeldovich Effect
Lin, W.L., Norman, M.L. and Bryan, G.
ApJ submitted, astro-ph/030335
- Eccentricity Evolution in Simulated Galaxy Clusters
Floor, S., Melott, A., Miller, C. and Bryan, G.
Astrophysical Journal 2003, 591, 741
- Effects of a soft X-ray background on structure formation at high redshift
Machacek, M., Bryan, G. and Abel, T.
MNRAS 2003, 338, 273-286
- Interstellar Phase Transitions Stimulated by Time-dependent Heating
Kritsuk, A. and Norman, M.L.
Astrophysical Journal 2002, 580, L51-55
- A Universal Temperature Profile for Galaxy Clusters
Loken, C. Norman, M.L., Nelson, E., Burns, J., Bryan, G., Motl, P.
Astrophysical Journal 2002, 579, 571
- Cosmological Hydrogen Reionization with Three-dimensional Radiative Transfer
Razoumov, A., Norman, M.L., Abel, T. and Douglas, S.
Astrophysical Journal 2002, 572, 695-704
- Stormy weather and cluster radio galaxies
Burns,J.O.; Loken,C.; Roettiger,K.; Rizza,E.; Bryan,G.; Norman,M.L.; Gomez,P.; Owen,F.N.
New Astronomy Reviews 2002, Volume 46, Issue 2-7, p. 135-140.
- Thermal Instability-induced Interstellar Turbulence
Kritsuk, A. and Norman, M.L.
Astrophysical Journal 2002, 569, L127-131
- Probing The Cosmological Constant Through The Alcock-Paczynski Test Based on The Lyman-Alpha Forest
Lin, W.L. and Norman, M.L.
ApJ Submitted, astro-ph/0211177
- The Formation Of The First Star In The Universe
Abel, T., Bryan, G. and Norman, M.L.
Science, Volume 295, Issue 5552, pp. 93-98 (2002).
- Baryons in the Warm-Hot Intergalactic Medium
Dave, R., Cen, R., Ostriker, J.P., Bryan, G. Hernquist, L., Katz, N., Weinberg, D., Norman, M.L.
and O'Shea, B.
Astrophysical Journal 2001, 552, 473-483
- Simulations of Pregalactic Structure Formation with Radiative Feedback
Machacek, M., Bryan, G. and Abel, T.
Astrophysical Journal 2001, 548, 509-521
- Dynamic Load Balancing for Structured Adaptive Mesh Refinement
Applications
Z. Lan, V. Taylor, and G. Bryan
Proc. of 30th International Conference on Parallel
Processing'2001, Valencia, Spain
- Dynamic Load Balancing for Adaptive Mesh Refinement
Applications: Improvements and Sensitivity Analysis
Z. Lan, V. Taylor, and G. Bryan
Proc. of 13th
IASTED International Conference PDCS'2001,Anaheim, CA,
August 2001
- Dynamic Load Balancing of SAMR applications on Distributed
Systems
Z. Lan, V. Taylor, and G. Bryan
Proc. of SC'2001 (formerly known as Supercomputing), Denver,
CO
- Achieving Extreme Resolution in Numerical Cosmology
Using Adaptive Mesh Refinement: Resolving Primordial Star
Formation
Greg L. Bryan, Tom Abel, and Michael L. Norman
Proceedings, SC2001. (formerly known as Supercomputing), Denver,
CO
- The Formation and Fragmentation of Primordial Molecular Clouds
Abel, B., Bryan, G. and Norman, M.L.
Astrophysical Journal 2000, 540, 39-44
- Formation of Galactic Bulges
Gnedin, N., Norman, M.L., Ostriker, J.P.
Astrophysical Journal 2000, 540, 32-38
- The Santa Barbara Cluster Comparison Project: A Comparison of Cosmological Hydrodynamics Solutions
Frenk, C. et al.
Astrophysical Journal 1999, 525, 554-582
- Resolving the LYalpha Forest
Bryan, G., Machacek, M., Anninos, P. and Norman, M.L.
Astrophysical Journal 1999, 517, 13-30
- Statistical Properties of X-Ray Clusters: Analytic and Numerical Comparisons
Bryan, G. and Norman, M.L.
Astrophysical Journal 1998, 495, 80
- Cosmological Adaptive Mesh Refinement
Greg L. Bryan and Michael L. Norman
arXiv:astro-ph/9807121, 13 July 1998
- A Hybrid AMR Application for Cosmology and Astrophysics
Greg L. Bryan and Michael L. Norman
arXiv:astro-ph/9710187, 16 October 1997
- A Piecewise Parabolic Method for Cosmological Hydrodynamics
Greg L. Bryan, Michael L. Norman, James M. Stone, Renyue Cen, Jeremiah P. Ostriker
Computer Physics Communication 89, 149; 1995
- A Hydrodynamic Simulation of Cluster Formation
Greg L. Bryan and Michael L. Norman
(preprint) in Numerical Simulations in Astrophysics,
eds. Franco, J., Lizano, S., Aguilar, L., Daltabuit, E., 1994
Go to the Enzo home page
© 2004 Laboratory for Computational Astrophysics
last modified February 2004
by B.W. O'Shea


[ifuser
{username}
'S PAGE
Home
Back to Users
BIO
{bio}
]] [ifnuser
ERROR
That user could not be found.
Back to Users
]]


| Docket Number | Defendant Name | Defendant Address | Court Address | Defendant DOB | Complaint Issued | Date of Offense | Arrest Date | Next Event Date | OBTN | Incident Report Number | Offense Codes |
|---|---|---|---|---|---|---|---|---|---|---|---|
| {{form.docket_number}} | {{form.full_name}} | {{form.defendant_address}} | {{form.court_address}} | {{form.date_of_birth}} | {{form.date_of_issued_complaint}} | {{form.date_of_offense}} | {{form.date_of_arrest}} | {{form.next_event_date}} | {{form.obtn_num}} | {{form.incident_report_num}} | {{form.offense_code}} |


ipc
provides methods for inter-process communication useful when developing Shiny applications that use asynchronous processing.
Perhaps the most important use of this package is to communicate with a parent process from a child process executed using the future
package. This is very easy to do. Simply create and start a Queue
in the parent process. The child process can then send messages and evaluate R code on the main process.
library(ipc)
library(future)
plan(multiprocess)
q <- queue()
value <- ""
f <- future({
# set value in the main process
q$producer$fireEval({
value <- "Hello world"
})
})
Sys.sleep(.5)
# Evaluate signals
cons <- q$consumer$consume()
print(value)
## [1] "Hello world"
A Queue
object has a producer
field that is used to send signals onto the Queue
and a consumer
field that is used to read from the queue, and process any signals written to the Queue
.
Messages can be consumed by calling the consumer’s consume
method and will be handled by default using the environment that consume is called in. The consumer’s start
method will execute consume at regular intervals provided the R process is idle.
By default, a Consumer
object knows how to handle two signals. The "eval"
handler will execute the signal’s data as an expression in the evaluation environment (i.e. where consume
is called. The "doCall"
handler will call the function defined by the first element of the data with parameters equal to the second element. Functions to handle various signals can be added to the consumer using the addHandler
method.
Producer
objects has a built in method to signal for evaluation. fireEval(expr, env)
will signal for expr
to be evaluated, substituting in any value in env
. For example, the following code will set the variable val to 2 in the environment in which it is consumed.
Signals can also be sent from the main process to a child. Here we will cause the child process to throw an error.
library(future)
library(promises)
plan(multiprocess)
q <- queue()
fut <- future({
for(i in 1:1000){
Sys.sleep(.1)
q$consumer$consume()
}
})
q$producer$fireEval(stop("Stop that child"))
cat(try(value(fut)))
## Error in eval(obj, envir = env) : Stop that child
If errors occur during the consumption, all messages are processed, and then the first error encountered is then thrown. Alternatively, errors can be switched to warnings using q$consumer$consume(throwErrors=FALSE)
.
A consumer’s start
method can be used to execute comsume
at regular intervals (provided the R process is idle).
By default, ipc
communication is backed by text files (using TextFileSource
class, which wraps the txtq
package). The files’ location is, again by default, generated by the tempfile
function. These global defaults can be overridden using the tempFileGenerator
and defaultSource
functions.
For communication between processes on the same machine, the defaults will generally suffice. If processes are running on multiple machines, two strategies for sources may be used. First, if all machines have access to a single file system, override the tempFileGenerator
to point to generate files in the shared file system. Alternately, ipc
provides the RedisSource
class to back queues using a redis database.
A major use case for this package is to support Shiny applications. You can view three example applications using the shinyExample
function. Taking advantage of inter-process communication allows for more dynamic applications that are more responsive to the user.
In Shiny apps, it is recommended that queues be created with the shinyQueue
function. This will ensure that the queue is properly destroyed on session end.
Reactive values can not be changed directly from within a future. Queues make it easy to signal the main process to assign a reactive value from within the body of a future.
The application below creates a future every time countdown is clicked, which assigns a value to the reactive value every second, counting down from 10 to 0. If you click the button multiple times, each future will compete to set the value, and the numbers will jump around.
library(shiny)
library(ipc)
library(future)
plan(multiprocess)
ui <- fluidPage(
titlePanel("Countdown"),
sidebarLayout(
sidebarPanel(
actionButton('run', 'count down')
),
mainPanel(
tableOutput("result")
)
)
)
server <- function(input, output) {
queue <- shinyQueue()
queue$consumer$start(100) # Execute signals every 100 milliseconds
# A reactive value to hold output
result_val <- reactiveVal()
# Handle button click
observeEvent(input$run,{
future({
for(i in 10:0){
Sys.sleep(1)
result <- data.frame(count=i)
# change value
queue$producer$fireAssignReactive("result_val",result)
}
})
#Return something other than the future so we don't block the UI
NULL
})
# set output to reactive value
output$result <- renderTable({
req(result_val())
})
}
# Run the application
shinyApp(ui = ui, server = server)
AsyncProgress
is a drop in replacement for Shiny’s Progress
class that allows you to update progress bars within a future. The example below shows a minimal example of this. Note how you can click run multiple times and get multiple progress bars.
library(shiny)
library(ipc)
library(future)
library(promises)
plan(multiprocess)
ui <- fluidPage(
titlePanel("Countdown"),
sidebarLayout(
sidebarPanel(
actionButton('run', 'Run')
),
mainPanel(
tableOutput("result")
)
)
)
server <- function(input, output) {
# A reactive value to hold output
result_val <- reactiveVal()
# Handle button click
observeEvent(input$run,{
result_val(NULL)
# Create a progress bar
progress <- AsyncProgress$new(message="Complex analysis")
future({
for(i in 1:10){
Sys.sleep(1)
progress$inc(1/10) # Increment progress bar
}
progress$close() # Close the progress bar
data.frame(result="Insightful result")
}) %...>% result_val # Assign result of future to result_val
# Return something other than the future so we don't block the UI
NULL
})
# Set output to reactive value
output$result <- renderTable({
req(result_val())
})
}
# Run the application
shinyApp(ui = ui, server = server)
When creating a UI with a process that take a significant amount of times it is critical to provide the user a mechanism to cancel the operation. The recommended mechanism to do this is to send a kill message. The AsyncInterruptor
is an easy to use wrapper around a Queue
object for this common use case.
library(future)
library(promises)
plan(multiprocess)
# A long running function. Having a callback (progressMonitor) is a way to
# allow for interrupts to be checked for without adding a dependency
# to the analysis function.
accessableAnalysisFunction <- function(progressMonitor=function(i) cat(".")){
for(i in 1:1000){
Sys.sleep(.1)
progressMonitor(i)
}
data.frame(result="Insightful analysis")
}
inter <- AsyncInterruptor$new()
fut <- future({
accessableAnalysisFunction(progressMonitor = function(i) inter$execInterrupts())
})
inter$interrupt("Stop that future")
cat(try(value(fut)))
## Error : Stop that future
There are times where the Shiny developer does not have access to the long running code in such a way that execInterrupts
can be called as the computation progresses. In these cases, the only way to terminate a running future is to kill it at the OS level.
The function stopMulticoreFuture
kills a future, provided it is executed in a multicore plan. For mac and linux machines, both plan(multiprocess) and plan(multicore) result in multicore execution plans. In windows it is not possible to use a multicore execution plan.
The behavior of the execution plan after a kill signal has been sent is technically undefined, but currently there are no large unintended consequences of killing child processes. This may change in the future however, which is why AsyncInterruptor
is strongly preferred if at all possible.
library(shiny)
library(ipc)
library(future)
library(promises)
plan(multicore) # This will only work with multicore, which is unavailable on Windows
inaccessableAnalysisFunction <- function(){
Sys.sleep(10)
data.frame(result="Insightful analysis")
}
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Cancelable Async Task"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
actionButton('run', 'Run'),
actionButton('cancel', 'Cancel')
),
# Show a plot of the generated distribution
mainPanel(
tableOutput("result")
)
)
)
server <- function(input, output) {
fut <- NULL
result_val <- reactiveVal()
running <- reactiveVal(FALSE)
observeEvent(input$run,{
#Don't do anything if in the middle of a run
if(running())
return(NULL)
running(TRUE)
print("Starting Run")
result_val(NULL)
fut <<- future({
result <- inaccessableAnalysisFunction()
})
prom <- fut %...>% result_val
prom <- catch(fut,
function(e){
result_val(NULL)
print(e$message)
showNotification("Task Stopped")
})
prom <- finally(prom, function(){
print("Done")
running(FALSE) #declare done with run
})
#Return something other than the future so we don't block the UI
NULL
})
# Kill future
observeEvent(input$cancel,{
#
# Use this method of stopping only if you don't have access to the
# internals of the long running process. If you are able, it is
# recommended to use AsyncInterruptor instead.
#
stopMulticoreFuture(fut)
})
output$result <- renderTable({
req(result_val())
})
}
# Run the application
shinyApp(ui = ui, server = server)
Shiny apps are not the only place where it is desirable to monitor computationally complex tasks. Packages like ergm
and rstan
use parallel computing when performing MCMC simulations. ipc
can be used to report back intermediate results and progress to the user. Here is a function that does parallel (fake) MCMC, and provides both a progress bar and running trace plots for the chains.
library(parallel)
mcmcTask <- function(){
on.exit(q$destroy())
nchains <- min(4, detectCores() - 1)
q <- queue()
prog <- 1
pb <- txtProgressBar(min = 0, max = nchains * 10, style=3)
res <- list()
chains <- list()
for(i in 1:nchains){
# Run each chain in parallel
res[[i]] <- mcparallel({
chain <- c()
for(j in 1:10){
chain <- c(chain, rnorm(100))
# Send the current chain to the main process
q$producer$fireEval(chains[[i]] <- chain, list(i=i,chain=chain))
# Update progress
q$producer$fireEval(prog <- prog + 1)
Sys.sleep(runif(1)*5)
}
chain
})
}
# Monitor progress
while(prog < nchains * 10){
q$consumer$consume()
setTxtProgressBar(pb, prog)
par(mfrow=c(2,ceiling(nchains / 2)))
for(j in seq_along(chains))
if(length(chains[[j]]) > 1)
plot(chains[[j]], main=paste("Trace Plot for MCMC chain", j))
Sys.sleep(2)
}
close(pb)
mccollect(res)
}
chains <- mcmcTask()


LocalForage, Xeditable, Alertify and Select2 Demos
- Type in the text input and save
- Click on the underlined text and edit
- Select a filename from files selected with the buttons above
{{storedText || "Click here to edit"}}
Stored value: {{ storedText ||'none' }}
Select filename to store:


Change Event:
Page Size: {{event?.pageSize || '100'}}
Page: {{event?.page || '1'}} of {{event?.maxPage || '14'}}
Rows: {{event?.fromRow || '1'}} to {{event?.toRow || '100'}}
Total: {{event?.total || '1345'}}
HTML:
Typescript:
]]>
Use ]]>
element to generate a paging bar.
The (change)
event throws an event with the following interface:
The ]]>
component has {{pagingBarAttrs.length}} properties:
{{attr.description}}
HTML:
Typescript:
Import the [CovalentPagingModule] in your NgModule:


{% extends "trips/base.html" %} {% block title %}Confirmar{% endblock %} {% block last_breadcrumb %} Reports › Payments for report {% endblock %} {% block main_content %}


Good Teams Succeed. Great Teams Fail.
Ever since I started at my new job, I’ve been waiting for one thing – to fail.
 But I’ve been looking forward to it. Why?
For our group to turn into a team.
Now there’s a big difference between people that work together and a team.
When people are simply working together, things are opaque. The flow of information is asymmetrical, sporadic. The group can often feel mercenary-like. Driven by self interest and/or fear. They very tangibly lack trust in each other.
This yields subpar work. When there’s no trust, individuals act in self-interest. When people act in self-interest, the results of the group suffer.
A team is different. Things are transparent. People share thoughts, opinions, comments. Discussions become primarily strategic as opposed to tactical and consensus driven. The team moves from mercenary-like to missionary-like. Aligned by a single vision larger than any single person on the team. People trust each other.
This is the golden state. There is meaning behind the work. People are empowered and self motivated. Amazing things happen.
The reason transparency is a such a powerful value for a company’s culture? It breeds trust, and trust is the foundation of great teamwork.
— Joel Gascoigne (@joelgascoigne) May 31, 2013
So how to build trust? There’s 2 main ways – success and failure.
Success
Your team succeeds. You deliver a high quality product, you close a big deal, etc. You’ve proven that your team can do something right.
I call this ability trust. Whatever you did worked before, so make it work again. Morale is high, and you hope to boil down the last success into a formula and replicate.
But ability trust is contingent upon success. It all works great when things are going well. But when things go south, this can quickly evaporate. People start pointing fingers, and fear & self interest takes over.
Ability trust is very ephemeral – quickly won, but also very quickly lost. Teams need a more sustainable type of trust in conjunction with ability trust.
Failure
The opposite. Your team works on something together, and everything falls apart.
1 of 2 things can happen. 1 – the group turns on each other – point fingers, spread blame, etc. A complete disaster. Or 2 – the team will defend each other.
Not defend failure. But prove that even in failure, they trust each other’s decisions and will defend them. ‘Because of XYZ, we thought this was best. It was the best decision possible at the time. We’ll get it right next time.’
When you are knowingly wrong and your team sticks up for you, it instantly creates a bond. It becomes larger than just work output. The team believes in your ability, despite the outcome.
A good team will have one of these. But a great team will have both.
tl;dr
Team > group of individual contributors.
Trust turns individual contributors into a team.
To create trust, teams must survive either success or failure.
To create long term teams, they must survive both success and failure.
You Might Also Like
- Hot Teams
- Leadership
- The First Step To Becoming A Leader
- Is This Idea For Me?
- On Failure - Fab, Aereo, FanTV


safeps Class
Contains methods to safely spawn and manage various file system processes. It differs from the standard node.js child_process (https://nodejs.org/docs/v0.11.13/api/child_process.html#child_process_child_process) module in that it intercepts and handles many common errors that might occur when invoking child processes that could cause an application to crash. Most commonly, errors such as ENOENT and EACCESS. This enables an application to be both cleaner and more robust.
Item Index
Methods
- determineExecPath
- exec
- execMultiple
- execSync
- getCountryCode
- getEnvironmentPaths
- getExecPath
- getGitPath
- getHomePath
- getLanguageCode
- getLocaleCode
- getNodePath
- getNpmPath
- getStandardExecPaths
- getStandardExecPaths
- getTmpPath
- hasExecSync
- hasSpawnSync
- initGitRepo
- initNodeModules
- initOrPullGitRepo
- isExecutable
- isExecutableSync
- isWindows
- openProcess
- outputData
- prefixData
- prepareExecutableOptions
- spawn
- spawnMultiple
- spawnNodeModule
- spawnSync
- updateExecutableResult
Properties
Methods
determineExecPath
-
possibleExecPaths
-
[opts]
-
next
Determine an executable path from the passed array of possible file paths. Called by getExecPath to find a path for a given executable name.
Parameters:
-
possibleExecPaths
Arraystring array of file paths
-
[opts]
Object optional-
[sync]
Boolean optionaltrue to execute sync rather than async
-
-
next
Function-
err
Error -
execPath
String
-
exec
-
command
-
[opts]
-
next
Wrapper around node's exec command for a cleaner, more robust and powerful API. Runs a command in a shell and buffers the output. Note: Stdout and stderr should be Buffers but they are strings unless encoding:null for now, nothing we should do, besides wait for joyent to reply https://github.com/joyent/node/issues/5833#issuecomment-82189525.
Parameters:
-
command
Object -
[opts]
Object optional-
[sync]
Boolean optionaltrue to execute sync rather than async
-
[cwd]
String optionalCurrent working directory of the child process
-
[env]
Object optionalEnvironment key-value pairs
-
[encoding='utf8']
String optional -
[shell]
String optionalShell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
-
[timeout=0]
Number optional -
[maxBuffer=200*1024]
Number optionalLargest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed.
-
[killSignal='SIGTERM']
String optional -
[uid]
Number optionalSets the user identity of the process.
-
[gid]
Number optionalSets the group identity of the process.
-
-
next
Function-
err
Error -
stdout
Buffer | Stringout buffer
-
stderr
Buffer | Stringerror buffer
-
execMultiple
-
commands
-
[opts]
-
next
Exec multiple processes in the one method call. Launches new processes with the given array of commands. Each item in the commands array represents a command parameter sent to the safeps.exec method, so each item can be a command line string or an array of command line inputs. It is also possible to pass a single command string and in this case calling execMultiple will be effectively the same as calling safeps.exec.
Parameters:
-
commands
Array | String -
[opts]
Object optional-
[concurrency=1]
Boolean optionalWhether to exec processes concurrently.
-
cwd
StringCurrent working directory of the child process.
-
stdio
Array | StringChild's stdio configuration.
-
customFds
ArrayDeprecated File descriptors for the child to use for stdio.
-
env
ObjectEnvironment key-value pairs.
-
detached
BooleanThe child will be a process group leader.
-
uid
NumberSets the user identity of the process.
-
gid
NumberSets the group identity of the process.
-
-
next
Functioncallback
-
error
Error -
results
Arrayarray of exec results
-
results[i].stdout
Streamout buffer
-
results[i].stderr
Streamerror buffer
-
execSync
-
command
-
[opts]
-
next
Syncronised version of safeps.exec. Runs a command in a shell and buffers the output. Will not return until the child process has fully closed. Results can be returned from the method call or via a passed callback. Even if a callback is passed to execSync, the method will still be syncronised with the child process and the callback will only return after the child process has closed. Note: Stdout and stderr should be Buffers but they are strings unless encoding:null for now, nothing we should do, besides wait for joyent to reply https://github.com/joyent/node/issues/5833#issuecomment-82189525.
Parameters:
-
command
Object -
[opts]
Object optional-
[sync]
Boolean optionaltrue to execute sync rather than async
-
[cwd]
String optionalCurrent working directory of the child process
-
[env]
Object optionalEnvironment key-value pairs
-
[encoding='utf8']
String optional -
[shell]
String optionalShell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
-
[timeout=0]
Number optional -
[maxBuffer=200*1024]
Number optionalLargest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed.
-
[killSignal='SIGTERM']
String optional -
[uid]
Number optionalSets the user identity of the process.
-
[gid]
Number optionalSets the group identity of the process.
-
-
next
Function-
err
Error -
stdout
Buffer | Stringout buffer
-
stderr
Buffer | Stringerror buffer
-
Returns:
{error, stdout, stderr}
getCountryCode
-
localeCode
Given the localeCode, return the country code.
Parameters:
-
localeCode
String
Returns:
getEnvironmentPaths
()
Array
Get the system's environment paths.
Returns:
string array of file paths
getExecPath
-
execName
-
[opts]
-
next
Given an executable name, search and find its actual path. Will search the standard file paths defined by the environment to see if the executable is in any of those paths.
Parameters:
-
execName
Object -
[opts]
Object optional-
[cache=true]
Boolean optional
-
-
next
Function-
err
Error -
foundPath
Stringpath to the executable
-
getGitPath
-
[opts]
-
next.err
-
next.gitPath
Path to the evironment's GIT directory. As 'git' is not always available in the environment path, we should check common path locations and if we find one that works, then we should use it.
Parameters:
-
[opts]
Object optional-
[cache=true]
Object optional
-
-
next.err
Error -
next.gitPath
String
getHomePath
-
[opts]
-
next
Get home path. Returns the user's home directory. Based upon home function from: https://github.com/isaacs/osenv
Parameters:
-
[opts]
Object optional-
[cache=true]
Object optional
-
-
next
Function-
err
Error -
homePath
String
-
getLanguageCode
-
localeCode
Given the localeCode, return the language code.
Parameters:
-
localeCode
String
Returns:
getLocaleCode
-
lang
Get locale code - eg: en-AU, fr-FR, zh-CN etc.
Parameters:
-
lang
String
Returns:
getNodePath
-
[opts]
-
next.err
-
next.nodePath
Path to the evironment's Node directory. As 'node' is not always available in the environment path, we should check common path locations and if we find one that works, then we should use it
Parameters:
-
[opts]
Object optional-
[cache=true]
Object optional
-
-
next.err
Error -
next.nodePath
String
getNpmPath
-
[opts]
-
next.err
-
next.npmPath
Path to the evironment's NPM directory. As 'npm' is not always available in the environment path, we should check common path locations and if we find one that works, then we should use it
Parameters:
-
[opts]
Object optional-
[cache=true]
Object optional
-
-
next.err
Error -
next.npmPath
String
getStandardExecPaths
-
execName
Get the possible paths for the passed executable using the standard environment paths. Basically, get a list of places to look for the executable. Makes allowances for Windows executables possibly needing an extension to ensure execution (.exe, .cmd, .bat).
Parameters:
-
execName
String
Returns:
string array of file paths
getStandardExecPaths
-
execName
Get the possible paths for the passed executable using the standard environment paths. Basically, get a list of places to look for the executable. Only safe for non-Windows systems.
Parameters:
-
execName
String
Returns:
string array of file paths
getTmpPath
-
[opts]
-
next.err
-
next.tmpPath
Path to the evironment's temporary directory. Based upon tmpdir function from: https://github.com/isaacs/osenv
Parameters:
-
[opts]
Object optional-
[cache=true]
Object optional
-
-
next.err
Error -
next.tmpPath
String
hasExecSync
()
Boolean
Has exec sync. Returns true if the child_process execSync method exists, otherwise false
Returns:
hasSpawnSync
()
Boolean
Has spawn sync. Returns true if the child_process spawnSync method exists, otherwise false
Returns:
initGitRepo
-
opts
-
next
Initialize a git Repository. Requires internet access.
Parameters:
-
opts
Object-
path
Stringpath to initiate local repository
-
[remote='origin']
String optional -
url
Stringurl to git remote repository
-
[branch='master']
String optional -
log
String -
output
String -
[cwd=process.cwd()]
String optionalCurrent working directory of the child process.
-
-
next
Function-
err
Error -
results
Arrayarray of spawn results
-
results[i].stdout
Streamout stream
-
results[i].stderr
Streamerror stream
-
results[i].status
Numbernode.js exit code
-
results[i].signal
Stringunix style signal such as SIGKILL or SIGHUP
-
initNodeModules
-
opts
-
next
Init Node Modules with cross platform support supports linux, heroku, osx, windows
Parameters:
-
opts
Object -
next
Function-
err
Object -
stdout
Streamout stream
-
stderr
Streamerror stream
-
status
Numbernode.js exit code
-
signal
Stringunix style signal such as SIGKILL or SIGHUP
-
initOrPullGitRepo
-
opts
-
next
Pull from a git repository if it already exists on the file system else initialize new Git repository. Requires internet access.
Parameters:
-
opts
Object-
path
Stringpath to local repository
-
[remote='origin']
String optional -
url
Stringurl to git remote repository
-
[branch='master']
String optional -
log
String -
output
String -
[cwd=process.cwd()]
String optionalCurrent working directory of the child process.
-
-
next
Function-
err
Error -
results
Arrayarray of spawn results
-
results[i].stdout
Streamout stream
-
results[i].stderr
Streamerror stream
-
results[i].status
Numbernode.js exit code
-
results[i].signal
Stringunix style signal such as SIGKILL or SIGHUP
-
isExecutable
-
path
-
[opts]
-
next
Is the path to a file object an executable? Boolean result returned as the isExecutable parameter of the passed callback. next(err, isExecutable)
Parameters:
-
path
Stringpath to test
-
[opts]
Object optional-
[sync]
Boolean optionaltrue to test sync rather than async
-
-
next
Functioncallback
-
err
Error -
isExecutable
Boolean
-
Returns:
returned if opts.sync = true
isExecutableSync
-
path
-
opts
-
[next]
Is the path to a file object an executable? Synchronised version of isExecutable
Parameters:
-
path
Stringpath to test
-
opts
Object -
[next]
Function optional-
err
Error -
isExecutable
Boolean
-
Returns:
isWindows
()
Boolean
Returns whether or not we are running on a windows machine
Returns:
openProcess
-
fn
Open a file. Pass your callback to fire when it is safe to open the process
Parameters:
-
fn
Functioncallback
outputData
-
data
-
[channel = 'stdout']
-
prefix
Internal: Set output data
Parameters:
-
data
Object -
[channel = 'stdout']
Object optional -
prefix
Object
prefixData
-
data
-
[prefix = '>\t']
Internal: prefix data
Parameters:
-
data
Object -
[prefix = '>\t']
String optional
Returns:
data
prepareExecutableOptions
-
[opts]
Internal: Prepare options for an execution. Makes sure all options are populated or exist and gives the opportunity to prepopulate some of those options.
Parameters:
-
[opts]
Object optional-
[stdin=null]
Stream optionalin stream
-
[stdio=null]
Array optionalChild's stdio configuration
-
[safe=true]
Boolean optional -
[env=process.env]
Object optional
-
Returns:
opts
spawn
-
command
-
[opts]
-
next
Wrapper around node's spawn command for a cleaner, more robust and powerful API. Launches a new process with the given command. Command line arguments are part of the command parameter (unlike the node.js spawn). Command can be an array of command line arguments or a command line string. Opts allows additional options to be sent to the spawning action.
Simple usage example:
var safeps = require('safeps');
var command = ['npm', 'install','jade','--save'];
//a lot of the time you won't need the opts argument
var opts = {
cwd: __dirname //this is actually pointless in a real application
}
function myCallback(error, stdout, stderr, status, signal){
console.log(error);
console.log(status);
console.log(signal);
console.log("I've finished...");
}
safeps.spawn(command, opts, myCallback);
Parameters:
-
command
Array | String -
[opts]
Object optional-
[safe]
Boolean optionalWhether to check the executable path.
-
[cwd]
String optionalCurrent working directory of the child process
-
[stdio]
Array | String optionalChild's stdio configuration.
-
[customFds]
Array optionalDeprecated File descriptors for the child to use for stdio.
-
[env]
Object optionalEnvironment key-value pairs.
-
[detached]
Boolean optionalThe child will be a process group leader.
-
[uid]
Number optionalSets the user identity of the process.
-
[gid]
Number optionalSets the group identity of the process.
-
-
next
Functioncallback
-
error
Error -
stdout
Streamout stream
-
stderr
Streamerror stream
-
status
Numbernode.js exit code
-
signal
Stringunix style signal such as SIGKILL or SIGHUP
-
spawnMultiple
-
commands
-
[opts]
-
next
Spawn multiple processes in the one method call. Launches new processes with the given array of commands. Each item in the commands array represents a command parameter sent to the safeps.spawn method, so each item can be a command line string or an array of command line inputs. It is also possible to pass a single command string and in this case calling spawnMultiple will be effectively the same as calling safeps.spawn.
Parameters:
-
commands
Array | String -
[opts]
Object optional-
[concurrency=1]
Boolean optionalWhether to spawn processes concurrently.
-
cwd
StringCurrent working directory of the child process.
-
stdio
Array | StringChild's stdio configuration.
-
customFds
ArrayDeprecated File descriptors for the child to use for stdio.
-
env
ObjectEnvironment key-value pairs.
-
detached
BooleanThe child will be a process group leader.
-
uid
NumberSets the user identity of the process.
-
gid
NumberSets the group identity of the process.
-
-
next
Functioncallback
-
error
Error -
results
Arrayarray of spawn results
-
results[i].stdout
Streamout stream
-
results[i].stderr
Streamerror stream
-
results[i].status
Numbernode.js exit code
-
results[i].signal
Stringunix style signal such as SIGKILL or SIGHUP
-
spawnNodeModule
-
name
-
args
-
opts
-
next
Spawn Node Modules with cross platform support supports linux, heroku, osx, windows spawnNodeModule(name:string, args:array, opts:object, next:function) Better than https://github.com/mafintosh/npm-execspawn as it uses safeps
Parameters:
-
name
String -
args
Array -
opts
Object-
name
Stringname of node module
-
[cwd=process.cwd()]
String optionalCurrent working directory of the child process.
-
-
next
Function-
err
Object -
stdout
Streamout stream
-
stderr
Streamerror stream
-
status
Numbernode.js exit code
-
signal
Stringunix style signal such as SIGKILL or SIGHUP
-
spawnSync
-
command
-
[opts]
-
[next]
Syncronised version of safeps.spawn. Will not return until the child process has fully closed. Results can be returned from the method call or via a passed callback. Even if a callback is passed to spawnSync, the method will still be syncronised with the child process and the callback will only return after the child process has closed.
Simple usage example:
var safeps = require('safeps');
var command = ['npm', 'install', 'jade', '--save'];
//a lot of the time you won't need the opts argument
var opts = {
cwd: __dirname //this is actually pointless in a real application
};
var result = safeps.spawnSync(command, opts);
console.log(result.error);
console.log(result.status);
console.log(result.signal);
console.log("I've finished...");
Parameters:
-
command
Array | String -
[opts]
Object optional-
[safe]
Boolean optionalWhether to check the executable path.
-
[cwd]
String optionalCurrent working directory of the child process
-
[stdio]
Array | String optionalChild's stdio configuration.
-
[customFds]
Array optionalDeprecated File descriptors for the child to use for stdio.
-
[env]
Object optionalEnvironment key-value pairs.
-
[detached]
Boolean optionalThe child will be a process group leader.
-
[uid]
Number optionalSets the user identity of the process.
-
[gid]
Number optionalSets the group identity of the process
-
-
[next]
Function optionalcallback
-
error
Error -
stdout
Streamout stream
-
stderr
Streamerror stream
-
status
Numbernode.js exit code
-
signal
Stringunix style signal such as SIGKILL or SIGHUP
-
Returns:
{error, pid, output, stdout, stderr, status, signal}
updateExecutableResult
-
result
-
[opts]
Internal: Prepare result of an execution
Parameters:
-
result
Object-
pid
ObjectNumber Pid of the child process
-
output
Objectoutput Array Array of results from stdio output
-
stdout
Streamstdout The contents of output
-
stderr
Streamstderr The contents of output
-
status
Numberstatus The exit code of the child process
-
signal
Stringsignal The signal used to kill the child process
-
error
ErrorThe error object if the child process failed or timed out
-
-
[opts]
Object optional-
[output]
Object optional -
[outputPrefix]
Object optional
-
Returns:
result
Properties
execPathCache
Unknown
private
Cache of executable paths


General Functionality
In this tutorial we will be adding some of the missing features for our todo application. They are as follows:
- Displaying the current username in the header.
- Render the Logout button only when appropriate (ie: not on the login page).
- Completing Todo entries.
- Marking all todo entries.
- Deleting Todo entries.
- Rendering the number of remaining todo entries.
- Clearing completed todo entries.
- Filtering the todo entries (complete, not-complete, all).
- Saving todo entries to localStorage.
- Loading todo entries from localStorage.
Header
Lets start by taking care of a couple of the more visible issues.
Firstly the persistent Logout button that is displayed in the header whether or not the user has 'logged in'. That button should only be visible when the user has actually logged in. Currently it is present on the login page as well...that does not make much sense does it?
And secondly we should display the current username to the user in the header, this is a general UX niceity which helps give the user context.
To add this functionality we will need to wrap that section (the header) with a viewModel so that we can bind against it for the logic we need. Lets do that now.
Add a <viewModel> wrapper for the header:

<viewModel module="Header">

</viewModel>

Now that the header is wrapped, we need to tell footwork where our Header module can be found.
Register the Header location with footwork:
// ...
/**
* Tell footwork it can find the 'LoginForm', 'TodoList', and 'Header' viewModels
* inside of scripts/viewModels.
*/
fw.viewModels.registerLocation([
'LoginForm', // will load from scripts/viewModels/LoginForm.js
'TodoList', // will load from scripts/viewModels/TodoList.js
'Header' // will load from scripts/viewModels/Header.js
], 'scripts/viewModels/');
// ...
And finally, we need to add the Header module that footwork will load for us when it encounters the corresponding markup in the DOM.
A bare Header viewModel module:
define(['footwork'],
function(fw) {
return fw.viewModel({
namespace: 'Header',
initialize: function() {
// ...
}
});
}
);
At this point, reloading the page will not visibly indicate much new is happening. From dev tools you might notice that the Header viewModel is now being downloaded and instantiated for our application...but no new behavior. Remember that our goal is to hide or display the Logout button based on whether or not the user has logged in.
Username Display
If our logic for displaying the Logout button needs to be housed in the Header viewModel (ie: what our markup for the header is binding against), then we need to somehow communicate or share the username/login information with it. An informed reader may be thinking: "just send a message or event/etc to the Header". And well, you aren't wrong...but there is a much cleaner way to share information and state between modules...using a broadcastable and receivable!
A broadcastable and receivable are simply special observables which share information amongst each other. broadcastables broadcast, or send out their information to any number of listening receivables. These variables are knockout observables at their core, and can be used just like any other observable. This means you can share state and properties between modules, still being able to bind/subscribe/etc to them (you can even still create computed values based on them which are automatically resolved for you like normal knockout computed observables).
Before we create our broadcastable and receivable we need to make the LoginForm add the username to the event it emits when a user is logging in.
Add the username to the triggered event emitted when a user is logging in:
// ...
this.loginUser = function() {
// Tell the MainRouter that a user has logged in (and provide the current username)
this.mainRouterNamespace.trigger('userLogin', this.username());
};
// ...
Now lets create a broadcastable inside the MainRouter, using it we will share (broadcast) the user state. Any receivable listening for that variable on the MainRouter namespace will be kept in sync automatically. To do this, we will use the .broadcastAs() method on the newly created loggedInUser property.
In addition to that we also need to alter the '/todo' route and append the username to it.
Create a broadcastable in the initialize method of the MainRouter which will share the current loggedInUser:
Also add the username to the '/todo' router .setState() call:
// ...
initialize: function() {
// Create reference to the router we will use in the callback
var router = this;
/**
* broadcast the username of the current user as 'loggedInUser'
* (the default value is null indicating 'logged out')
*/
this.loggedInUser = fw.observable(null).broadcastAs('loggedInUser');
// Create the event handler which receives the 'userLogin' event (and corresponding username)
this.$namespace.event.handler('userLogin', function(username) {
// Tell the router to route to '/todo/username' if we have a username
if(username) {
router.setState('/todo/' + username);
}
});
},
// ...
Now that the setState() call has the username being appended to the route string we need to modify the '/todo' route to also accept that parameter (the username) and set the loggedInUser property to the new value (which is then broadcasted). The '/' route also needs to reset the loggedInUser property back to null (user logged out state).
The following shows those necessary changes.
Alter the routes to alter the loggedInUser property appropriately:
// ...
routes: [
{
route: '/',
title: 'Todo Application Tutorial',
controller: function() {
// the user is logged out if at the default route, lets nullify the username
this.loggedInUser(null);
// show our login page here
this.$outlet('mainView', 'login-page');
}
},
{
route: '/todo/:username', // defines a required parameter 'username'
title: 'Todo List',
controller: function(username) {
// set the loggedInUser value to the username
this.loggedInUser(username);
// show our todo list page here
this.$outlet('mainView', 'todo-page');
}
}
]
// ...
Now the Header viewModel needs to listen for changes being broadcast for the loggedInUser. To do that we use the corresponding .receiveFrom() method on an observable (providing it the namespace and variable name to 'receiveFrom').
Create the receivable inside of the Header:
define(['footwork'],
function(fw) {
return fw.viewModel({
namespace: 'Header',
initialize: function() {
// loggedInUser will receive its value from the MainRouter
this.loggedInUser = fw.observable().receiveFrom('MainRouter', 'loggedInUser');
}
});
}
);
The previous block creates a new .loggedInUser receivable which will mirror the value of the loggedInUser value emitted from the MainRouter. This means any changes made in the MainRouter to the LoggedInUser will automatically propagate to this module and its value kept in sync.
The last thing we need to do for the username display is to add the markup (along with its binding) in the header to display it.
Add the markup to the header for the username display:

Things To Do...

And thats it, you should be able to refresh the page, login and see the username in the header.
Logout Rendering
Now that the loggedInUser value is being received from the MainRouter we can create some logic and bindings based on it to get the behavior we need. Lets add a binding in our markup for it which will control when the Login button is displayed. In this example we are using an if: binding, although there are many other control-flow bindings available.
While we are at it, we will use that same loggedInUser property to display the current logged in username on the page by binding its value using a text: binding.
Display the receivable username:

<viewModel module="Header">

Things To Do...

Logout

</viewModel>

Todo List
In this final series of steps we will be adding some functionality around the todo items. Specifically we will cover:
- Completing TodoItem entries.
- Marking all TodoItem entries as complete.
- Deleting TodoItem entries from the list.
Completing a Todo
To 'complete' a todo we simply need to wire up a couple bindings to the TodoItem viewModel. One for the click event on the check mark (to toggle its status). And one more which will add a class to the todo container indicating its completion state (which is used to style the TodoItem).
Lets add the logic to our TodoItem viewModel so that we can then add the binding in the markup.
Add the logic necessary for the bindings we need in the DOM:
// ...
initialize: function(thingToDo) {
// store the string text entered by user as thingToDo
this.thingToDo = fw.observable(thingToDo);
// store the state of the TodoItem (true = done, false = not done)
this.isDone = fw.observable(false);
// toggle the state of this TodoItem
this.toggleDone = function() {
this.isDone(!this.isDone());
};
}
// ...
The previous code block shows the addition of a .isDone property which will store the current state of the TodoItem as well as a new .toggleDone() method which will toggle the current state.
Now that the logic is in the viewModel lets add the declarative binding in the markup.
Add the css: and click: bindings necessary to wire up the viewModel:

And thats it...refresh the page, login and you should be able to create a TodoItem which you can then click to complete. It should look something like the following:
Marking All Todos as Complete / Not-Complete
Now that we can mark a single TodoItem as being completed, lets add the 'mark all as completed/non-completed' functionality. To do this we will use a click: binding which sends a command to the TodoList which will then set each TodoItem entry state to a certain value.
The click event will occur on the .icon-chevron-down element, which exists in the template for the TodoForm component. Lets add the markup for that binding now.
Add the binding to the markup for the 'set-all' functionality:
<form class="todo" data-bind="submit: submitForm">

<input type="text" name="thingToDo" data-bind="value: thingToDo" placeholder="What needs to be done?"  The css: binding simply is used to control how the chevron (button) looks depending on whether or not we have 'marked all' or 'mark none' of the TodoItem entries.
With the bindings now in our markup we can add the necessary logic to our TodoForm.
Add the logic necessary for the new click: and css: bindings:
// ...
// holds flag which indicates whether we have 'marked all' or 'mark none' of the items
this.allMarked = fw.observable(false);
// event triggered when user clicks the down-chevron icon
this.markAll = function() {
this.allMarked( !this.allMarked() );
};
// Listen for changes on the allMarked value
this.allMarked.subscribe(function(doneState) {
// When a change is made command the TodoList to setAllAs the doneState
this.todoListNamespace.command('setAllAs', doneState);
}, this);
// ...
The one thing of special note here is the command being issued on the todoListNamespace, this is simply another type of message (a command) being utilized which is sent to any listening command handlers on the TodoList.
Now that we are sending out the setAllAs command from the TodoForm we need to setup the handler on the other side which will listen for and act on it. The list of TodoItem entries exists on the TodoList so we should setup our handler there.
When we receive the command we will need to mark all of the entries as the received value, lets add the code for that now.
Add the command handler which acts on any received setAllAs command:
// ...
var self = this; // create a reference to this viewModel we can use inside of the callback
// stores the list of TodoItem entries
this.todos = fw.observableArray();
// listen for any 'newItem' messages broadcast on our namespace.
this.$namespace.subscribe('newItem', function(thingToDo) {
// new thingToDo was received, lets create a new TodoItem based on it
self.todos.push( new TodoItem(thingToDo) );
});
// listen for any 'setAllAs' commands broadcast on our namespace.
this.$namespace.command.handler('setAllAs', function(doneState) {
// when a new doneState is received loop through and set each todo
self.todos().forEach(function(todo) {
todo.isDone(doneState);
});
});
// ...
The previous block of code creates a new command handler which listens for any setAllAs commands. When such a command is received the handler will loop over the current list of todos setting each .isDone property to the specified doneState value.
Deleting a Todo
Another obviously missing feature is the ability to erase/delete a todo. The logic for this feature will be contained within each individual TodoItem. Whenever a user clicks the 'X' we need to send a command to the TodoList telling it to delete this TodoItem (very similar in nature to the 'mark all' feature we just completed in the previous step).
Lets go ahead and add the click: binding we need for the 'X' in our markup.
Add the click: binding to the todo item:

Now that the binding is in place, we need to create the logic in the viewModel it is bound against. In this case, that is the TodoItem, lets add the necessary deleteItem method/logic to it now. Much like in the previous step when we were sending a command to mark/not mark all todo entries, in this method we will be sending a similar command. This one however will pass a reference to this TodoItem which will be used by the TodoList to remove this todo entry.
Create the deleteItem method, using it to pass a reference to this todo:
// ...
initialize: function(thingToDo) {
// create the namespace 'channel' we will use to talk to the TodoList
this.todoListNamespace = fw.namespace('TodoList');
// store the string text entered by user as thingToDo
this.thingToDo = fw.observable(thingToDo);
// store the state of the TodoItem (true = done, false = not done)
this.isDone = fw.observable(false);
// toggle the state of this TodoItem
this.toggleDone = function() {
this.isDone(!this.isDone());
};
// method used to send the deleteItem command when a user clicks the 'X'
this.deleteItem = function() {
// tell the TodoList to delete this item
this.todoListNamespace.command('deleteItem', this);
};
}
// ...
You will notice that just like in the previous step we used a todoListNamespace channel to (in this case) issue the 'deleteItem' command (from the deleteItem() method/event) passing it a reference to this.
Now we write the handler of the 'deleteItem' command inside of the TodoList.
Create the handler for the 'deleteItem' command:
// ...
// listen for any 'deleteItem' commands broadcast on our namespace.
this.$namespace.command.handler('deleteItem', function(item) {
// when a new deleteItem command is received delete it from the list of todos
self.todos.remove(item);
});
// ...
Once the handler on the other side receives the command it will then delete that entry from the todos observable array...which then is automatically removed from the DOM.
And thats it...you should now be able to create and delete todo item entries to your hearts content!
Footer
In this section we will add a few features which will be contained within the 'footer' of our application. These features are the following:
- Render the number of todos remaining to be completed.
- Clearing all completed todos.
- Filtering the todo list (all/active/completed).
Lets begin by adding the actual footer element with the markup for the viewModel wrapper.
Add the footer element and the <viewModel> wrapper:

<viewModel module="Footer">

</viewModel>
Now we need to add the Footer module and tell footwork where it can find it.
Create a basic Footer module:
define(['footwork'],
function(fw) {
return fw.viewModel({
namespace: 'Footer',
initialize: function() {
// ...
}
});
}
);
Tell footwork where it can find the Footer module:
// ...
/**
* Tell footwork it can find the 'LoginForm', 'TodoList', 'Header' and
* 'Footer' viewModels inside of scripts/viewModels/
*/
fw.viewModels.registerLocation([
'LoginForm', // will load from scripts/viewModels/LoginForm.js
'TodoList', // will load from scripts/viewModels/TodoList.js
'Header', // will load from scripts/viewModels/Header.js
'Footer' // will load from scripts/viewModels/Footer.js
], 'scripts/viewModels/');
// ...
Thats all we needed for the base structure of the footer. Reloading the page won't net any visible change at the moment. You may notice the Footer module being downloaded in dev tools...but no behavior and nothing visible just yet.
Render Number of Todos Left
Now that we have the basic structure for the footer we can begin adding behavior and display elements.
First on the list is adding a count of the todo items that have not yet been completed. To do this we need to do a few things:
- Add the HTML markup (with binding) to display the number in the footer.
- Create a receivable on the Footer which will receive the number of remaining todo items from the TodoList.
- Create a broadcastable in the TodoList which will broadcast the number of remaining todo items to the Footer.
- Create a method on the TodoList which will compute the number of remaining todo items (which is then broadcast to the Footer).
- In the TodoList, add subscriptions and handlers onto messages and commands which trigger an update/refresh of the number of remaining todo items when appropriate.
- Publish a message to the TodoList whenever an individual todo entry state changes (so that it can recalculate the number of remaining todo entries correctly).
Lets begin by adding the markup in the footer that we need to display the number of remaining todo entries.
Add the markup to display the number:

<viewModel module="Footer">

 items left

</viewModel>
Now we create the receivable in the Footer that will receive the number of remaining todo items from the TodoList. It is also what we are binding against in the UI to display the number.
Create the numRemainingTodos receivable:
// ...
initialize: function() {
// numRemainingTodo will receive its value from the TodoList
this.numRemainingTodos = fw.observable().receiveFrom('TodoList', 'numRemainingTodos');
}
// ...
Next we need to create the other side of the equation, the broadcastable which will live inside of the TodoList that tells (broadcasts to) the Footer how many remaining todo entries are left.
Create the numRemainingTodos broadcastable:
// ...
// broadcasts the number of remaining todos
this.numRemainingTodos = fw.observable(0).broadcastAs('numRemainingTodos');
// ...
Next we need to create a function which will compute the number of remaining todo items and write the result to numRemainingTodo (which will then be broadcast to the Footer).
Create the method which computes the number of remaining todo items and write the result to numRemainingTodos:
// ...
// This method computes the number of remaining todos
function computeRemainingTodos() {
// Loop over each todo and count the number that are !isDone().
var numRemaining = 0;
self.todos().forEach(function(todo) {
if(!todo.isDone()) {
numRemaining++;
}
});
// write the number of remaining todos to the numRemainingTodos broadcastable
self.numRemainingTodos(numRemaining);
}
// ...
Now that we have the method we need to compute the number of todo items left we need to trigger it when anything about the todos list changes. To do that we will simply add a few more subscriptions and handlers which will take care of this for us.
Add the necessary subscriptions and handlers which will update the numRemainingTodos:
// ...
// listen for any messages/commands which require us to compute the remaining todos.
this.$namespace.subscribe('itemChanged', computeRemainingTodos);
this.$namespace.subscribe('newItem', computeRemainingTodos);
this.$namespace.command.handler('setAllAs', computeRemainingTodos);
this.$namespace.command.handler('deleteItem', computeRemainingTodos);
// ...
As you can see we added additional handlers and subscriptions which call our new computeRemainingTodos method when needed (ie: when something changes that requires updating/refreshing the value).
One thing you might be curious about is the 'itemChanged' subscription. It is new, we haven't yet created anything which triggers that message. One of the missing features we haven't covered, is recomputing the number of remaining todo entries whenever a single one has its state changed (ie: when a user clicks the check mark on one of them). To do this we will use/trigger the 'itemChanged' message from each TodoItem when it has its isDone state changed (so that the computeRemainingTodos handler can then recompute the number of remaining todo entries). Lets do that now.
Add a subscription to the isDone property which fires off an 'itemChanged' event to the TodoList:
// ...
// Listen for any changes on the TodoItem isDone state
this.isDone.subscribe(function() {
// when it is changed publish an 'itemChanged' event to the TodoList
this.todoListNamespace.publish('itemChanged');
}, this);
// ...
Now when a state change is made to any TodoItem it will publish a message to the TodoList. This will trigger the subscription handler on the other side, which then (re)calculates the current number of outstanding TodoItem entries remaining. It updates the numRemainingTodos on the TodoList which is then broadcast to the Footer whose bound markup then automatically updates the UI.
And that should take care of what we need. Reload the page, login, add a todo and check it off...you should see the 'items left' value in the footer update as appropriate!
Clearing Completed Todos
Next on the list is adding a button into the footer which will let a user clear all of the currently 'completed' todo entries. Doing this is relatively simple, we just need to create the button in the footer and send a message to the TodoList telling it to remove all of the completed TodoItem entries that are completed.
Lets begin by creating the markup for the button in the footer.
Add the HTML for the button in the footer (including the click binding):

 items left

<button class="button" data-bind="click: clearCompleted">Clear Completed</button>

With the binding in the markup we now need to create the method our new button will bind against. This method will use a namespace channel to issue another command, this time telling the TodoList to clear/erase the currently completed todo entries.
Create the needed namespace channel and add the clearCompleted() method which issues the command:
// ...
initialize: function() {
// create the namespace 'channel' we will use to talk to the TodoList
this.todoListNamespace = fw.namespace('TodoList');
// numRemainingTodos will receive its value from the TodoList
this.numRemainingTodos = fw.observable().receiveFrom('TodoList', 'numRemainingTodos');
// method which sends the command to clear all completed todos
this.clearCompleted = function() {
// tell the TodoList to clear the completed todo entries
this.todoListNamespace.command('clearCompleted');
};
}
// ...
Now we need to create the handler for the 'clearCompleted' command. This handler will loop through the list of TodoItem entries, removing each one which is completed.
Add the handler which removes the complete todo entries:
// ...
// listen for any 'clearCompleted' commands broadcast on our namespace.
this.$namespace.command.handler('clearCompleted', function() {
// Create a list of the completed todos
var completedTodos = [];
self.todos().forEach(function(todo) {
if(todo.isDone()) {
completedTodos.push(todo);
}
});
// remove the completed todo entries
completedTodos.forEach(function(todo) {
todo.deleteItem();
});
});
// ...
And thats it...reload the page and you should now be able to remove all completed todo entries with the button on the right side of the footer!
Filtering the List
Next, lets add some filtering options to the todo list. It would be nice to be able to filter the list according to their completion state (all/active/completed).
To do this we will add a second (but optional) parameter to our '/todo/:username' route and use it in tandem with another broadcastable to tell the TodoList how to filter its list. Lets start by adding the broadcastable to the MainRouter.
Add the ListFilter property on the MainRouter:
// ...
// broadcast the state we wish to filter the list for
this.listFilter = fw.observable(null).broadcastAs('listFilter');
// ...
With that added to the initialize: method we now need to alter our route to accept the optional state parameter. In the controller we will use this optional parameter to set the value of the listFilter (which in a moment we will receive inside the TodoList and use it to apply the specified filter).
Add the optional :state parameter and apply it to the listFilter:
// ...
{
route: '/todo/:username(/:state)', // required parameter 'username', optional parameter 'state'
title: 'Todo List',
controller: function(username, state) {
// set the loggedInUser value to the username
this.loggedInUser(username);
// set the listFilter value to the supplied state (will be broadcast to the TodoList)
this.listFilter(state || 'all');
// show our todo list page here
this.$outlet('mainView', 'todo-page');
}
}
// ...
As you can see above we add the optional parameter using the (:/state) syntax. Further down inside of the controller: the listFilter is being assigned its value (with 'all' as the default).
One final thing we need to do to the MainRouter, make it choose a 'default' filter option upon user login.
Add the default filter option to the 'userLogin' handler:
// ...
if(username) {
router.setState('/todo/' + username + '/all');
}
// ...
Now when a user logs in they will be directed to '/todo/username/all'. In order to allow the user to choose a different filter option we will need to add the appropriate $route bindings to a few links in the footer, lets create those now.
Add the $route bound links to the footer to trigger the new filter state when clicked:

 items left

all
active
completed

<button class="button" data-bind="click: clearCompleted">Clear Completed</button>

The three $route bindings will trigger their designated route on the MainRouter (their parent router) when clicked. One new thing you may have noticed here is the { url: allRoute } syntax defined on the binding. This option essentially tells footwork to resolve the url: for the link using the allRoute method on the viewModel it is bound against. Given where those callback methods (allRoute, activeRoute, and completedRoute) are declared we need to define their corresponding methods inside of the Footer.
The reason we are defining the url: as callbacks is because we need to create a url/route with a profile like '/todo/[username]/[filter option]'. There is no way to do that with a simple string value (thus it needs to be created in a callback).
Lets create the three different callback methods we need to allow the $route bindings we have defined to correctly construct their route definitions.
Create the callbacks needed for the $route bindings on the Footer:
// ...
initialize: function() {
// ...
// loggedInUser will receive its value from the MainRouter
this.loggedInUser = fw.observable().receiveFrom('MainRouter', 'loggedInUser');
// the callbacks which return the needed filter routes
this.allRoute = function() {
return '/todo/' + this.loggedInUser() + '/all';
}.bind(this);
this.activeRoute = function() {
return '/todo/' + this.loggedInUser() + '/active';
}.bind(this);
this.completedRoute = function() {
return '/todo/' + this.loggedInUser() + '/completed';
}.bind(this);
// ...
}
// ...
Something you may also notice here is the receivable defined at the top. Just as with the other receivable properties we've created it will receive any updates for its value from the designated viewModel. In this case the loggedInUser will receive its value from the MainRouter. Using that value we construct the routes we need for the allRoute, activeRoute, and completedRoute
Now that we have our links/handlers/etc in place lets create the filtered list. Knockout (and thus, footwork as well) has what are called computed values. These are special values which depend on other observables for their result. Anytime a dependency of a computed changes the value is re-evaluated automatically.
Lets create a computed value based on the listFilter value we are broadcasting from the MainRouter.
Add the listFilter receivable and filteredTodos computed:
// ...
// receives the list filter value from the MainRouter
this.listFilter = fw.observable().receiveFrom('MainRouter', 'listFilter');
// filter the list of todo entries based on this.listFilter received from MainRouter
this.filteredTodos = fw.computed(function() {
var listFilter = this.listFilter();
var todoList = [];
// go through each todo entry and add it to the filtered todoList if appropriate
this.todos().forEach(function(todo) {
switch(listFilter) {
case 'active': // show only 'active' todo entries
if(!todo.isDone()) {
todoList.push(todo);
}
break;
case 'completed': // show only 'completed' todo entries
if(todo.isDone()) {
todoList.push(todo);
}
break;
default: // show all todo entries (no filter)
todoList.push(todo);
break;
}
});
// return the filtered todoList entries
return todoList;
}, this);
// ...
So what is happening here? Well the listFilter is receiving its value from the MainRouter. That value is then referenced inside of a computed observable which uses it to determine how to filter the current list of todos. The todos are iterated over and the filtered list is created and returned.
This gets us our filtered list...but the UI won't display it just yet. We have one small step remaining...in our markup we just swap out the current binding for the todos list with our new filteredTodos list.
Swap the todos reference in the foreach: binding with our new filteredTodos computed value.

And that should be all we need for this feature. Reload the page, login, and play around with the list...it should update and be filtered as you would expect.
Preserving / Saving the List
The final features we will be covering in this tutorial is the saving and loading of the todo list. This will enable each user to preserve their todo list locally on the machine so that when they refresh or come back at a later time the list they made is still there.
Saving
Each TodoItem is an individual object responsible for its own data. We should extend that concept to include the saving, updating, and removal of itself as well.
Since each TodoItem is an individual record of something we should add a unique identifier so that we can also retrieve and identify it from localStorage at a later time as well. We will need to generate that unique identifier because the TodoItem currently has no such property.
To do this we will create a composite key consisting of our loggedInUser (the username) + the guid. This will give our keys a format of <username>-########-####-####-####-############. The username being present at the start of the key is significant (and necessary) as you will see further on.
So to begin with, lets create the composite guid.
Create the loggedInUser receiveable and use it to create a composite guid:
// ...
initialize: function(thingToDo) {
// get the username from the MainRouter so we can use it in the GUID
var loggedInUser = fw.observable().receiveFrom('MainRouter', 'loggedInUser');
// use existing GUID or generate a random one
var guid = thingToDo.guid || (loggedInUser() + '-' + fw.utils.guid());
// ...
Next we need to create the method which will actually do the saving of our TodoItem to localStorage. Lets do that now.
Create the saveItem() method which saves the todo to localStorage:
// ...
this.saveItem = function() {
// save the todo item using the username-based GUID as its key
localStorage.setItem(guid, JSON.stringify({
guid: guid,
thingToDo: this.thingToDo(),
isDone: this.isDone()
}));
};
// ...
Each time this method is called the TodoItem will be saved to localStorage using the composite guid we created before (this will help us when we go to find it later). The data itself is encoded into a string using JSON.stringify. This lets us store the todo and its details in a readily usable form when we read it later (although we will have to decode it back into an object first).
Now that we have our saveItem() method defined lets put it to use. We know that every time a todo is changed we need to update localStorage. Turns out we already have a subscription to changes on that value, lets add our new callback to it.
Add the saveItem() call to the isDone subscription:
// ...
// Listen for any changes on the TodoItem isDone state
this.isDone.subscribe(function() {
// when it is changed publish an 'itemChanged' event to the TodoList
this.todoListNamespace.publish('itemChanged');
// the value changed so we save the todo again
this.saveItem();
}, this);
// ...
Now every time the state of the TodoItem changes it will be saved to localStorage.
We also need the TodoItem to delete itself whenever it is removed so lets add the code to do that in the deleteItem() method. Since we use the guid as its key when writing, we can also use that same value to delete it.
Delete the TodoItem using its own guid inside the deleteItem() method:
// ...
// method used to send the deleteItem command when a user clicks the 'X'
this.deleteItem = function() {
// tell the TodoList to delete this item
this.todoListNamespace.command('deleteItem', this);
// delete this item from localStorage also
localStorage.removeItem(guid);
};
// ...
Another thing we need to change in the TodoItem viewModel is how it loads its data. As noted above we are storing the data for this todo in a JSON format (which is really just a serialized javascript object). When we load the data back in (ie: when the user loads the page) we will be getting back a javascript object...the constructor of our TodoItem needs to be modified to handle this.
Modify the TodoItem to read its initial values from an object being passed in (rather than a string as before):
// ...
// store the string text entered by user as thingToDo
this.thingToDo = fw.observable(thingToDo.thingToDo);
// store the state of the TodoItem (true = done, false = not done)
this.isDone = fw.observable(thingToDo.isDone);
// ...
One more thing we need to do to the TodoItem is have it save the todo when it is first create by the user. To do that we will look at the data passed into the constructor. If the object has a provided guid then it is being loaded from a previous entry. If it does not it is a new entry and we will save it.
Add the call to save the todo entry when it is initially created:
// ...
if(!thingToDo.guid) {
// the data object as no guid, it is new so lets save it to localStorage
this.saveItem();
}
// ...
And lastly, we need to modify how new entries that are typed in are provided to the constructor of the TodoItem. Since those are created in the TodoList that is where we need to make the alteration.
Alter the TodoList to create new TodoItem instances using the new object format:
// ...
// listen for any 'newItem' messages broadcast on our namespace.
this.$namespace.subscribe('newItem', function(thingToDo) {
// new thingToDo was received, lets create a new TodoItem based on it
self.todos.push( new TodoItem({ thingToDo: thingToDo }) );
});
// ...
And thats it, every TodoItem created will now be saved to localStorage.
Loading
And finally, the last feature we will be adding in this tutorial is the ability for the application to essentially 'hydrate' itself, loading in the list of previously entered todo entries based on what user has logged in.
We mostly have everything setup we needed from the previous step. To read the existing todo entries from localStorage we will need to loop over all entries found, look at each key to determine if it is part of our users todo list, and if so - create a new TodoItem based off of it.
If you recall from above, the keys we wrote to localStorage are a composite made up of the loggedInUser and a random portion that footwork creates for us. We can utilize the first portion, compare it to the currently logged in user and grep out only those entries that are relevant to this user.
Add the code to import pre-existing todo entries found in localStorage:
// ...
// loggedInUser will receive its value from the MainRouter, we use it to filter localStorage
var loggedInUser = fw.observable().receiveFrom('MainRouter', 'loggedInUser');
// loop over all localStorage entries and import only our users todo entries
for(var keyNum = 0; keyNum < localStorage.length; keyNum++) {
var key = localStorage.key(keyNum);
// we only want to add todos that belong to this user so we check here
if(loggedInUser() === key.substr(0, loggedInUser().length)) {
/**
* The key starts with our loggedInUser so we add a new TodoItem using its value
* which we read and parse from localStorage
*/
this.todos.push( new TodoItem( JSON.parse(localStorage.getItem(key)) ) );
}
}
// since we may have new entries we need to (re)compute the number of remaining todos
computeRemainingTodos();
// ...
And thats it...now all todo entries will be preserved on a per-user basis and reloaded each time they log in or load the page!
We have now covered most of the major sections of footwork in the persuit of creating a todo application. Note that this tutorial series did not cover saving to a server, footwork as of yet does not have native/included support for RESTful endpoints and AJAX. This is coming soon! Until then, libraries such as jQuery or (for something lightweight) reqwest work great in with footwork.
There are of course improvements and additional features not mentioned here which can also be created...so go off into the great unknown, experiment and try it out!


{% comment %} This subcategory assumes that the first questiongroup contains a image checkbox question where each conditionally opens a new questiongroup. The questiongroups not appearing part of the conditions are rendered normally. For this reason, the following configurations in "form_options" need to be set: - questiongroup_conditions: Must correspond to the list of "questiongroup_conditions" set in the "form_options" of the first key of the first questiongroup. {% endcomment %} {% load i18n %} {% load floppyforms %} {% load list_to_columns %} {% if config.next_level == 'subcategories' %}
{{ config.label }}
{% for sub_config, sub_formsets in formsets %} {% form form using sub_config.form_template with config=sub_config formsets=sub_formsets %} {% endfor %} {% else %} {% endif %}


I am a first year PhD student in the IEOR department at Columbia. Previously I studied Electrical Engineering at UCLA.


Add KeyTerms to Question
Category
Question (en)
Question (ru)
Edit Question
Add New Answer
Key Terms
Select
Name
Description
Save Selected KeyTerms
Add New Key Term


Posting of expressions and relations
[Direct modelling]
Functions | |
| template<class Var> | |
| IntVar | Gecode::post (Space *home, const MiniModel::LinExpr< Var > &e, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post linear expression and return its value. | |
| IntVar | Gecode::post (Space *home, const IntVar &x, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post linear expression (special case for integer variable) and return its value. | |
| IntVar | Gecode::post (Space *home, int n, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post linear expression (special case for constant) and return its value. | |
| template<class Var> | |
| void | Gecode::post (Space *home, const MiniModel::LinRel< Var > &r, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post linear relation. | |
| void | Gecode::post (Space *home, bool r, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Make it work for special integer only-case. | |
| BoolVar | Gecode::post (Space *home, const MiniModel::BoolExpr &e, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post Boolean expression and return its value. | |
| BoolVar | Gecode::post (Space *home, const BoolVar &b, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post Boolean expression (special case for variable) and return its value. | |
| void | Gecode::post (Space *home, const MiniModel::BoolRel &r, IntConLevel icl=ICL_DEF, PropKind pk=PK_DEF) |
| Post Boolean relation. |
Function Documentation
template<class Var>
| IntVar Gecode::post | ( | Space * | home, | |
| const MiniModel::LinExpr< Var > & | e, | |||
| IntConLevel | icl, | |||
| PropKind | pk | |||
| ) | [inline] |
| IntVar Gecode::post | ( | Space * | , | |
| const IntVar & | x, | |||
| IntConLevel | , | |||
| PropKind | ||||
| ) | [inline] |
Post linear expression (special case for integer variable) and return its value.
Definition at line 352 of file lin-expr.icc.
| IntVar Gecode::post | ( | Space * | home, | |
| int | n, | |||
| IntConLevel | , | |||
| PropKind | ||||
| ) | [inline] |
Post linear expression (special case for constant) and return its value.
Definition at line 357 of file lin-expr.icc.
template<class Var>
| void Gecode::post | ( | Space * | home, | |
| const MiniModel::LinRel< Var > & | r, | |||
| IntConLevel | icl, | |||
| PropKind | pk | |||
| ) | [inline] |
| void Gecode::post | ( | Space * | home, | |
| bool | r, | |||
| IntConLevel | , | |||
| PropKind | ||||
| ) | [inline] |
| BoolVar Gecode::post | ( | Space * | home, | |
| const MiniModel::BoolExpr & | e, | |||
| IntConLevel | icl, | |||
| PropKind | pk | |||
| ) | [inline] |
| BoolVar Gecode::post | ( | Space * | , | |
| const BoolVar & | b, | |||
| IntConLevel | , | |||
| PropKind | ||||
| ) | [inline] |
Post Boolean expression (special case for variable) and return its value.
Definition at line 124 of file bool-expr.icc.
| void Gecode::post | ( | Space * | home, | |
| const MiniModel::BoolRel & | r, | |||
| IntConLevel | icl, | |||
| PropKind | pk | |||
| ) | [inline] |


B—Have you a horse?
E—I have a horse.
B—This horse you have, has it been known to suffer from some common ailments of the horse?
E—A horse I have. A knowledge of horse health I have not.
B—Better put “horse ill-health” than “horse health”. Lack of horse ailment knowledge would suggest you know not of spavins, sweeney, ringbone, windgalls, poll evil, callous, cracked heels, galls of all kinds, fresh wounds, sprains, bruises, fistula, sitfast, sand cracks, strains, lameness, foundered feet, scratches or grease, mange, rheumatism, bites of animals, external poisons, painful nervous affections, frost bites, boils, corns, whitlows, burns and scalds, chilblains, chapped hands, cramps, contraction of the muscles, swellings, weakness of the joints, caked breast, &c.
E—I know them not but find it hard to credit they are all ailments of horse.
B—They are indeed not entirely those of the horse, but of that no matter. My point is that by making purchase of Geo. W. Merchant's Celebrated Gargling Oil, unparalleled in the history of medicine as the most remarkable external application ever discovered for horses and human flesh, you will cure your horse of all the specified ailments.
E—I shall make such purchase without further ado.
Hooting Yard is indebted to Odd Ends.


I used to work at Horizon Air before continuing with higher education. After acquiring my BA, I got an internship working at the Port of Seattle, and then was hired full-time. I work there currently.


Get personal one-on-one help from Apple expert John Geleynse on user interface design, accessibility, app review, marketing, analytics, app distribution, and more. You may request a consultation online starting at 7 am PDT for that day.


[gecode-users] Re: gecode-users Digest, Vol 21, Issue 9
Ivan Carvajal
peliculasivan at gmail.com
Tue Jun 19 02:32:36 CEST 2007
Hello.
Hello, ¿Hablas español? Si es asi avisa para poder responderte mejor.
I am new in this subject and beginning to use Gecode/J. I need to make
> searches step by step to know the domains of the variables and to give
> statistics as it advances the resolution of the CSP.
>
In addition I require
> to change the branching strategy during the execution. Is possible to make
> this? I must make my own search engine? What things I must consider to get
> this?
> thanks for its aid
> sorry by the bad english
You can implement you own branching strategy, look the QueensJavaPropagator
java's example, here implement a custom branching, defining a branching
class, and in this branching class you can know the domain of each variable.
Francisco Olmedo
Ivan Carvajal
--
...:::PAU TE AMO:::...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.ps.uni-sb.de/pipermail/users/attachments/20070618/3ab5b3c9/attachment.htm>
More information about the gecode-users
mailing list


'Best chance' - Nottingham Forest tipped to maintain promotion push by former Reds coach
Sabri Lamouchi's side are currently fifth in the Championship table
by Sarah ClapsonFormer caretaker boss Ian “Charlie” McParland says Nottingham Forest have “the best chance they’ve had for years” of reaching the Premier League.
It has been a fine start to the season for the Reds under Sabri Lamouchi.
With 15 games of the campaign gone, they sit fifth in the table, five points behind leaders West Bromwich Albion and with a game in hand.
They have been beaten just three times in the league, having bounced back from successive defeats after the last international break with wins at Luton Town and at home to arch-rivals Derby County.
The only time they have failed to score in the Championship was in their 1-0 reverse to Wigan Athletic.
And McParland says Forest's ability to keep finding the back of the net can be key to their bid to clinch promotion.
“Most of the games they’ve scored one goal,” McParland told Notts TV.
“Even when they are getting beat 1-0, you think they are going to nick a goal. Or if it’s 0-0, they are capable of nicking a goal.
“At the start of the season, I said we’d need to see how it pans out, but maybe seventh or sixth position - just getting in the play-offs slightly.
“But after having a look at all the teams and watching the games, I’m thinking this is the best chance they’ve had for years of going up. And if they don’t go up this year, I think it’s a failure."
Nottingham Forest latest
This is your round up of all things Forest; the one-stop shop that will keep you updated on the latest goings on at the City Ground and beyond.
Transfers, injuries, match-days and managers, we’ve got you covered.
We’ll be bringing the very latest on the Reds throughout the week and around the clock.
Make sure you keep yourself updated with our handy daily catch up...
Must reads...
- Championship is 'there for the taking'
- Was Lamouchi appointment a 'stroke of genius'?
- Leeds star's interesting claim about City Ground
- How Reds players rate for season so far
For all your latest NFFC news, opinion, analysis and transfer gossip, click here
You can follow our Reds reporter Sarah Clapson on Twitter, and her email address is<EMAIL_ADDRESS>Sign up for our free Forest WhatsApp service for latest news
Keep up to date with the latest Nottingham Forest news, features and exclusives from Nottinghamshire Live via our free WhatsApp service.
Text NEWS to<PHONE_NUMBER>2 and then add the number to your phone contacts book as ForestLive to receive daily updates and breaking news from our Reds reporter Sarah Clapson.
Your phone number won't be shared with any other members of the group. Click here for more information on the service.


About Us¶
About eQuilibrator¶
eQuilibrator is a simple web interface designed to enable easy thermodynamic analysis of biochemical systems. eQuilibrator enables free-text search for biochemical compounds and reactions and provides thermodynamic estimates for both in a variety of conditions. Estimation of thermodynamic parameters (ΔrG and ΔfG) elucidates how much energy is required to drive a particular biochemical reaction and in which direction the reaction will flow in particular cellular conditions [1] [2].
Because experimental measurement of the free energy of formation (ΔfG°) of compounds is technically challenging, the vast majority of known metabolites have not been thermodynamically characterized. eQuilibrator uses a well-studied approximation of ΔfG called group contribution [3] [4] [5], enabling thermodynamic analysis of many biochemical reactions and pathways.
Currently, eQuilibrator can provide estimates for many compounds in the KEGG database [7] (about 4500). Individual compounds and enzymes can be searched for by their common names (“water”, “glucosamine”, “hexokinase”), and reactions can be entered in a simple, free-text format (“ribulose bisphosphate + CO2 + water => 2 3-phosphoglycerate”) that eQuilibrator parses automatically. eQuilibrator also allows manipulation of the conditions of a reaction - pH, ionic strength, and reactant and product concentrations - to help explore the thermodynamic landscape of a biochemical reaction.
eQuilibrator is a project of the Milo Lab at the Weizmann Institute in Rehovot, Israel. If you have any thoughts or questions feel free to write us on the eQuilibrator Users Google Group
Implementation of eQuilibrator¶
eQuilibrator makes heavy use of open source libraries and frameworks and is open-source itself. You can find the eQuilibrator source code on our GitHub repository called equilibrator.
The eQuilibrator back-end is implemented in pure Python using the Django web framework and several other open-source Python libraries, including NumPy and Pyparsing. The eQuilibrator user-interface is implemented using HTML, CSS and the jQuery Javascript framework.
All thermodynamic data presented by eQuilibrator was generated using the Component Contribution method [DOI: 10.1371/journal.pcbi.1003098] [6] which was implemented also in Python and is open-source as well. You can find the source code on our GitHub repository called component-contribution.
Acknowledgements¶
- Avi Flamholz, Elad Noor, Ron Milo and Arren Bar-Even designed the eQuilibrator interface
- Avi Flamholz and Elad Noor implemented eQuilibrator
- Elad Noor, Avi Flamholz, Hulda Haraldsdóttir, Arren Bar-Even and Ron Milo designed and tuned eQuilibrator’s version of the component contribution
References¶
| [1] | R.A. Alberty, “Thermodynamics of biochemical reactions” (Hoboken N.J.: Wiley-Interscience, 2003) |
| [2] | R.A. Alberty, “Biochemical Thermodynamics” (Hoboken, NJ, USA: John Wiley & Sons, Inc., 2006) |
| [3] | M.L. Mavrovouniotis, “Estimation of standard Gibbs energy changes of biotransformations” The Journal of Biological Chemistry (1991) 266(22):14440-14445 |
| [4] | M.D. Jankowski et al., “Group Contribution Method for Thermodynamic Analysis of Complex Metabolic Networks” Biophysical Journal (2008) 95(3):1487-1499 |
| [5] |
|
| [6] |
|
| [7] |
|


Class future< void > (2.9.0)
Implement ISO/IEC TS 19571:2016 future for void.
Constructors
future()
future(future< future< void > > &&)
Creates a new future that unwraps rhs
.
This constructor creates a new shared state that becomes satisfied when both rhs
and rhs.get()
become satisfied. If rhs
is satisfied, but rhs.get()
returns an invalid future then the newly created future becomes satisfied with a std::future_error
exception, and the exception error code is std::future_errc::broken_promise
.
| Parameter | |
|---|---|
| Name | Description |
rhs |
future< future< void > > &&
|
future(future< T > &&)
Creates a future from a future whose result type is convertible to this future's result type.
| Parameters | |
|---|---|
| Name | Description |
rhs |
future< T > &&
|
class T |
|
future(std::shared_ptr< shared_state_type >)
| Parameter | |
|---|---|
| Name | Description |
state |
std::shared_ptr< shared_state_type >
|
Functions
get()
Waits until the shared state becomes ready, then retrieves the value stored in the shared state.
| Exceptions | |
|---|---|
| Type | Description |
... |
any exceptions stored in the shared state. |
std::future_error |
with std::no_state if the future does not have a shared state. |
| Returns | |
|---|---|
| Type | Description |
void |
then(F &&)
Attach a continuation to the future.
Attach a callable func to be invoked when the future is ready. The return type is a future wrapping the return type of func.
Side effects: valid() == false
if the operation is successful.
| Parameters | |
|---|---|
| Name | Description |
func |
F &&
a Callable to be invoked when the future is ready. The function might be called immediately, e.g., if the future is ready. |
typename F |
|
| Returns | |
|---|---|
| Type | Description |
internal::then_helper< F, void >::future_t |
|
Type Aliases
shared_state_type
typename internal::future_base< void >::shared_state_type


Your Play List library_music
_Recent
Like
keyboard_arrow_up
Sing Me To Sleep
Alan Walker
00:00 / 00:00
Buffering...


This is just a demo to show how the dependencies are loaded
The developer console will show how many source files are loaded


[root]/src
Resources
(1 files, 0 lines)
TortoiseBlame
(1 files, 2395 lines)
TortoiseMerge
(1 files, 6464 lines)
TortoiseProc
(4 files, 4875 lines)
Commands
(1 files, 872 lines)
TortoiseUDiff
(1 files, 861 lines)
Utils
(0 files, 0 lines)
MiscUI
(2 files, 3127 lines)
| Author | Changes | Lines of Code | Lines per Change |
|---|---|---|---|
| tortoisesvn | 2 (100.0%) | 0 (-) | 0.0 |
add the editorconfig.build script to the solution folder.
0 lines of code changed in 2 files:


For general proposal calling information, see Call for Proposals.
First of all, thank you considering giving a talk in PyCon Taiwan 2017. The following will help you submit an successful proposal. In the following, we are going to provide you the tips to make your proposal strong and informative and get the best chance of acceptance.
Generally, you will have the following aspects to think through before your proposal:
- What’s your topic?
- Who is your target audience?
- What will the audience gain after your talk?
- How you organize your talk time?
You will ask to fill up the following fields for your proposal:
- Title
- Category
- Duration
- Language
- Abstract
- Python Level
- Objectives
- Detailed Description (optional)
- Outline (optional)
- Supplementary (optional)
- Recording Policy
- Slide Link (optional)
Looks like quite a lot of fields to fill in. Well, you can skip those optional fields and the rest of the form will only take you about 500 chars to type. But we encourage you to fill most of the fields to help reviewer understand your proposal.
Some of the fields are for reviewers only so no need to worry about spoilers:
- Objectives
- Outline
- Supplementary
If you are a very experienced speaker, you can directly enter the DashBoard to propose！
Next we will give more detailed advice on each aspects.


The celeb net
We are the world’s first self-serve celebrity marketplace plaXorm connecYng brands and celebriYes. Are you a brand or agency, looking for celebriYes for your markeYng campaigns? Are you a celebrity, looking for brands to collaborate with? Strike a deal within the same day with our intelligent full-service automated plaXorm.
FULL-SERVICE AUTOMATED PLATFORM
Our full-service platorm is the most efficient soluYon for celebrity endorsement in the market, disYlled with two decades of our solid industry experience and know-how. Our automated systems take care of all the tedious work of discovering and selecYng celebriYes, matching budgets, contract and payment handling. Our intelligent plaXorm and efficient processes enable us to keep overhead costs low and ensure clients get the most bang for their buck.
-
INSTANT FEE QUOTESSearch and discover celebriYes by your campaign criteria and get instantaneous fee quotes. No more emailing mulYple agents back and forth for weeks!
-
DIRECT ACCESSGet direct access to an extensive list of local and regional celebriYes. No more mulYple layers of agents! Host video conferences directly on the plaXorm.
-
LOWEST COMMISSIONEnjoy commission as low as 6%, the lowest in the industry! For deals above S$100,000, our commission is capped at S$6,000. Yes you read it right!
-
E-CONTRACT & E-INVOICEReduce your paperwork by e-signing contracts autogenerated by the system. Invoices too!
-
DATA ANALYSISUse data collected by the plaXorm to understand how your brand fares among celebriYes, so you can make informed decisions about your offer and strategies.
-
CELEBRITY PITCHESReceive pitches directly from celebriYes to collaborate with your brand!
the celeb net MANAGED SERVICES
-
MANAGED SERVICES
You want celebrity endorsement experts on your team and you prefer the human touch. We will guide you through the earliest planning stages through choosing which celebriYes to partner with. If you need a producYon team, photographers or stylists, we will take care of that too.


In this technical documentation page, you can see the basics of which languages make up the internet's many websites.
On this page, you will improve your digital literacy for these web languages. This page in particular is not for learning syntax or commands.
These are the languages that fundamentally make up a webpage, which you can read about below:
What you should already know
This reference page covers the basics of web literacy, so you do not need to know any code.
What you should be familiar with:
- How to use a web browser to access the internet
- What a website is and how to access them via an address bar or search engine
- That HTML, CSS, and JavaScript are coding markups and languages, even if you don't know how they work
HTML is a markup language, as evidenced by its name, Hyper Text Markup Language. A markup language is what is used to write out text for a webpage and have it show up in your browser.
Depending on the syntax used, HTML can categorize text in a hierarchy of header, paragraph, list, etc., and organize textual information
HTML can be linked to CSS to adjust its appearance, which is why HTML and CSS are often spoken of in tandem.
!DOCTYPE html
CSS stands for Cascading Style Sheets, and through links, can change everything from the background, images, and even text itself through, for example, color and font.
body {
background-color: blue;
}
Often if a developer is coding HTML, they are referencing and ajusting CSS code at the same time, and vice versa.
#main-doc {}
.main-section {}
JavaScript is a programming language.
For websites, it can communicate with HTML/CSS elements for interactivity.
getElementById()
JavaScript can reference files outside of what you see on a website, and can even change HTML or CSS.
What else will I need to make a website?
The great thing about building websites is that for the most part, the sky's the limit! There are many more languages and frameworks to explore once you've learned the basics, such as Ruby and React.
Internet technologies are always changing and growing!


Benefits of unit testing
- Automatic
- Good for long-term
- New people dont unknowingly break stuff
- Catches bugs during refactoring
- Tests are self-documenting
- Shorter feedback loops
- More thoughtful development
- preemptively set expectations vs. reactive programming