# @lume/kiwi
Lume Kiwi is an efficient implementation of the Cassowary constraint solving
algorithm, based on the seminal Cassowary paper.
It is _not_ a refactoring or port of the original C++ solver, but
has been designed from the ground up to be lightweight and fast.
**Example**
```javascript
import * as kiwi from '@lume/kiwi'
// Create a solver
const solver = new kiwi.Solver()
// Adjust the max number of solver iterations before an error is thrown if
// more is needed. Default is 10,000.
solver.maxIterations = 20000
// Create and add some editable variables
const left = new kiwi.Variable()
const width = new kiwi.Variable()
solver.addEditVariable(left, kiwi.Strength.strong)
solver.addEditVariable(width, kiwi.Strength.strong)
// Create a variable calculated through a constraint
const centerX = new kiwi.Variable()
const expr = new kiwi.Expression([-1, centerX], left, [0.5, width])
solver.addConstraint(new kiwi.Constraint(expr, kiwi.Operator.Eq, kiwi.Strength.required))
// Suggest some values to the solver
solver.suggestValue(left, 0)
solver.suggestValue(width, 500)
// Lets solve the problem!
solver.updateVariables()
console.assert(centerX.value() === 250)
```
# API Documentation
- [@lume/kiwi](#module_@lume/kiwi)
- [~Variable](#module_@lume/kiwi..Variable)
- [new Variable([name])](#new_module_@lume/kiwi..Variable_new)
- [.name()](#module_@lume/kiwi..Variable+name) ⇒ String
- [.setName(name)](#module_@lume/kiwi..Variable+setName)
- [.value()](#module_@lume/kiwi..Variable+value) ⇒ Number
- [.subscribe(callback)](#module_@lume/kiwi..Variable+subscribe)
- [.unsubscribe()](#module_@lume/kiwi..Variable+unsubscribe)
- [.plus(value)](#module_@lume/kiwi..Variable+plus) ⇒ Expression
- [.minus(value)](#module_@lume/kiwi..Variable+minus) ⇒ Expression
- [.multiply(coefficient)](#module_@lume/kiwi..Variable+multiply) ⇒ Expression
- [.divide(coefficient)](#module_@lume/kiwi..Variable+divide) ⇒ Expression
- [~Expression](#module_@lume/kiwi..Expression)
- [new Expression(...args)](#new_module_@lume/kiwi..Expression_new)
- [.plus(value)](#module_@lume/kiwi..Expression+plus) ⇒ Expression
- [.minus(value)](#module_@lume/kiwi..Expression+minus) ⇒ Expression
- [.multiply(coefficient)](#module_@lume/kiwi..Expression+multiply) ⇒ Expression
- [.divide(coefficient)](#module_@lume/kiwi..Expression+divide) ⇒ Expression
- [~Strength](#module_@lume/kiwi..Strength)
- _instance_
- [.required](#module_@lume/kiwi..Strength+required)
- [.strong](#module_@lume/kiwi..Strength+strong)
- [.medium](#module_@lume/kiwi..Strength+medium)
- [.weak](#module_@lume/kiwi..Strength+weak)
- _static_
- [.create(a, b, c, [w])](#module_@lume/kiwi..Strength.create) ⇒
- [~Constraint](#module_@lume/kiwi..Constraint)
- [new Constraint(expression, operator, [rhs], [strength])](#new_module_@lume/kiwi..Constraint_new)
- [.expression()](#module_@lume/kiwi..Constraint+expression) ⇒ Expression
- [.op()](#module_@lume/kiwi..Constraint+op) ⇒ Operator
- [.strength()](#module_@lume/kiwi..Constraint+strength) ⇒ Number
- [~Solver](#module_@lume/kiwi..Solver)
- [new Solver()](#new_module_@lume/kiwi..Solver_new)
- [.maxIterations](#module_@lume/kiwi..Solver+maxIterations) : number
- [.createConstraint(lhs, operator, rhs, [strength])](#module_@lume/kiwi..Solver+createConstraint)
- [.addConstraint(constraint)](#module_@lume/kiwi..Solver+addConstraint)
- [.removeConstraint(constraint)](#module_@lume/kiwi..Solver+removeConstraint)
- [.hasConstraint(constraint)](#module_@lume/kiwi..Solver+hasConstraint) ⇒ Bool
- [.getConstraints()](#module_@lume/kiwi..Solver+getConstraints) ⇒ [ 'Array' ].<Constraint>
- [.addEditVariable(variable, strength)](#module_@lume/kiwi..Solver+addEditVariable)
- [.removeEditVariable(variable)](#module_@lume/kiwi..Solver+removeEditVariable)
- [.hasEditVariable(variable)](#module_@lume/kiwi..Solver+hasEditVariable) ⇒ Bool
- [.suggestValue(variable, value)](#module_@lume/kiwi..Solver+suggestValue)
- [.updateVariables()](#module_@lume/kiwi..Solver+updateVariables)
- [~Operator](#module_@lume/kiwi..Operator) : enum
## @lume/kiwi~Variable
The primary user constraint variable.
**Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi)
- [~Variable](#module_@lume/kiwi..Variable)
- [new Variable([name])](#new_module_@lume/kiwi..Variable_new)
- [.name()](#module_@lume/kiwi..Variable+name) ⇒ String
- [.setName(name)](#module_@lume/kiwi..Variable+setName)
- [.value()](#module_@lume/kiwi..Variable+value) ⇒ Number
- [.subscribe(callback)](#module_@lume/kiwi..Variable+subscribe)
- [.unsubscribe()](#module_@lume/kiwi..Variable+unsubscribe)
- [.plus(value)](#module_@lume/kiwi..Variable+plus) ⇒ Expression
- [.minus(value)](#module_@lume/kiwi..Variable+minus) ⇒ Expression
- [.multiply(coefficient)](#module_@lume/kiwi..Variable+multiply) ⇒ Expression
- [.divide(coefficient)](#module_@lume/kiwi..Variable+divide) ⇒ Expression
### new Variable([name])
| Param | Type | Default | Description |
| ------ | ------------------- | ------------------------- | ----------------------------------------- |
| [name] | String | "" | The name to associated with the variable. |
### variable.name() ⇒ String
Returns the name of the variable.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
**Returns**: String - name of the variable
### variable.setName(name)
Set the name of the variable.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
| Param | Type | Description |
| ----- | ------------------- | -------------------- |
| name | String | Name of the variable |
### variable.value() ⇒ Number
Returns the value of the variable.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
**Returns**: Number - Calculated value
### variable.subscribe(callback)
Set a callback for whenever the value changes.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
| Param | Type | Description |
| -------- | --------------------- | ------------------------------------------- |
| callback | function | to call whenever the variable value changes |
### variable.unsubscribe()
Stops the variable from calling the callback when the variable value
changes.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
### variable.plus(value) ⇒ Expression
Creates a new Expression by adding a number, variable or expression
to the variable.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
**Returns**: Expression - expression
| Param | Type | Description |
| ----- | ----------------------------------------------------------------------- | ------------- |
| value | Number \| Variable \| Expression | Value to add. |
### variable.minus(value) ⇒ Expression
Creates a new Expression by substracting a number, variable or expression
from the variable.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
**Returns**: Expression - expression
| Param | Type | Description |
| ----- | ----------------------------------------------------------------------- | ------------------- |
| value | Number \| Variable \| Expression | Value to substract. |
### variable.multiply(coefficient) ⇒ Expression
Creates a new Expression by multiplying with a fixed number.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
**Returns**: Expression - expression
| Param | Type | Description |
| ----------- | ------------------- | ----------------------------- |
| coefficient | Number | Coefficient to multiply with. |
### variable.divide(coefficient) ⇒ Expression
Creates a new Expression by dividing with a fixed number.
**Kind**: instance method of [Variable](#module_@lume/kiwi..Variable)
**Returns**: Expression - expression
| Param | Type | Description |
| ----------- | ------------------- | ------------------------- |
| coefficient | Number | Coefficient to divide by. |
## @lume/kiwi~Expression
An expression of variable terms and a constant.
The constructor accepts an arbitrary number of parameters,
each of which must be one of the following types:
- number
- Variable
- Expression
- 2-tuple of [number, Variable|Expression]
The parameters are summed. The tuples are multiplied.
**Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi)
- [~Expression](#module_@lume/kiwi..Expression)
- [new Expression(...args)](#new_module_@lume/kiwi..Expression_new)
- [.plus(value)](#module_@lume/kiwi..Expression+plus) ⇒ Expression
- [.minus(value)](#module_@lume/kiwi..Expression+minus) ⇒ Expression
- [.multiply(coefficient)](#module_@lume/kiwi..Expression+multiply) ⇒ Expression
- [.divide(coefficient)](#module_@lume/kiwi..Expression+divide) ⇒ Expression
### new Expression(...args)
| Param | Type |
| ------- | --------------------------------------------------------------------------------------------- |
| ...args | number \| Variable \| Expression \| Array |
### expression.plus(value) ⇒ Expression
Creates a new Expression by adding a number, variable or expression
to the expression.
**Kind**: instance method of [Expression](#module_@lume/kiwi..Expression)
**Returns**: Expression - expression
| Param | Type | Description |
| ----- | ----------------------------------------------------------------------- | ------------- |
| value | Number \| Variable \| Expression | Value to add. |
### expression.minus(value) ⇒ Expression
Creates a new Expression by substracting a number, variable or expression
from the expression.
**Kind**: instance method of [Expression](#module_@lume/kiwi..Expression)
**Returns**: Expression - expression
| Param | Type | Description |
| ----- | ----------------------------------------------------------------------- | ------------------- |
| value | Number \| Variable \| Expression | Value to substract. |
### expression.multiply(coefficient) ⇒ Expression
Creates a new Expression by multiplying with a fixed number.
**Kind**: instance method of [Expression](#module_@lume/kiwi..Expression)
**Returns**: Expression - expression
| Param | Type | Description |
| ----------- | ------------------- | ----------------------------- |
| coefficient | Number | Coefficient to multiply with. |
### expression.divide(coefficient) ⇒ Expression
Creates a new Expression by dividing with a fixed number.
**Kind**: instance method of [Expression](#module_@lume/kiwi..Expression)
**Returns**: Expression - expression
| Param | Type | Description |
| ----------- | ------------------- | ------------------------- |
| coefficient | Number | Coefficient to divide by. |
## @lume/kiwi~Strength
**Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi)
- [~Strength](#module_@lume/kiwi..Strength)
- _instance_
- [.required](#module_@lume/kiwi..Strength+required)
- [.strong](#module_@lume/kiwi..Strength+strong)
- [.medium](#module_@lume/kiwi..Strength+medium)
- [.weak](#module_@lume/kiwi..Strength+weak)
- _static_
- [.create(a, b, c, [w])](#module_@lume/kiwi..Strength.create) ⇒
### strength.required
The 'required' symbolic strength.
**Kind**: instance property of [Strength](#module_@lume/kiwi..Strength)
### strength.strong
The 'strong' symbolic strength.
**Kind**: instance property of [Strength](#module_@lume/kiwi..Strength)
### strength.medium
The 'medium' symbolic strength.
**Kind**: instance property of [Strength](#module_@lume/kiwi..Strength)
### strength.weak
The 'weak' symbolic strength.
**Kind**: instance property of [Strength](#module_@lume/kiwi..Strength)
### Strength.create(a, b, c, [w]) ⇒
Create a new symbolic strength.
**Kind**: static method of [Strength](#module_@lume/kiwi..Strength)
**Returns**: strength
| Param | Default | Description |
| ----- | -------------- | ----------- |
| a | | strong |
| b | | medium |
| c | | weak |
| [w] | 1 | weight |
## @lume/kiwi~Constraint
A linear constraint equation.
A constraint equation is composed of an expression, an operator,
and a strength. The RHS of the equation is implicitly zero.
**Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi)
- [~Constraint](#module_@lume/kiwi..Constraint)
- [new Constraint(expression, operator, [rhs], [strength])](#new_module_@lume/kiwi..Constraint_new)
- [.expression()](#module_@lume/kiwi..Constraint+expression) ⇒ Expression
- [.op()](#module_@lume/kiwi..Constraint+op) ⇒ Operator
- [.strength()](#module_@lume/kiwi..Constraint+strength) ⇒ Number
### new Constraint(expression, operator, [rhs], [strength])
| Param | Type | Default | Description |
| ---------- | ----------------------- | ------------------------------ | ---------------------------------- |
| expression | Expression | | The constraint expression (LHS). |
| operator | Operator | | The equation operator. |
| [rhs] | Expression | | Right hand side of the expression. |
| [strength] | Number | Strength.required | The strength of the constraint. |
### constraint.expression() ⇒ Expression
Returns the expression of the constraint.
**Kind**: instance method of [Constraint](#module_@lume/kiwi..Constraint)
**Returns**: Expression - expression
### constraint.op() ⇒ Operator
Returns the relational operator of the constraint.
**Kind**: instance method of [Constraint](#module_@lume/kiwi..Constraint)
**Returns**: Operator - linear constraint operator
### constraint.strength() ⇒ Number
Returns the strength of the constraint.
**Kind**: instance method of [Constraint](#module_@lume/kiwi..Constraint)
**Returns**: Number - strength
## @lume/kiwi~Solver
The constraint solver class.
**Kind**: inner class of [@lume/kiwi](#module_@lume/kiwi)
- [~Solver](#module_@lume/kiwi..Solver)
- [new Solver()](#new_module_@lume/kiwi..Solver_new)
- [.maxIterations](#module_@lume/kiwi..Solver+maxIterations) : number
- [.createConstraint(lhs, operator, rhs, [strength])](#module_@lume/kiwi..Solver+createConstraint)
- [.addConstraint(constraint)](#module_@lume/kiwi..Solver+addConstraint)
- [.removeConstraint(constraint)](#module_@lume/kiwi..Solver+removeConstraint)
- [.hasConstraint(constraint)](#module_@lume/kiwi..Solver+hasConstraint) ⇒ Bool
- [.getConstraints()](#module_@lume/kiwi..Solver+getConstraints) ⇒ [ 'Array' ].<Constraint>
- [.addEditVariable(variable, strength)](#module_@lume/kiwi..Solver+addEditVariable)
- [.removeEditVariable(variable)](#module_@lume/kiwi..Solver+removeEditVariable)
- [.hasEditVariable(variable)](#module_@lume/kiwi..Solver+hasEditVariable) ⇒ Bool
- [.suggestValue(variable, value)](#module_@lume/kiwi..Solver+suggestValue)
- [.updateVariables()](#module_@lume/kiwi..Solver+updateVariables)
### new Solver()
Construct a new Solver.
### solver.maxIterations : number
- The max number of solver iterations before an erroris thrown, in order to prevent infinite iteration. Default: `10,000`.
**Kind**: instance property of [Solver](#module_@lume/kiwi..Solver)
### solver.createConstraint(lhs, operator, rhs, [strength])
Creates and add a constraint to the solver.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
| Param | Type | Default | Description |
| ---------- | ----------------------------------------------------------------------- | ------------------------------ | --------------------------------- |
| lhs | Expression \| Variable | | Left hand side of the expression |
| operator | Operator | | Operator |
| rhs | Expression \| Variable \| Number | | Right hand side of the expression |
| [strength] | Number | Strength.required | Strength |
### solver.addConstraint(constraint)
Add a constraint to the solver.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
| Param | Type | Description |
| ---------- | ----------------------- | ------------------------------- |
| constraint | Constraint | Constraint to add to the solver |
### solver.removeConstraint(constraint)
Remove a constraint from the solver.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
| Param | Type | Description |
| ---------- | ----------------------- | ------------------------------------ |
| constraint | Constraint | Constraint to remove from the solver |
### solver.hasConstraint(constraint) ⇒ Bool
Test whether the solver contains the constraint.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
**Returns**: Bool - true or false
| Param | Type | Description |
| ---------- | ----------------------- | ---------------------- |
| constraint | Constraint | Constraint to test for |
### solver.getConstraints() ⇒ [ 'Array' ].<Constraint>
Get an array of the current constraints.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
### solver.addEditVariable(variable, strength)
Add an edit variable to the solver.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
| Param | Type | Description |
| -------- | --------------------- | ------------------------------------------------- |
| variable | Variable | Edit variable to add to the solver |
| strength | Number | Strength, should be less than `Strength.required` |
### solver.removeEditVariable(variable)
Remove an edit variable from the solver.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
| Param | Type | Description |
| -------- | --------------------- | --------------------------------------- |
| variable | Variable | Edit variable to remove from the solver |
### solver.hasEditVariable(variable) ⇒ Bool
Test whether the solver contains the edit variable.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
**Returns**: Bool - true or false
| Param | Type | Description |
| -------- | --------------------- | ------------------------- |
| variable | Variable | Edit variable to test for |
### solver.suggestValue(variable, value)
Suggest the value of an edit variable.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
| Param | Type | Description |
| -------- | --------------------- | ------------------------------------ |
| variable | Variable | Edit variable to suggest a value for |
| value | Number | Suggested value |
### solver.updateVariables()
Update the values of the variables.
**Kind**: instance method of [Solver](#module_@lume/kiwi..Solver)
## @lume/kiwi~Operator : enum
An enum defining the linear constraint operators.
| Value | Operator | Description |
| ----- | -------- | ------------------ |
| `Le` | <= | Less than equal |
| `Ge` | >= | Greater than equal |
| `Eq` | == | Equal |
**Kind**: inner enum of [@lume/kiwi](#module_@lume/kiwi)