Sei sulla pagina 1di 156

<?

php
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
*/

namespace Leafo\ScssPhp;

use Leafo\ScssPhp\Block;
use Leafo\ScssPhp\Compiler;
use Leafo\ScssPhp\Node;
use Leafo\ScssPhp\Type;

/**
* SCSS parser
*
* @author Leaf Corcoran <leafot@gmail.com>
*/
class Parser
{
const SOURCE_INDEX = -1;
const SOURCE_POSITION = -2;

/**
* @var array
*/
protected static $precedence = array(
'=' => 0,
'or' => 1,
'and' => 2,
'==' => 3,
'!=' => 3,
'<=>' => 3,
'<=' => 4,
'>=' => 4,
'<' => 4,
'>' => 4,
'+' => 5,
'-' => 5,
'*' => 6,
'/' => 6,
'%' => 6,
);

protected static $commentPattern;


protected static $operatorPattern;
protected static $whitePattern;

private $sourceName;
private $sourceIndex;
private $charset;
private $count;
private $env;
private $inParens;
private $eatWhiteDefault;
private $buffer;

/**
* Constructor
*
* @api
*
* @param string $sourceName
* @param integer $sourceIndex
*/
public function __construct($sourceName, $sourceIndex = 0)
{
$this->sourceName = $sourceName ?: '(stdin)';
$this->sourceIndex = $sourceIndex;
$this->charset = null;

if (empty(self::$operatorPattern)) {
self::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=\>|\<\=?|and|or)';

$commentSingle = '\/\/';
$commentMultiLeft = '\/\*';
$commentMultiRight = '\*\/';

self::$commentPattern = $commentMultiLeft . '.*?' . $commentMultiRight;


self::$whitePattern = '/' . $commentSingle . '[^\n]*\s*|(' . self::
$commentPattern . ')\s*|\s+/Ais';
}
}

/**
* Get source file name
*
* @api
*
* @return string
*/
public function getSourceName()
{
return $this->sourceName;
}

/**
* Get source line number (given character position in the buffer)
*
* @api
*
* @param integer $pos
*
* @return integer
*/
public function getLineNo($pos)
{
return 1 + substr_count(substr($this->buffer, 0, $pos), "\n");
}

/**
* Throw parser error
*
* @api
*
* @param string $msg
* @param integer $count
*
* @throws \Exception
*/
public function throwParseError($msg = 'parse error', $count = null)
{
$count = ! isset($count) ? $this->count : $count;

$line = $this->getLineNo($count);

if (! empty($this->sourceName)) {
$loc = "$this->sourceName on line $line";
} else {
$loc = "line: $line";
}

if ($this->peek("(.*?)(\n|$)", $m, $count)) {


throw new \Exception("$msg: failed at `$m[1]` $loc");
}

throw new \Exception("$msg: $loc");


}

/**
* Parser buffer
*
* @api
*
* @param string $buffer
*
* @return \Leafo\ScssPhp\Block
*/
public function parse($buffer)
{
$this->count = 0;
$this->env = null;
$this->inParens = false;
$this->eatWhiteDefault = true;
$this->buffer = rtrim($buffer, "\x00..\x1f");

$this->pushBlock(null); // root block

$this->whitespace();
$this->pushBlock(null);
$this->popBlock();

while ($this->parseChunk()) {
;
}

if ($this->count !== strlen($this->buffer)) {


$this->throwParseError();
}

if (! empty($this->env->parent)) {
$this->throwParseError('unclosed block');
}

if ($this->charset) {
array_unshift($this->env->children, $this->charset);
}

$this->env->isRoot = true;

return $this->env;
}

/**
* Parse a value or value list
*
* @api
*
* @param string $buffer
* @param string $out
*
* @return boolean
*/
public function parseValue($buffer, &$out)
{
$this->count = 0;
$this->env = null;
$this->inParens = false;
$this->eatWhiteDefault = true;
$this->buffer = (string) $buffer;

return $this->valueList($out);
}

/**
* Parse a selector or selector list
*
* @api
*
* @param string $buffer
* @param string $out
*
* @return boolean
*/
public function parseSelector($buffer, &$out)
{
$this->count = 0;
$this->env = null;
$this->inParens = false;
$this->eatWhiteDefault = true;
$this->buffer = (string) $buffer;

return $this->selectors($out);
}

/**
* Parse a single chunk off the head of the buffer and append it to the
* current parse environment.
*
* Returns false when the buffer is empty, or when there is an error.
*
* This function is called repeatedly until the entire document is
* parsed.
*
* This parser is most similar to a recursive descent parser. Single
* functions represent discrete grammatical rules for the language, and
* they are able to capture the text that represents those rules.
*
* Consider the function Compiler::keyword(). (All parse functions are
* structured the same.)
*
* The function takes a single reference argument. When calling the
* function it will attempt to match a keyword on the head of the buffer.
* If it is successful, it will place the keyword in the referenced
* argument, advance the position in the buffer, and return true. If it
* fails then it won't advance the buffer and it will return false.
*
* All of these parse functions are powered by Compiler::match(), which behaves
* the same way, but takes a literal regular expression. Sometimes it is
* more convenient to use match instead of creating a new function.
*
* Because of the format of the functions, to parse an entire string of
* grammatical rules, you can chain them together using &&.
*
* But, if some of the rules in the chain succeed before one fails, then
* the buffer position will be left at an invalid state. In order to
* avoid this, Compiler::seek() is used to remember and set buffer positions.
*
* Before parsing a chain, use $s = $this->seek() to remember the current
* position into $s. Then if a chain fails, use $this->seek($s) to
* go back where we started.
*
* @return boolean
*/
protected function parseChunk()
{
$s = $this->seek();

// the directives
if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] ===
'@') {
if ($this->literal('@at-root') &&
($this->selectors($selector) || true) &&
($this->map($with) || true) &&
$this->literal('{')
) {
$atRoot = $this->pushSpecialBlock(Type::T_AT_ROOT, $s);
$atRoot->selector = $selector;
$atRoot->with = $with;

return true;
}

$this->seek($s);

if ($this->literal('@media') && $this->mediaQueryList($mediaQueryList)


&& $this->literal('{')) {
$media = $this->pushSpecialBlock(Type::T_MEDIA, $s);
$media->queryList = $mediaQueryList[2];
return true;
}

$this->seek($s);

if ($this->literal('@mixin') &&
$this->keyword($mixinName) &&
($this->argumentDef($args) || true) &&
$this->literal('{')
) {
$mixin = $this->pushSpecialBlock(Type::T_MIXIN, $s);
$mixin->name = $mixinName;
$mixin->args = $args;

return true;
}

$this->seek($s);

if ($this->literal('@include') &&
$this->keyword($mixinName) &&
($this->literal('(') &&
($this->argValues($argValues) || true) &&
$this->literal(')') || true) &&
($this->end() ||
$this->literal('{') && $hasBlock = true)
) {
$child = array(Type::T_INCLUDE,
$mixinName, isset($argValues) ? $argValues : null, null);

if (! empty($hasBlock)) {
$include = $this->pushSpecialBlock(Type::T_INCLUDE, $s);
$include->child = $child;
} else {
$this->append($child, $s);
}

return true;
}

$this->seek($s);

if ($this->literal('@import') &&
$this->valueList($importPath) &&
$this->end()
) {
$this->append(array(Type::T_IMPORT, $importPath), $s);

return true;
}

$this->seek($s);

if ($this->literal('@import') &&
$this->url($importPath) &&
$this->end()
) {
$this->append(array(Type::T_IMPORT, $importPath), $s);
return true;
}

$this->seek($s);

if ($this->literal('@extend') &&
$this->selectors($selector) &&
$this->end()
) {
$this->append(array(Type::T_EXTEND, $selector), $s);

return true;
}

$this->seek($s);

if ($this->literal('@function') &&
$this->keyword($fnName) &&
$this->argumentDef($args) &&
$this->literal('{')
) {
$func = $this->pushSpecialBlock(Type::T_FUNCTION, $s);
$func->name = $fnName;
$func->args = $args;

return true;
}

$this->seek($s);

if ($this->literal('@break') && $this->end()) {


$this->append(array(Type::T_BREAK), $s);

return true;
}

$this->seek($s);

if ($this->literal('@continue') && $this->end()) {


$this->append(array(Type::T_CONTINUE), $s);

return true;
}

$this->seek($s);

if ($this->literal('@return') && ($this->valueList($retVal) || true) &&


$this->end()) {
$this->append(array(Type::T_RETURN, isset($retVal) ? $retVal :
array(Type::T_NULL)), $s);

return true;
}

$this->seek($s);

if ($this->literal('@each') &&
$this->genericList($varNames, 'variable', ',', false) &&
$this->literal('in') &&
$this->valueList($list) &&
$this->literal('{')
) {
$each = $this->pushSpecialBlock(Type::T_EACH, $s);

foreach ($varNames[2] as $varName) {


$each->vars[] = $varName[1];
}

$each->list = $list;

return true;
}

$this->seek($s);

if ($this->literal('@while') &&
$this->expression($cond) &&
$this->literal('{')
) {
$while = $this->pushSpecialBlock(Type::T_WHILE, $s);
$while->cond = $cond;

return true;
}

$this->seek($s);

if ($this->literal('@for') &&
$this->variable($varName) &&
$this->literal('from') &&
$this->expression($start) &&
($this->literal('through') ||
($forUntil = true && $this->literal('to'))) &&
$this->expression($end) &&
$this->literal('{')
) {
$for = $this->pushSpecialBlock(Type::T_FOR, $s);
$for->var = $varName[1];
$for->start = $start;
$for->end = $end;
$for->until = isset($forUntil);

return true;
}

$this->seek($s);

if ($this->literal('@if') && $this->valueList($cond) && $this-


>literal('{')) {
$if = $this->pushSpecialBlock(Type::T_IF, $s);
$if->cond = $cond;
$if->cases = array();

return true;
}

$this->seek($s);
if ($this->literal('@debug') &&
$this->valueList($value) &&
$this->end()
) {
$this->append(array(Type::T_DEBUG, $value), $s);

return true;
}

$this->seek($s);

if ($this->literal('@warn') &&
$this->valueList($value) &&
$this->end()
) {
$this->append(array(Type::T_WARN, $value), $s);

return true;
}

$this->seek($s);

if ($this->literal('@error') &&
$this->valueList($value) &&
$this->end()
) {
$this->append(array(Type::T_ERROR, $value), $s);

return true;
}

$this->seek($s);

if ($this->literal('@content') && $this->end()) {


$this->append(array(Type::T_MIXIN_CONTENT), $s);

return true;
}

$this->seek($s);

$last = $this->last();

if (isset($last) && $last[0] === Type::T_IF) {


list(, $if) = $last;

if ($this->literal('@else')) {
if ($this->literal('{')) {
$else = $this->pushSpecialBlock(Type::T_ELSE, $s);
} elseif ($this->literal('if') && $this->valueList($cond) &&
$this->literal('{')) {
$else = $this->pushSpecialBlock(Type::T_ELSEIF, $s);
$else->cond = $cond;
}

if (isset($else)) {
$else->dontAppend = true;
$if->cases[] = $else;
return true;
}
}

$this->seek($s);
}

// only retain the first @charset directive encountered


if ($this->literal('@charset') &&
$this->valueList($charset) &&
$this->end()
) {
if (! isset($this->charset)) {
$statement = array(Type::T_CHARSET, $charset);

$statement[self::SOURCE_POSITION] = $s;
$statement[self::SOURCE_INDEX] = $this->sourceIndex;

$this->charset = $statement;
}

return true;
}

$this->seek($s);

// doesn't match built in directive, do generic one


if ($this->literal('@', false) &&
$this->keyword($dirName) &&
($this->variable($dirValue) || $this->openString('{', $dirValue) ||
true) &&
$this->literal('{')
) {
if ($dirName === 'media') {
$directive = $this->pushSpecialBlock(Type::T_MEDIA, $s);
} else {
$directive = $this->pushSpecialBlock(Type::T_DIRECTIVE, $s);
$directive->name = $dirName;
}

if (isset($dirValue)) {
$directive->value = $dirValue;
}

return true;
}

$this->seek($s);

return false;
}

// property shortcut
// captures most properties before having to parse a selector
if ($this->keyword($name, false) &&
$this->literal(': ') &&
$this->valueList($value) &&
$this->end()
) {
$name = array(Type::T_STRING, '', array($name));
$this->append(array(Type::T_ASSIGN, $name, $value), $s);

return true;
}

$this->seek($s);

// variable assigns
if ($this->variable($name) &&
$this->literal(':') &&
$this->valueList($value) &&
$this->end()
) {
// check for '!flag'
$assignmentFlag = $this->stripAssignmentFlag($value);
$this->append(array(Type::T_ASSIGN, $name, $value, $assignmentFlag),
$s);

return true;
}

$this->seek($s);

// misc
if ($this->literal('-->')) {
return true;
}

// opening css block


if ($this->selectors($selectors) && $this->literal('{')) {
$b = $this->pushBlock($selectors, $s);

return true;
}

$this->seek($s);

// property assign, or nested assign


if ($this->propertyName($name) && $this->literal(':')) {
$foundSomething = false;

if ($this->valueList($value)) {
$this->append(array(Type::T_ASSIGN, $name, $value), $s);
$foundSomething = true;
}

if ($this->literal('{')) {
$propBlock = $this->pushSpecialBlock(Type::T_NESTED_PROPERTY, $s);
$propBlock->prefix = $name;
$foundSomething = true;
} elseif ($foundSomething) {
$foundSomething = $this->end();
}

if ($foundSomething) {
return true;
}
}

$this->seek($s);

// closing a block
if ($this->literal('}')) {
$block = $this->popBlock();

if (isset($block->type) && $block->type === Type::T_INCLUDE) {


$include = $block->child;
unset($block->child);
$include[3] = $block;
$this->append($include, $s);
} elseif (empty($block->dontAppend)) {
$type = isset($block->type) ? $block->type : Type::T_BLOCK;
$this->append(array($type, $block), $s);
}

return true;
}

// extra stuff
if ($this->literal(';') ||
$this->literal('<!--')
) {
return true;
}

return false;
}

/**
* Push block onto parse tree
*
* @param array $selectors
* @param integer $pos
*
* @return \Leafo\ScssPhp\Block
*/
protected function pushBlock($selectors, $pos = 0)
{
$b = new Block;
$b->parent = $this->env;
$b->sourcePosition = $pos;
$b->sourceIndex = $this->sourceIndex;
$b->selectors = $selectors;
$b->comments = array();

if (! $this->env) {
$b->children = array();
} elseif (empty($this->env->children)) {
$this->env->children = $this->env->comments;
$b->children = array();
$this->env->comments = array();
} else {
$b->children = $this->env->comments;
$this->env->comments = array();
}
$this->env = $b;

return $b;
}

/**
* Push special (named) block onto parse tree
*
* @param string $type
* @param integer $pos
*
* @return \Leafo\ScssPhp\Block
*/
protected function pushSpecialBlock($type, $pos)
{
$block = $this->pushBlock(null, $pos);
$block->type = $type;

return $block;
}

/**
* Pop scope and return last block
*
* @return \Leafo\ScssPhp\Block
*
* @throws \Exception
*/
protected function popBlock()
{
$block = $this->env;

if (empty($block->parent)) {
$this->throwParseError('unexpected }');
}

$this->env = $block->parent;
unset($block->parent);

$comments = $block->comments;
if (count($comments)) {
$this->env->comments = $comments;
unset($block->comments);
}

return $block;
}

/**
* Peek input stream
*
* @param string $regex
* @param array $out
* @param integer $from
*
* @return integer
*/
protected function peek($regex, &$out, $from = null)
{
if (! isset($from)) {
$from = $this->count;
}

$r = '/' . $regex . '/Ais';


$result = preg_match($r, $this->buffer, $out, null, $from);

return $result;
}

/**
* Seek to position in input stream (or return current position in input
stream)
*
* @param integer $where
*
* @return integer
*/
protected function seek($where = null)
{
if ($where === null) {
return $this->count;
}

$this->count = $where;

return true;
}

/**
* Match string looking for either ending delim, escape, or string
interpolation
*
* {@internal This is a workaround for preg_match's 250K string match limit. }}
*
* @param array $m Matches (passed by reference)
* @param string $delim Delimeter
*
* @return boolean True if match; false otherwise
*/
protected function matchString(&$m, $delim)
{
$token = null;

$end = strlen($this->buffer);

// look for either ending delim, escape, or string interpolation


foreach (array('#{', '\\', $delim) as $lookahead) {
$pos = strpos($this->buffer, $lookahead, $this->count);

if ($pos !== false && $pos < $end) {


$end = $pos;
$token = $lookahead;
}
}

if (! isset($token)) {
return false;
}
$match = substr($this->buffer, $this->count, $end - $this->count);
$m = array(
$match . $token,
$match,
$token
);
$this->count = $end + strlen($token);

return true;
}

/**
* Try to match something on head of buffer
*
* @param string $regex
* @param array $out
* @param boolean $eatWhitespace
*
* @return boolean
*/
protected function match($regex, &$out, $eatWhitespace = null)
{
if (! isset($eatWhitespace)) {
$eatWhitespace = $this->eatWhiteDefault;
}

$r = '/' . $regex . '/Ais';

if (preg_match($r, $this->buffer, $out, null, $this->count)) {


$this->count += strlen($out[0]);

if ($eatWhitespace) {
$this->whitespace();
}

return true;
}

return false;
}

/**
* Match literal string
*
* @param string $what
* @param boolean $eatWhitespace
*
* @return boolean
*/
protected function literal($what, $eatWhitespace = null)
{
if (! isset($eatWhitespace)) {
$eatWhitespace = $this->eatWhiteDefault;
}

// shortcut on single letter


if (! isset($what[1]) && isset($this->buffer[$this->count])) {
if ($this->buffer[$this->count] === $what) {
if (! $eatWhitespace) {
$this->count++;

return true;
}

// goes below...
} else {
return false;
}
}

return $this->match($this->pregQuote($what), $m, $eatWhitespace);


}

/**
* Match some whitespace
*
* @return boolean
*/
protected function whitespace()
{
$gotWhite = false;

while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this-


>count)) {
if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
$this->appendComment(array(Type::T_COMMENT, $m[1]));

$this->commentsSeen[$this->count] = true;
}

$this->count += strlen($m[0]);
$gotWhite = true;
}

return $gotWhite;
}

/**
* Append comment to current block
*
* @param array $comment
*/
protected function appendComment($comment)
{
$comment[1] = substr(preg_replace(array('/^\s+/m', '/^(.)/m'), array('',
' \1'), $comment[1]), 1);

$this->env->comments[] = $comment;
}

/**
* Append statement to current block
*
* @param array $statement
* @param integer $pos
*/
protected function append($statement, $pos = null)
{
if ($pos !== null) {
$statement[self::SOURCE_POSITION] = $pos;
$statement[self::SOURCE_INDEX] = $this->sourceIndex;
}

$this->env->children[] = $statement;

$comments = $this->env->comments;

if (count($comments)) {
$this->env->children = array_merge($this->env->children, $comments);
$this->env->comments = array();
}
}

/**
* Returns last child was appended
*
* @return array|null
*/
protected function last()
{
$i = count($this->env->children) - 1;

if (isset($this->env->children[$i])) {
return $this->env->children[$i];
}
}

/**
* Parse media query list
*
* @param array $out
*
* @return boolean
*/
protected function mediaQueryList(&$out)
{
return $this->genericList($out, 'mediaQuery', ',', false);
}

/**
* Parse media query
*
* @param array $out
*
* @return boolean
*/
protected function mediaQuery(&$out)
{
$s = $this->seek();

$expressions = null;
$parts = array();

if (($this->literal('only') && ($only = true) || $this->literal('not') &&


($not = true) || true) &&
$this->mixedKeyword($mediaType)
) {
$prop = array(Type::T_MEDIA_TYPE);

if (isset($only)) {
$prop[] = array(Type::T_KEYWORD, 'only');
}

if (isset($not)) {
$prop[] = array(Type::T_KEYWORD, 'not');
}

$media = array(Type::T_LIST, '', array());

foreach ((array)$mediaType as $type) {


if (is_array($type)) {
$media[2][] = $type;
} else {
$media[2][] = array(Type::T_KEYWORD, $type);
}
}

$prop[] = $media;
$parts[] = $prop;
}

if (empty($parts) || $this->literal('and')) {
$this->genericList($expressions, 'mediaExpression', 'and', false);

if (is_array($expressions)) {
$parts = array_merge($parts, $expressions[2]);
}
}

$out = $parts;

return true;
}

/**
* Parse media expression
*
* @param array $out
*
* @return boolean
*/
protected function mediaExpression(&$out)
{
$s = $this->seek();
$value = null;

if ($this->literal('(') &&
$this->expression($feature) &&
($this->literal(':') && $this->expression($value) || true) &&
$this->literal(')')
) {
$out = array(Type::T_MEDIA_EXPRESSION, $feature);

if ($value) {
$out[] = $value;
}

return true;
}

$this->seek($s);

return false;
}

/**
* Parse argument values
*
* @param array $out
*
* @return boolean
*/
protected function argValues(&$out)
{
if ($this->genericList($list, 'argValue', ',', false)) {
$out = $list[2];

return true;
}

return false;
}

/**
* Parse argument value
*
* @param array $out
*
* @return boolean
*/
protected function argValue(&$out)
{
$s = $this->seek();

$keyword = null;

if (! $this->variable($keyword) || ! $this->literal(':')) {
$this->seek($s);
$keyword = null;
}

if ($this->genericList($value, 'expression')) {
$out = array($keyword, $value, false);
$s = $this->seek();

if ($this->literal('...')) {
$out[2] = true;
} else {
$this->seek($s);
}

return true;
}
return false;
}

/**
* Parse comma separated value list
*
* @param string $out
*
* @return boolean
*/
protected function valueList(&$out)
{
return $this->genericList($out, 'spaceList', ',');
}

/**
* Parse space separated value list
*
* @param array $out
*
* @return boolean
*/
protected function spaceList(&$out)
{
return $this->genericList($out, 'expression');
}

/**
* Parse generic list
*
* @param array $out
* @param callable $parseItem
* @param string $delim
* @param boolean $flatten
*
* @return boolean
*/
protected function genericList(&$out, $parseItem, $delim = '', $flatten = true)
{
$s = $this->seek();
$items = array();

while ($this->$parseItem($value)) {
$items[] = $value;

if ($delim) {
if (! $this->literal($delim)) {
break;
}
}
}

if (count($items) === 0) {
$this->seek($s);

return false;
}

if ($flatten && count($items) === 1) {


$out = $items[0];
} else {
$out = array(Type::T_LIST, $delim, $items);
}

return true;
}

/**
* Parse expression
*
* @param array $out
*
* @return boolean
*/
protected function expression(&$out)
{
$s = $this->seek();

if ($this->literal('(')) {
if ($this->literal(')')) {
$out = array(Type::T_LIST, '', array());

return true;
}

if ($this->valueList($out) && $this->literal(')') && $out[0] ===


Type::T_LIST) {
return true;
}

$this->seek($s);

if ($this->map($out)) {
return true;
}

$this->seek($s);
}

if ($this->value($lhs)) {
$out = $this->expHelper($lhs, 0);

return true;
}

return false;
}

/**
* Parse left-hand side of subexpression
*
* @param array $lhs
* @param integer $minP
*
* @return array
*/
protected function expHelper($lhs, $minP)
{
$operators = self::$operatorPattern;

$ss = $this->seek();
$whiteBefore = isset($this->buffer[$this->count - 1]) &&
ctype_space($this->buffer[$this->count - 1]);

while ($this->match($operators, $m, false) && self::$precedence[$m[1]] >=


$minP) {
$whiteAfter = isset($this->buffer[$this->count]) &&
ctype_space($this->buffer[$this->count]);
$varAfter = isset($this->buffer[$this->count]) &&
$this->buffer[$this->count] === '$';

$this->whitespace();

$op = $m[1];

// don't turn negative numbers into expressions


if ($op === '-' && $whiteBefore && ! $whiteAfter && ! $varAfter) {
break;
}

if (! $this->value($rhs)) {
break;
}

// peek and see if rhs belongs to next operator


if ($this->peek($operators, $next) && self::$precedence[$next[1]] >
self::$precedence[$op]) {
$rhs = $this->expHelper($rhs, self::$precedence[$next[1]]);
}

$lhs = array(Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens,


$whiteBefore, $whiteAfter);
$ss = $this->seek();
$whiteBefore = isset($this->buffer[$this->count - 1]) &&
ctype_space($this->buffer[$this->count - 1]);
}

$this->seek($ss);

return $lhs;
}

/**
* Parse value
*
* @param array $out
*
* @return boolean
*/
protected function value(&$out)
{
$s = $this->seek();

if ($this->literal('not', false) && $this->whitespace() && $this-


>value($inner)) {
$out = array(Type::T_UNARY, 'not', $inner, $this->inParens);
return true;
}

$this->seek($s);

if ($this->literal('not', false) && $this->parenValue($inner)) {


$out = array(Type::T_UNARY, 'not', $inner, $this->inParens);

return true;
}

$this->seek($s);

if ($this->literal('+') && $this->value($inner)) {


$out = array(Type::T_UNARY, '+', $inner, $this->inParens);

return true;
}

$this->seek($s);

// negation
if ($this->literal('-', false) &&
($this->variable($inner) ||
$this->unit($inner) ||
$this->parenValue($inner))
) {
$out = array(Type::T_UNARY, '-', $inner, $this->inParens);

return true;
}

$this->seek($s);

if ($this->parenValue($out) ||
$this->interpolation($out) ||
$this->variable($out) ||
$this->color($out) ||
$this->unit($out) ||
$this->string($out) ||
$this->func($out) ||
$this->progid($out)
) {
return true;
}

if ($this->keyword($keyword)) {
if ($keyword === 'null') {
$out = array(Type::T_NULL);
} else {
$out = array(Type::T_KEYWORD, $keyword);
}

return true;
}

return false;
}
/**
* Parse parenthesized value
*
* @param array $out
*
* @return boolean
*/
protected function parenValue(&$out)
{
$s = $this->seek();

$inParens = $this->inParens;

if ($this->literal('(')) {
if ($this->literal(')')) {
$out = array(Type::T_LIST, '', array());

return true;
}

$this->inParens = true;

if ($this->expression($exp) && $this->literal(')')) {


$out = $exp;
$this->inParens = $inParens;

return true;
}
}

$this->inParens = $inParens;
$this->seek($s);

return false;
}

/**
* Parse "progid:"
*
* @param array $out
*
* @return boolean
*/
protected function progid(&$out)
{
$s = $this->seek();

if ($this->literal('progid:', false) &&


$this->openString('(', $fn) &&
$this->literal('(')
) {
$this->openString(')', $args, '(');

if ($this->literal(')')) {
$out = array(Type::T_STRING, '', array(
'progid:', $fn, '(', $args, ')'
));

return true;
}
}

$this->seek($s);

return false;
}

/**
* Parse function call
*
* @param array $out
*
* @return boolean
*/
protected function func(&$func)
{
$s = $this->seek();

if ($this->keyword($name, false) &&


$this->literal('(')
) {
if ($name === 'alpha' && $this->argumentList($args)) {
$func = array(Type::T_FUNCTION, $name, array(Type::T_STRING, '',
$args));

return true;
}

if ($name !== 'expression' && ! preg_match('/^(-[a-z]+-)?calc$/',


$name)) {
$ss = $this->seek();

if ($this->argValues($args) && $this->literal(')')) {


$func = array(Type::T_FUNCTION_CALL, $name, $args);

return true;
}

$this->seek($ss);
}

if (($this->openString(')', $str, '(') || true ) &&


$this->literal(')')
) {
$args = array();

if (! empty($str)) {
$args[] = array(null, array(Type::T_STRING, '', array($str)));
}

$func = array(Type::T_FUNCTION_CALL, $name, $args);

return true;
}
}

$this->seek($s);
return false;
}

/**
* Parse function call argument list
*
* @param array $out
*
* @return boolean
*/
protected function argumentList(&$out)
{
$s = $this->seek();
$this->literal('(');

$args = array();

while ($this->keyword($var)) {
$ss = $this->seek();

if ($this->literal('=') && $this->expression($exp)) {


$args[] = array(Type::T_STRING, '', array($var . '='));
$arg = $exp;
} else {
break;
}

$args[] = $arg;

if (! $this->literal(',')) {
break;
}

$args[] = array(Type::T_STRING, '', array(', '));


}

if (! $this->literal(')') || ! count($args)) {
$this->seek($s);

return false;
}

$out = $args;

return true;
}

/**
* Parse mixin/function definition argument list
*
* @param array $out
*
* @return boolean
*/
protected function argumentDef(&$out)
{
$s = $this->seek();
$this->literal('(');
$args = array();

while ($this->variable($var)) {
$arg = array($var[1], null, false);

$ss = $this->seek();

if ($this->literal(':') && $this->genericList($defaultVal,


'expression')) {
$arg[1] = $defaultVal;
} else {
$this->seek($ss);
}

$ss = $this->seek();

if ($this->literal('...')) {
$sss = $this->seek();

if (! $this->literal(')')) {
$this->throwParseError('... has to be after the final
argument');
}

$arg[2] = true;
$this->seek($sss);
} else {
$this->seek($ss);
}

$args[] = $arg;

if (! $this->literal(',')) {
break;
}
}

if (! $this->literal(')')) {
$this->seek($s);

return false;
}

$out = $args;

return true;
}

/**
* Parse map
*
* @param array $out
*
* @return boolean
*/
protected function map(&$out)
{
$s = $this->seek();
if (! $this->literal('(')) {
return false;
}

$keys = array();
$values = array();

while ($this->genericList($key, 'expression') && $this->literal(':') &&


$this->genericList($value, 'expression')
) {
$keys[] = $key;
$values[] = $value;

if (! $this->literal(',')) {
break;
}
}

if (! count($keys) || ! $this->literal(')')) {
$this->seek($s);

return false;
}

$out = array(Type::T_MAP, $keys, $values);

return true;
}

/**
* Parse color
*
* @param array $out
*
* @return boolean
*/
protected function color(&$out)
{
$color = array(Type::T_COLOR);

if ($this->match('(#([0-9a-f]{6})|#([0-9a-f]{3}))', $m)) {
if (isset($m[3])) {
$num = hexdec($m[3]);

foreach (array(3, 2, 1) as $i) {


$t = $num & 0xf;
$color[$i] = $t << 4 | $t;
$num >>= 4;
}
} else {
$num = hexdec($m[2]);

foreach (array(3, 2, 1) as $i) {


$color[$i] = $num & 0xff;
$num >>= 8;
}
}

$out = $color;
return true;
}

return false;
}

/**
* Parse number with unit
*
* @param array $out
*
* @return boolean
*/
protected function unit(&$unit)
{
if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m)) {
$unit = new Node\Number($m[1], empty($m[3]) ? '' : $m[3]);

return true;
}

return false;
}

/**
* Parse string
*
* @param array $out
*
* @return boolean
*/
protected function string(&$out)
{
$s = $this->seek();

if ($this->literal('"', false)) {
$delim = '"';
} elseif ($this->literal('\'', false)) {
$delim = '\'';
} else {
return false;
}

$content = array();
$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false;

while ($this->matchString($m, $delim)) {


$content[] = $m[1];

if ($m[2] === '#{') {


$this->count -= strlen($m[2]);

if ($this->interpolation($inter, false)) {
$content[] = $inter;
} else {
$this->count += strlen($m[2]);
$content[] = '#{'; // ignore it
}
} elseif ($m[2] === '\\') {
$content[] = $m[2];

if ($this->literal($delim, false)) {
$content[] = $delim;
}
} else {
$this->count -= strlen($delim);
break; // delim
}
}

$this->eatWhiteDefault = $oldWhite;

if ($this->literal($delim)) {
$out = array(Type::T_STRING, $delim, $content);

return true;
}

$this->seek($s);

return false;
}

/**
* Parse keyword or interpolation
*
* @param array $out
*
* @return boolean
*/
protected function mixedKeyword(&$out)
{
$s = $this->seek();

$parts = array();

$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false;

for (;;) {
if ($this->keyword($key)) {
$parts[] = $key;
continue;
}

if ($this->interpolation($inter)) {
$parts[] = $inter;
continue;
}

break;
}

$this->eatWhiteDefault = $oldWhite;

if (count($parts) === 0) {
return false;
}

if ($this->eatWhiteDefault) {
$this->whitespace();
}

$out = $parts;

return true;
}

/**
* Parse an unbounded string stopped by $end
*
* @param string $end
* @param array $out
* @param string $nestingOpen
*
* @return boolean
*/
protected function openString($end, &$out, $nestingOpen = null)
{
$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false;

$patt = '(.*?)([\'"]|#\{|' . $this->pregQuote($end) . '|' . self::


$commentPattern . ')';

$nestingLevel = 0;

$content = array();

while ($this->match($patt, $m, false)) {


if (isset($m[1]) && $m[1] !== '') {
$content[] = $m[1];

if ($nestingOpen) {
$nestingLevel += substr_count($m[1], $nestingOpen);
}
}

$tok = $m[2];

$this->count-= strlen($tok);

if ($tok === $end && ! $nestingLevel--) {


break;
}

if (($tok === '\'' || $tok === '"') && $this->string($str)) {


$content[] = $str;
continue;
}

if ($tok === '#{' && $this->interpolation($inter)) {


$content[] = $inter;
continue;
}
$content[] = $tok;
$this->count+= strlen($tok);
}

$this->eatWhiteDefault = $oldWhite;

if (count($content) === 0) {
return false;
}

// trim the end


if (is_string(end($content))) {
$content[count($content) - 1] = rtrim(end($content));
}

$out = array(Type::T_STRING, '', $content);

return true;
}

/**
* Parser interpolation
*
* @param array $out
* @param boolean $lookWhite save information about whitespace before and after
*
* @return boolean
*/
protected function interpolation(&$out, $lookWhite = true)
{
$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = true;

$s = $this->seek();

if ($this->literal('#{') && $this->valueList($value) && $this->literal('}',


false)) {
// TODO: don't error if out of bounds

if ($lookWhite) {
$left = preg_match('/\s/', $this->buffer[$s - 1]) ? ' ' : '';
$right = preg_match('/\s/', $this->buffer[$this->count]) ? ' ': '';
} else {
$left = $right = false;
}

$out = array(Type::T_INTERPOLATE, $value, $left, $right);


$this->eatWhiteDefault = $oldWhite;

if ($this->eatWhiteDefault) {
$this->whitespace();
}

return true;
}

$this->seek($s);
$this->eatWhiteDefault = $oldWhite;
return false;
}

/**
* Parse property name (as an array of parts or a string)
*
* @param array $out
*
* @return boolean
*/
protected function propertyName(&$out)
{
$s = $this->seek();
$parts = array();

$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false;

for (;;) {
if ($this->interpolation($inter)) {
$parts[] = $inter;
continue;
}

if ($this->keyword($text)) {
$parts[] = $text;
continue;
}

if (count($parts) === 0 && $this->match('[:.#]', $m, false)) {


// css hacks
$parts[] = $m[0];
continue;
}

break;
}

$this->eatWhiteDefault = $oldWhite;

if (count($parts) === 0) {
return false;
}

// match comment hack


if (preg_match(
self::$whitePattern,
$this->buffer,
$m,
null,
$this->count
)) {
if (! empty($m[0])) {
$parts[] = $m[0];
$this->count += strlen($m[0]);
}
}
$this->whitespace(); // get any extra whitespace

$out = array(Type::T_STRING, '', $parts);

return true;
}

/**
* Parse comma separated selector list
*
* @param array $out
*
* @return boolean
*/
protected function selectors(&$out)
{
$s = $this->seek();
$selectors = array();

while ($this->selector($sel)) {
$selectors[] = $sel;

if (! $this->literal(',')) {
break;
}

while ($this->literal(',')) {
; // ignore extra
}
}

if (count($selectors) === 0) {
$this->seek($s);

return false;
}

$out = $selectors;

return true;
}

/**
* Parse whitespace separated selector list
*
* @param array $out
*
* @return boolean
*/
protected function selector(&$out)
{
$selector = array();

for (;;) {
if ($this->match('[>+~]+', $m)) {
$selector[] = array($m[0]);
continue;
}
if ($this->selectorSingle($part)) {
$selector[] = $part;
$this->match('\s+', $m);
continue;
}

if ($this->match('\/[^\/]+\/', $m)) {
$selector[] = array($m[0]);
continue;
}

break;
}

if (count($selector) === 0) {
return false;
}

$out = $selector;
return true;
}

/**
* Parse the parts that make up a selector
*
* {@internal
* div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder
* }}
*
* @param array $out
*
* @return boolean
*/
protected function selectorSingle(&$out)
{
$oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false;

$parts = array();

if ($this->literal('*', false)) {
$parts[] = '*';
}

for (;;) {
// see if we can stop early
if ($this->match('\s*[{,]', $m)) {
$this->count--;
break;
}

$s = $this->seek();

// self
if ($this->literal('&', false)) {
$parts[] = Compiler::$selfSelector;
continue;
}
if ($this->literal('.', false)) {
$parts[] = '.';
continue;
}

if ($this->literal('|', false)) {
$parts[] = '|';
continue;
}

if ($this->match('\\\\\S', $m)) {
$parts[] = $m[0];
continue;
}

// for keyframes
if ($this->unit($unit)) {
$parts[] = $unit;
continue;
}

if ($this->keyword($name)) {
$parts[] = $name;
continue;
}

if ($this->interpolation($inter)) {
$parts[] = $inter;
continue;
}

if ($this->literal('%', false) && $this->placeholder($placeholder)) {


$parts[] = '%';
$parts[] = $placeholder;
continue;
}

if ($this->literal('#', false)) {
$parts[] = '#';
continue;
}

// a pseudo selector
if ($this->match('::?', $m) && $this->mixedKeyword($nameParts)) {
$parts[] = $m[0];

foreach ($nameParts as $sub) {


$parts[] = $sub;
}

$ss = $this->seek();

if ($this->literal('(') &&
($this->openString(')', $str, '(') || true ) &&
$this->literal(')')
) {
$parts[] = '(';

if (! empty($str)) {
$parts[] = $str;
}

$parts[] = ')';
} else {
$this->seek($ss);
}

continue;
}

$this->seek($s);

// attribute selector
// TODO: replace with open string?
if ($this->literal('[', false)) {
$attrParts = array('[');

// keyword, string, operator


for (;;) {
if ($this->literal(']', false)) {
$this->count--;
break; // get out early
}

if ($this->match('\s+', $m)) {
$attrParts[] = ' ';
continue;
}

if ($this->string($str)) {
$attrParts[] = $str;
continue;
}

if ($this->keyword($word)) {
$attrParts[] = $word;
continue;
}

if ($this->interpolation($inter, false)) {
$attrParts[] = $inter;
continue;
}

// operator, handles attr namespace too


if ($this->match('[|-~\$\*\^=]+', $m)) {
$attrParts[] = $m[0];
continue;
}

break;
}

if ($this->literal(']', false)) {
$attrParts[] = ']';

foreach ($attrParts as $part) {


$parts[] = $part;
}

continue;
}

$this->seek($s);
// TODO: should just break here?
}

break;
}

$this->eatWhiteDefault = $oldWhite;

if (count($parts) === 0) {
return false;
}

$out = $parts;

return true;
}

/**
* Parse a variable
*
* @param array $out
*
* @return boolean
*/
protected function variable(&$out)
{
$s = $this->seek();

if ($this->literal('$', false) && $this->keyword($name)) {


$out = array(Type::T_VARIABLE, $name);

return true;
}

$this->seek($s);

return false;
}

/**
* Parse a keyword
*
* @param string $word
* @param boolean $eatWhitespace
*
* @return boolean
*/
protected function keyword(&$word, $eatWhitespace = null)
{
if ($this->match(
'(([\w_\-\*!"\']|[\\\\].)([\w\-_"\']|[\\\\].)*)',
$m,
$eatWhitespace
)) {
$word = $m[1];

return true;
}

return false;
}

/**
* Parse a placeholder
*
* @param string $placeholder
*
* @return boolean
*/
protected function placeholder(&$placeholder)
{
if ($this->match('([\w\-_]+|#[{][$][\w\-_]+[}])', $m)) {
$placeholder = $m[1];

return true;
}

return false;
}

/**
* Parse a url
*
* @param array $out
*
* @return boolean
*/
protected function url(&$out)
{
if ($this->match('(url\(\s*(["\']?)([^)]+)\2\s*\))', $m)) {
$out = array(Type::T_STRING, '', array('url(' . $m[2] . $m[3] . $m[2] .
')'));

return true;
}

return false;
}

/**
* Consume an end of statement delimiter
*
* @return boolean
*/
protected function end()
{
if ($this->literal(';')) {
return true;
}

if ($this->count === strlen($this->buffer) || $this->buffer[$this->count]


=== '}') {
// if there is end of file or a closing block next then we don't need a
;
return true;
}

return false;
}

/**
* Strip assignment flag from the list
*
* @param array $value
*
* @return string
*/
protected function stripAssignmentFlag(&$value)
{
$token = &$value;

for ($token = &$value; $token[0] === Type::T_LIST && ($s =


count($token[2])); $token = &$lastNode) {
$lastNode = &$token[2][$s - 1];

if ($lastNode[0] === Type::T_KEYWORD && in_array($lastNode[1], array('!


default', '!global'))) {
array_pop($token[2]);

$token = $this->flattenList($token);

return $lastNode[1];
}
}

return false;
}

/**
* Turn list of length 1 into value type
*
* @param array $value
*
* @return array
*/
protected function flattenList($value)
{
if ($value[0] === Type::T_LIST && count($value[2]) === 1) {
return $this->flattenList($value[2][0]);
}

return $value;
}

/**
* @deprecated
*
* {@internal
* advance counter to next occurrence of $what
* $until - don't include $what in advance
* $allowNewline, if string, will be used as valid char set
* }}
*/
protected function to($what, &$out, $until = false, $allowNewline = false)
{
if (is_string($allowNewline)) {
$validChars = $allowNewline;
} else {
$validChars = $allowNewline ? '.' : "[^\n]";
}

if (! $this->match('(' . $validChars . '*?)' . $this->pregQuote($what), $m,


! $until)) {
return false;
}

if ($until) {
$this->count -= strlen($what); // give back $what
}

$out = $m[1];

return true;
}

/**
* @deprecated
*/
protected function show()
{
if ($this->peek("(.*?)(\n|$)", $m, $this->count)) {
return $m[1];
}

return '';
}

/**
* Quote regular expression
*
* @param string $what
*
* @return string
*/
private function pregQuote($what)
{
return preg_quote($what, '/');
}
}
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
#<?php
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
*/

namespace Leafo\ScssPhp;

/**
* SCSS block/node types
*
* @author Anthon Pang <anthon.pang@gmail.com>
*/
class Type
{
const T_ASSIGN = 'assign';
const T_AT_ROOT = 'at-root';
const T_BLOCK = 'block';
const T_BREAK = 'break';
const T_CHARSET = 'charset';
const T_COLOR = 'color';
const T_COMMENT = 'comment';
const T_CONTINUE = 'continue';
const T_CONTROL = 'control';
const T_DEBUG = 'debug';
const T_DIRECTIVE = 'directive';
const T_EACH = 'each';
const T_ELSE = 'else';
const T_ELSEIF = 'elseif';
const T_ERROR = 'error';
const T_EXPRESSION = 'exp';
const T_EXTEND = 'extend';
const T_FOR = 'for';
const T_FUNCTION = 'function';
const T_FUNCTION_CALL = 'fncall';
const T_HSL = 'hsl';
const T_IF = 'if';
const T_IMPORT = 'import';
const T_INCLUDE = 'include';
const T_INTERPOLATE = 'interpolate';
const T_INTERPOLATED = 'interpolated';
const T_KEYWORD = 'keyword';
const T_LIST = 'list';
const T_MAP = 'map';
const T_MEDIA = 'media';
const T_MEDIA_EXPRESSION = 'mediaExp';
const T_MEDIA_TYPE = 'mediaType';
const T_MEDIA_VALUE = 'mediaValue';
const T_MIXIN = 'mixin';
const T_MIXIN_CONTENT = 'mixin_content';
const T_NESTED_PROPERTY = 'nestedprop';
const T_NOT = 'not';
const T_NULL = 'null';
const T_NUMBER = 'number';
const T_RETURN = 'return';
const T_ROOT = 'root';
const T_SELF = 'self';
const T_STRING = 'string';
const T_UNARY = 'unary';
const T_VARIABLE = 'var';
const T_WARN = 'warn';
const T_WHILE = 'while';
}
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
###################################################################################
##############################################################################�##�#
###�#######|&######�L######�L######�L##%###�L##
####M##5####M##>###YM## ###�M##=###�M##;###�M##'###3N##)###[N##�###�N##<###-
O##/###jO##
###�O######�O## ###�O##,###�O## ###�O## ###�O## ###�O## ####P##
###
P##x####P##r###�P##C####Q##$###GQ##8###lQ######�R##�###�R##�###jS##�####T##,###�T##
####�T##$####U######5U##D###YU##P###�U##;###�U##:###+V##;###fV######�V##!
###�V##:###�V##>####W##�###^W##�###�W##�###�X#######Y##m###9Y##i###�Y##D####Z##b###
VZ##u###�Z##�###/[######�[## ###�[######�[## ###�[#####�[##
###�[######�[##
####\######\##
####\##
###*\## ###7\######A\##
###I\##
###T\##j###a\##V###�\#######]######+]######:]######J]######V]######_]######h]##
###y]######�]######�]######�]######�]##s###�]##p###;^##(###�^##|
###�^######R_##,###Z_######�_######�_##
###�_######�_## ###�_######�_######�_######�_##r###�_##�###b`######
a#######a#######a##'###=a##/###ea##-###�a##

###�a######�a######�a######�a#######b#######b######8b######Tb######qb######�b##
###�b######�b##f###�b######c######&c######2c##$###9c######^d######`e##�###vf##
###Zg##
###dg##
###og######|h######�h######�h##
###�h######�h######�h######�h## ###�h##�###�h##
###ei######pi######�i######�i######�i######�i######�i######�i######�i#######j######
#j######4j######Jj######bj######�j######�j######�j######�j######�j######�j#######k#
#####*k######Ak######\k######sk######k######�k##
###�k######�k##
###�k#####�k##G###�k##$####l##<###Al##$###~l######�m######�n## ###�n##
###�n######�n##
###�n######�n######�n######�n##
####o######o#######o##
###+o######8o######Ko######_o######ro######�o######�o######�o######�o######�o##
###�o##
###�o##
###�o#######p#######p#######p##
###$p######/p######8p######Wp#####^p######lp######xp######�p######�p##
###�p######�p##
###�p##
###�p######�p##2###�p#######q## ####q##
###$q######1q######7q######Fq######Uq######jq######rq##
###yq######�q######�q######�q##
###�q#####�q######�q#####�q##
###�q######�q######�q##9###�q######4r######=r######Rr##E###dr##E###�r##B###�r##

###3s##�###=s##3###�s##w####t######�t######�t######�t######�t######�t######�t######
�t#####�t######u#######u##
####u##
###,u######7u######Ou##�###bu######Hv######Pv######bv######hv##
###nv#####{v######�v##
###�v######�v######�v######�v##
###�v######�v######�v##a###�w#####Ux######cx######lx######tx##@###|x##
###�x######�x######�x######�x#######y######%y######-y######?y#####Ny######\y##
###ky#####xy######�y######�y######�y######�y##�###�y######Wz##
###`z######jz######yz##�###~z##
###~{######�{######�{######�{######�{######�{######�{######�{##
####|##
####|######*|## ###J|##!###k|##!###�|######�|######�|######�|######�|######�|
######�|######�|##
###�|######
}#######}######'}######A}##-###S}######�}######�}#####�}##
###�}######�}######�}######�}######�}######�}######�}##J####~######\~##+###x~##)###
�~##'###�~##'###�~##-
######+###L##)###x######�######�##*###�##,####�##;###<�######x�##E###��####
##Հ##)###�##'####�##)###@�##&###j�##+###��##e###��#######�##
###(�##+###2�##&###^�## ###��##2###��######‚##�###˂######��######��##
###��##
‫‪###��#####��######��#####��#######‬‬
‫‪##‬ك‪###### ߃######‬‬
###�#######�#######�######3�######F�######W�######i�######�######��######��######
��######Ä##=###Մ##W####�######k�##�###��##E###-�##
###s�######��##)###��######Æ##1###�##-####�## ###@�##"###a�##!###��##7###��##A###
‫އ‬##E### �##3###f�##'###��##0###ˆ##*###�##)####�##*###H�##
%###s�##(###��##,###‰######�##-####�##!
###6�##$###X�##&###}�##'###��##/####
######�##!
####�##'###>�##"###f�######��######��######ы##
%###�##&####�##&###B�##.###i�##(###��##"###L##)###�##4####�######C�######`�######h�
######z�##1###��######��######ō######ʍ######‫ۍ‬######�######�######��#######�######$
�######-�######G�######L�######S�######m�######q�######w�######|�##
###��##=###��##C###Ɏ##t###�##'###��######��##D###��##/###�######$�##
###0�## ###:�##
###D�##7###O�##�###��##�####�######��######��##"###��######ܑ##v###�##Y###[�##N###��
#######�######�#######�##|
###+�##+###��######ԓ######�##O###�######J�######]�######f�######k�######p�######y�#
#####��######��#####��######��##
###ɔ######֔######�######�######�#######�## ####�##
###&�######1�#####G�######U�## ###Z�##
###d�######o�######��######��######��######��######��######��######Ε######ѕ######֕##
###�#####�#####�###### �#######�######(�##=###.�##�###l�##p###N�#####��######?�##
###E�######P�######f�######x�######��######��##q###��##+###$�######P�######W�##
###^�######i�######z�##
###�######��##
###��######��## ###��######��######ə######‫ܙ‬##
###�######�######��#######�#####$�##
###2�######<�######B�######b�######u�######��######��######��######��##
###Ț######Ӛ######‫ؚ‬######�######�###### �##
####�######"�##
###+�######6�######F�######_�######s�######��######��######��######��######��######
��######›######Λ######ӛ##
###�######�#######�#######�## ###&�######0�## ###<�######F�##'###O�##�###w�######
�#######�######!�######)�######0�######?�######O�##
###T�######^�######{�######��######��######��## ###��##
###��############ɝ######�#######�#######�######*�######/�######>�######T�######s�#
#####��##
###��######��#####��##!###��###### ‫ڞ‬######�##
###�######�#######�#######�#####!�##;###/�######k�######s�######y�##
###~�######��######��######��######��##M###��#######�##
####�#######�##1###%�######W�##
###\�##
###g�######t�######}�######��##�###��######o�######�##
###��######��##
###��##>###��######�######�######�######�#######�#######�##

####�######(�######:�######R�######g�######l�##�###x�######+�######2�######J�######
d�##
###y�######��######��#####��######��######��#####Σ######
8######�####,##�######�######‫�ܣ‬######@�######R�######c�######f�##}###o�######�##
####�#######�##M###&�##M###t�##J###¥######�#######�#######�#####+�######9�##
###K�######Y�##
###i�######v�######��##x###��#######�######*�######E�##
###M�##E###Z�##;###��######2######�#######�#######��######�######‫�ܧ‬######B�#####
#V�######^�######d�######p�######v�######��##
###��##
###��##
###��######��##
###è##
###Ψ#####ۨ##

###�######�#######�#######�######*�######1�######A�######R�######^�######g�##(###v�
######��######��######ө######�#######�##"###+�##,###N�######{�##^###��######�##'###
#�##M###>�##=###��##{###ʫ######F�######V�######f�##!###r�##*###��######��## ###߬##
###�######�######�##C####�######J�## ###`�######j�######z�######��##
###��######��##
‫‪###��##‬‬ ‫‪#####‬‬
‫‪#### ##‬‬
‫‪######�######�######�##‬׭‪###‬‬
####�#######�######$�## ###*�##
###4�##1###?�######q�#####}�#####��######��##
###��######��##
###n##
###ή######‫ۮ‬######�######�##�####�######�######�##
###�#######�#######�##
####�######(�##y###@�######��######ʰ######Ӱ######۰######�######�######
�##&###0�######W�######q�######��##$###��######r######ɲ##
###�######�#######�##6####�######L�######U�##
###[�##
###h�##
###u�#####��## ###��######��######��######��#####ѳ######߳######�######�##
###�##
####�#######�#######�######�######1�######=�##
###B�#####M�######[�######q�######��######��######��######´###### ‫״‬##
###�######�##p###
�##=###}�#####��##
###ɵ######Ե##
###‫ڵ‬######�##u###�######d�######k�######r�######z�##
###��######��######��##
###��#####��##
###v##O###ζ######�##$###,�##;###Q�######��##>###��######�#####�##

###�#######�#######�######&�######5�######D�##�###L�######θ######�######�######�##
####�######�## ####�#####'�######5�##
###J�##
###W�######d�#####t�######��######��######��######˹######‫ڹ‬######�##
####�##y####�######��######��######��##
###��##7###��######�##
###�######�######
�#######�######%�######.�######=�######D�######T�######d�##
###k�######u�######��######��######��######ͻ######�######�##
###�#######�##>####�######V�######^�######m�######~�######��######��##
###��######��######��######��######��######ȼ######‫ؼ‬## ###�######�######�##
###�#######�###### �######;�##
###O�######\�######o�######��######��#####��##
###��######��######ǽ######ֽ######�######�##
###�######��#######�###### �######2�######G�## ###[�######e�##
###q�######~�######��######��######��######��######;######�######�#######�##
###(�######3�######?�######K�##
###\�#####i�######w�## ###��##
###��##9###��##9###ҿ##�###
�##I###��##2###��##�###(�##C###��##�###��##�###}�##z###5�##T###��##+####�##A###1�##
;###s�##U###��##S####�######Y�##�###[�##L####�##G###i�##8###��##[###��##�###F�##�##
#��##�###�##�###/�##�###��##?###6�##O###v�##k###��##l###2�##l###��##]###
�##�###j�##`###��##_###^�##;###��##9###��######4�######C�######V�######h�##
###z�######��##M###��##:###��##1####�##>###U�##*###��##2###��##,###��##M####�##U###
m�##3###��##W###��##-###O�##N###}�##6###��##W####�##-
###[�##Q###��##*###��##K####�##1###R�##R###��##,###��##D####�##P###I�##2###��##S###
��##O###!�##/###q�##P###��##6###��##Q###)�##/###{�##P###��##?
###��##Q###<�##+###��##L###��##.####�##O###6�##:###��##1###��##C###��##h###7�##C###
��##�###��##)###�##I###��######��##x####�##8###��##g###��##d###%�##�###��##
###0�######:�#####A�######O�######[�## ###`�######j�##
###p�######{�######��##
###��######��## ###��######��##
###��######��######��######��######��#######�##b####�##�###i�#######�#######�##=###
#�## ###Q�##"###[�######~�##8###��######��##5###��## ####�#######�######"�##?
###1�##a###q�##�###��##u###p�##I###��##H###0�##\###y�##W###��######.�######>�##J###
G�######��######��######��######��##
###��######��##
###��##
###��######��#######�##$####�######8�##
###P�##
###[�##�###i�##`###��######Z�##.###j�######��######��##f###��#######�##'###>�##�###
f�##3###*�##.###^�##=###��##<###��#######�##<###
�######J�######Q�######W�######c�######o�######��######��######��##h###��##�###��##
�###��######
�##�####�##]###��##\###��##K###Y�##`###��##Y####�##U###`�##r###��##`###)�##V###��##
W###��##]###9�#####��##N####�##�###f�#######�######4�##
###X�######e�##
###t�######�######��######��##
###��## ###��##
###��######��#######�#######�######(�######L�##
###U�##�###_�##5###Q�##0###��######��##4###��##*####�######,�######<�##
###W�######e�######u�##�###��#####\�## ###j�##+###��##
###��#####��##R###��##
###%�##
###2�##
###?�##
###L�##
###Y�##�###f�##�###��##]###��##<###��##�####�######��##�###��##�###��##I###��##
###"�##a###-
�######��##;###��##j###��##s###N�######�##m###�##�###9�##"###��##9###�#############
#)###�###;###�###3###�###-###$###%###�###J###�#######�###�###�###�###�###Q#######?
###
###P###
###]#######j#######�#######�#######�#######�######�#######�#######�########
####### ######. ######D ######U ##D###i ##9###�
######� ######� ##,####
######4
######L
######d
##$###x
######�
##)###�
##!###�
##$#######@###(###�###i###y###(
##%###�
##�###�
######�##=###�######�## ###########%#######8###
###A#######N#######U#######Z###�###c###U###>###
###�### ###�###2###�#######�#######�###################,###########J###
###i#######w#######�#######�#######�#######�#######�########### ###
###�###A###"##########(#######6###�###F###�###�###�###x###d###X###
###�#######�#######�#######�###%###�###,#######
###J#######X#######g#######{#######�###�###�#######t#######�#######�###3###�###!
###�###############.### ###G#######h### ##########�#######�###
###�#######�#######�###########
###########$#######4#######;#######K#######\#######c###
###t##########!###�###!###�#######�######�#######�######## ##�###9 ##\###�
##�###*!##�###�!##�###/######�$######�$######�$#####�$#####�$##$####%#####-%##
###;%######F%######X%######r%######�%######�%##
###�%######�%######�%######�%######�%######�%##
####&##
####&#######&######4&######F&##!###Z&######|&#####�&##
%###�&######�&##>###�&#######'######$'######;'##
###O'######p'######�'######�'######�'######�'######�'######�'##T###�'######N(######
W(######`(######|(## ###�(## ###�(######�(##
###�(##
###�(######�(######
)
#######)#######)######3)######B)######a)######h)######�)######�)######�)##�###�)###
###Z*##%###u*######�*##�###�*##�###e+##�###,######�,##�###�,##]###�-##�####.##
###�.##&###�.#######/######7/######V/######z/##"###�/######�/######�/######�/######
�/#######0######!0######10##B###A0######�1##-###�1##
###�1######�1######�1######�1#######2######'2######02######<2######E2######]2##
###m2##�###{2##�###84######�4######�4##
####5##
####5##D####5######a5######q5##"###�5##+###�5######�5##
###�5######�5#######6###### 6######66######P6######b6######t6######�6##
%###�6######�6##�###�6######�7######�7######�7#####�7##�###�7######�9##
###�9######�9##"###�9## ###�9#######:##0###
%:##5###V:######�:######�:######�:######�:#####�:######�:######�:#######;##
####;#######;##$###*;######O;##
###V;######a;#####z;##8###�;##'###�;######�;#######<##
###!<######,<######3<##
###C<##-###N<##*###|<######�<##,###�<##
###�<######�<##`####=##*###t=##I###�=##B###�=##7###,>##H###d>##j###�>##9####?
##I###R?##,###�?##3###�?##D###�?##4###B@##d###w@##/###�@##P###
A##*###]A##I###�A##E###�A##K####B##I###dB##Q###�B##�####C######�C######�C##]###�C##
C###,D######pD######�D######�D######�D##
###�E######�E######�E######�E#######F##
###3F######>F######RF######fF##&###�F######�F##0###�F##5###�F##'###(G##
%###PG##)###vG##%###�G######�G##7###�G#######H######.H##-
###IH##g###wH##�###�H##=###�I##�###�I##�###�J## ###hK##9###�K##H###�K##A###
L##h###NL##R###�L##:###
M##:###EM##:###�M##^###�M##a####N##_###|
N##W###�N##7###4O##@###lO##2###�O##9###�O##:####P##5###UP##0###�P##:###�P##+###�P##
H####Q##>###lQ##>###�Q##>###�Q##?
###)R##G###iR##8###�R##9###�R##A###$S##=###fS##E###�S##B###�S##B###-
T##9###pT##B###�T##D###�T##I###2U##L###|
U##9###�U##C####V##U###GV##*###�V######�V##!###�V######�V##<###
W######GW#####]W##$###kW######�W######�W######�W######�W##)###�W#######X#######X##
###,X##
###:X######EX######LX######`X######iX######rX######{X##}###�X##~####Y##�###�Y##A###
iZ######�Z##T###�Z##I####[######Q[######g[######y[######�[##q###�[##�####\##�###�\#
#####�]##
####^#######^##
###&^##.###1^######`^##
###p^######{^##&###�^######�^##�###�^##1###�_######�_##"###�_##�###�_######�`######
�`######�`######�`######�`######�`##'###�`##
###%a######0a## ###Ba######ca######wa######�a##
###�a######�a##$###�a######�a#######b##)####b######Cb######]b######qb######�b##
###�b######�b######�b######�b##<###�b##3####c######Cc##
###Lc##
###Wc######bc######tc######�c######�c######�c######�c######�c##c####d##W###ed##l###
�e##�###*f##
###�f######�f######�f######�f##
###�f#######g#######g##�###
%g#######h#######h######,h######>h######Ph######gh######nh######�h######�h######�h#
####�h######�h##%###�h##
####i#######i#######i##
###,i######7i######@i######Ti######]i##:###fi##,###�i##$###�i######�i######�i######
#j######3j######Qj######ij##$###nj######�j######�j######�j######�j##
###�j#######k#######k###### k##"###:k######]k######qk##
%###zk######�k##�###�k######`l######l######�l######�l##O###�l######�l######�l##P#
###m######bm######�m######�m######�m######�m######�m##�###�m######�n######�n######�
n#####�n#######o######"o##
###=o######Jo######ao######qo######�o######�o######�o######�o######�o##
###�o##:####p##P###?p######�p##.###�p######�p######�p######�p##,####q##-
###Iq######wq######�q######�q##+###�q##I###�q##
####r#######r######3r##%###Lr######rr##
###�r######�r##
###�r######�r######�r##
###�r######�r######�r##
####s######&s######As##}###\s######�s######�s######�s##T####t######`t######gt##
###wt######�t######�t######�t##M###�t######.v######Kv######Tv######fv######xv##\###
�v######�v######�v######�v#######w######,w##3###<w######pw##
###�w##9###�w##7###�w#######x######)x##B###:x######}y######�y######�y## ###�y##
###�y######�y#######z#######z######7z######Gz######Yz######kz######�z######�z##M###
�z##
####{#######{######1{######K{######]{##^###z{######�|######�|##
###
}##�####}##�###�}##�####~##
###�~######�~######�~######�~######�~####################5##'###T######|
##�###�##7###��##8###��######�######
�##�####�##l###��##"####�######A�######^�######n�##
%###�######��##)###��######�#######�######
�#######�#######�######5�######E�######U�######e�######u�######��######��######��##
####˃######�##
###�######�##
####�#######�######2�######J�##
###Z�######g�##D###��##2###Ȅ##,###�##.###(�##?###W�##?
###��##C###‫ׅ‬##^####�##:###z�##�###��##F###]�##H###��##�###�##O###{�##�###
ˈ######��##)###��######�######�#######�#######�#######�######7�##
###F�##
###Q�##b###^�##9###J######�#######�##"###.�######Q�######p�######��##!###��##
###ˋ######ً######�#######�#######�##-###,�##
###Z�##"###{�######��######��######��######Ԍ######�######�#######�######,�######I�#
#####_�######~�## ###��######��######ˍ######�##�###��##
###�######�#######�######(�######C�######T�##-
###h�##�###��######*�######D�######a�######j�######q�##.###��##6###��##\###�##(###F
�##,###o�##
###��##�###��######_�##+###p�######��##J###��#######�##�####�##
###��######��######��######Ҕ######�#######�######"�######;�######K�######_�######}�
######��######��######��######ѕ######�#######�######�######)�######H�##
###\�######g�######��##%###��######Ζ##/###�##-####�######K�##$###k�##
%###��######��##)####
##�###�##�###�######��##!###��##
###ՙ######�######�##�####�##
###
�##
####�######"�##
###2�######?�######^�######t�######��######��##
###ě##�###�######x�######��######��######��##�###��##
###:�######E�######`�######r�######��######��######Ý##
###‫۝‬##�###�##!###��##
###Ş######О######�######
�#######�##)###6�######`�##3###��##*###��######�######�#######�##@###)�##>###j�##
###��######ʠ##+###�#######�##"###2�##�###U�######'�######;�##
###O�######\�##~###n�##
###�######�#######�######+�######C�######_�######|
�######��######��######��######ۣ######�######��#######�#######�##N###%�##!
###t�##,###��######ä##'###Ҥ######�##r####�######��######��##
##########٥##
###�######�##
###�#######�######
�#######�######5�##,###H�######u�##
###|�######��##
###��######��##$###��##)###֦#######�#######�##*###4�######_�######~�##+###��##$###��
## ###�##
####�#######�#######�######:�######L�######`�##"###p�######��######��######Ũ######Ψ
##
###ը######�######��#######�######"�######3�######H�######b�######��######��######ȩ#
#####�######�######�#######�##<###8�######u�######��######��######��#####ʪ##a###
‫ت‬##b###:�######��##�###��##�###/�##�###��##^###��##�###�##H###|
�##�###Ű##o###��##S####�##\###m�##Z###ʲ##�###
%�##�###��##�###K�######�##s####�##�###��##6###9�##�###p�##E####�##2###Y�##2###��##
�###��##�###��##Y###m�##�###ǽ##~###P�##�###Ͼ##�###P�##�###ѿ##�###\�##�###
%�##�###��##\###��##^####�######y�######��######��######��######��##
%###��##�####�##h###��##H####�##j###N�##A###��##]###��##D###Y�##h###��##h####�##F##
#p�##j###��##:###"�##a###]�##S###��##j####�##@###~�##d###��##7###$�##Y###\�##I###��
##e####�##:###f�##]###��##c###��##R###c�##f###��##b####�##G###��##c###��##Q###,�##�
###~�##<####�##c###=�##j###��##d###
�##C###q�##X###��##F####�##b###U�##P###��##D###

�##Y###N�##�###��##;###A�##�###}�##b###w�##<###��##2####�##�###J�##c####�##�###y�##
�####�##�###��######��######��##,###��##$####�######*�######3�##
###I�######T�######h�######w�######��##'###��######��######��##
###��######��##
###��#######�#######�######'�##�###.�##�###��######��#######�##u####�######��##7###
��######��##Q###��##"###)�##�###L�######��##7###��######&�##y###J�##�###��##�###Q�#
#�###I�##�###��##�###��##�####�##�###��######u�######��#####��##
###��##&###��##
###��######��#######�######)�######F�######Z�##
%###l�##&###��######��##"###��######��#######�##�####�##�####�######��##P####�#####
#_�##'###r�##�###��##<###m�##K###��##4###��##A###+�######m�##_###t�##l###��######A�
##z###J�##
###��######��##
###��######��##
###��#######�#######�######$�##�###5�##�####�##�###��######��##�####�##y###��##�###
B�##{###��##�###A�##�###��##t###[�##�###��##�###e�##x###��##�###a�#####��##�###o�
##{####�##�###��##$###��##)###��######��######��#######�##1####�##(###E�##$###n�###
###��#####��######��##%###��######��#######�##+###"�##
###N�##
###[�###"Add to Cart" Button#"{message}" on line {line} of {file}.#% Comments#%s is
the preset hex color code.#%s added to presets!#%s is the preset hex color code.#%s
is already a saved preset.#%s stands for author name.#By %s#%s stands for custom
branded "Page Builder" name.#%s Settings#%s stands for custom branded "Page
Builder" name.#Launch %s#%s stands for form field label.#Edit %s#%s stands for
post/page title.#Copy of %s#%s stands for the module filename#A module with the
filename %s.php already exists! Please namespace your module filenames to ensure
compatibility with Beaver Builder.#%s stands for the type of node template being
saved.#Save %s#%s stands for widget slug.#%s no longer exists.#0 Comments#1
Column#1 Comment#1865 Winchester Blvd #202 Campbell, CA 95008#2 Columns#3 Columns#4
Columns#5 Columns#6 Columns#<a href="https://www.wpbeaverbuilder.com/go/bb-
facebook" target="_blank">Join the Beaver Builder's Group on Facebook</a>#<a
href="https://www.wpbeaverbuilder.com/go/bb-slack" target="_blank">Join the Beaver
Builder's Group on Slack</a>#<strong>Note</strong>: These settings apply to all
posts and pages.#<strong>UPDATE UNAVAILABLE!</strong>#A CSS and JavaScript file is
dynamically generated and cached each time you create a new layout. Sometimes the
cache needs to be refreshed when you migrate your site to another server or update
to the latest version. If you are running into any issues, please try clearing the
cache by clicking the button below.#A WYSIWYG text editor.#A class that will be
applied to this column's HTML. Must start with a letter and only contain dashes,
underscores, letters or numbers. Separate multiple classes with spaces.#A class
that will be applied to this module's HTML. Must start with a letter and only
contain dashes, underscores, letters or numbers. Separate multiple classes with
spaces.#A class that will be applied to this row's HTML. Must start with a letter
and only contain dashes, underscores, letters or numbers. Separate multiple classes
with spaces.#A client account in Campaign Monitor.#Client#A comma separated list of
tags.#A comma separated list of tags.#Tags#A divider line to separate content.#A
heading and snippet of text with an optional link, icon and image.#A label to
identify this slide on the Slides tab of the Content Slider settings.#A list of
subscribers group from a Mailrelay account.#Group#A photo that will be displayed if
the video fails to load.#A revamped editor with more accurate dragging and
dropping.#A simple call to action button.#A simple pricing table generator.#A tag
to add to contacts in Drip when they subscribe.#Tags#A tag to add to contacts in
Hatchbuck when they subscribe.#Tag#A unique ID that will be applied to this
column's HTML. Must start with a letter and only contain dashes, underscores,
letters or numbers. No spaces.#A unique ID that will be applied to this module's
HTML. Must start with a letter and only contain dashes, underscores, letters or
numbers. No spaces.#A unique ID that will be applied to this row's HTML. Must start
with a letter and only contain dashes, underscores, letters or numbers. No
spaces.#A very simple contact form.#A video from Youtube or Vimeo to use as the
background of this row. Most modern browsers support this format.#A video in the
MP4 format to use as the background of this row. Most modern browsers support this
format.#A video in the MP4 format. Most modern browsers support this format.#A
video in the MP4 to use as the background of this row. Most modern browsers support
this format.#A video in the WebM format to use as fallback. This format is required
to support browsers such as FireFox and Opera.#A video in the WebM format to use as
the background of this row. This format is required to support browsers such as
FireFox and Opera.#API Key#API Token#API URL#Above Bar#Above Heading#Above
Text#Above Title#Accent Color#Accent Text Color#Access Key#Access
Token#Accordion#Account#Account ID#Account Name#Account name for a third party
service such as MailChimp.#Error: An account with that name already exists.#Account
name for a third party service such as MailChimp.#Error: Missing account
name.#Active!#Add Account...#Add Audio Files#Add Content#Add Icon#Add Item#Add More
Content#Add Photos#Add Pricing Box#Add Rows#Add Testimonial#Add a color preset
first.#Add multi-column rows, adjust spacing, add backgrounds and more by dragging
and dropping row layouts onto the page.#Add new content by dragging and dropping
modules or widgets into your row layouts or to create a new row layout.#Add
predefined value.#- Add predefined -#Additional modules: Contact Form, Tabs,
Slider, Pricing Table, Map, Blog Posts, Subscribe Form, Social Icons, and many
more.#Address#Adds a simple subscribe form to your layout.#Advanced#Advanced
Modules#After
Text#Align#Alignment#Alignment.#Center#Alignment.#Left#Alignment.#Right#All rows
will default to this width. You can override this and make a row full width in the
settings for each row.#Along with access to our expert support team, the premium
versions of Beaver Builder are packed with more features to save you time and make
building websites easier!#Always#Always Visible#An animated tesimonials area.#An
email list from ActiveCampaign.#List#An email list from a third party
provider.#List#An email list from third party provider.#List#Animation#Animation
Delay#Animation Speed#Animation style.#Fade In#Animation style.#None#Animation
style.#Slide Down#Animation style.#Slide Left#Animation style.#Slide
Right#Animation style.#Slide Up#App ID#App Password#Append New Layout#Are you sure
you want to remove this account? Other modules that are connected to it will be
affected.#Are you sure?#Arrow Color#Arrows#As you add product categories in the
WooCommerce Products area, each will be assigned a unique ID. This ID can be found
by hovering on the category in the categories area under Products and looking in
the URL that is displayed in your browser. The ID will be the only number value in
the URL.#As you add product categories in the WooCommerce Products area, each will
be assigned a unique slug or you can edit and add your own. These slugs can be
found in the Categories area under WooCommerce Products. Several can be added here
separated by a comma.#As you add products in the WooCommerce Products area, each
will be assigned a unique ID. You can find this unique product ID by visiting the
Products area and rolling over the product. The unique ID will be the first
attribute and you can add several here separated by a comma.#As you add products in
the WooCommerce Products area, each will be assigned a unique ID. You can find this
unique product ID by visiting the Products area and rolling over the product. The
unique ID will be the first attribute.#Ascending#Attachment#Attachment will specify
how the image reacts when scrolling a page. When scrolling is selected, the image
will scroll with page scrolling. This is the default setting. Fixed will allow the
image to scroll within the background if fill is selected in the scale
setting.#Audio#Audio File Selected#Audio Files Selected#Audio
Type#Author#Authorization Code#Authors#Auto Play#Auto will allow the overlay to fit
however long the text content is. 100% will fit the overlay to the top and bottom
of the slide.#Background#Background Color#Background Hover Color#Background Hover
Opacity#Background Layout#Background Opacity#Background Overlay#Background
Parallax#Background Photo#Background Slideshow#Background Video#Background Video
Code#Background height.#Auto#Background repeat.#Horizontal#Background
repeat.#None#Background repeat.#Tile#Background repeat.#Vertical#Background
scale.#None#Background type.#Color#Background type.#None#Background
type.#Parallax#Background type.#Photo#Background type.#Slideshow#Background
type.#Video#Backgrounds#Bar Background Color#Bar Foreground Color#Bar
Styles#Bars#Bars Counter#Basic Modules#Be sure to add your license key for access
to updates and new features.#Beautiful pre-made layout templates.#Beaver Builder
1.9 is out and it has some epic new features:#Beaver Builder caught the following
JavaScript error. If Beaver Builder is not functioning as expected the cause is
most likely this error. Please help us by disabling all plugins and testing Beaver
Builder while reactivating each to determine if the issue is related to a third
party plugin.#Beaver Builder may not be functioning correctly as it does not have
permission to write files to the WordPress uploads directory on your server. Please
update the WordPress uploads directory permissions before continuing or contact
your host for assistance.#Before Text#Below Bar#Below Heading#Below Photo#Below
Text#Best Selling Products#Blinds#Border#Border Color#Border Radius#Border
Size#Border Style#Border size.#Large#Border size.#Medium#Border size.#Small#Border
type.#Dashed#Border type.#Dotted#Border type.#Double#Border type.#None#Border
type.#Solid#Bottom#Bottom Margin#Bottom Width#Box Border#Box Foreground#Box Top
Margin#Boxes#Boxes Grow#Branding#Build your own custom modules.#Button#Button
Colors#Button Icon#Button Icon Position#Button Link#Button Structure#Button
Style#Button Text#Button URL#Button Width#Buttons#Buy Now <i class="fa fa-external-
link-square"></i>#CSS#CSS Class#CSS Selector#Cache#Call To Action#Call to
Action#Call to action.#None#Callout#Cancel#Capitalize#Caption#Caption
Button#Cart#Categories#Category Slug#Center#Center Bottom#Center Top#Change
Template#Change Templates#Check or uncheck modules below to enable or disable
them.#Checkout#Choose Another Photo#Choose a Template#Choose whether to show or
hide this column at different device sizes.#Choose whether to show or hide this
module at different device sizes.#Choose whether to show or hide this row at
different device sizes.#Choose...#Choosing no will hide the default theme heading
for the "Page" post type.
You will also be required to enter some basic CSS for this to work if you choose
no.#Choosing yes will expand the first item by default.#Choosing yes will keep only
one item open at a time. Choosing no will allow multiple items to be open at the
same time.#Circle#Circle Background Color#Circle Bar Styles#Circle Counter#Circle
Foreground Color#Circle Size#Circle Stroke Size#Circle Styles#Class#Clear
Cache#Click Action#Click Here#Click action type.#None#Click action.#None#Clicking
the button below will uninstall the page builder plugin and delete all of the data
associated with it. You can uninstall or deactivate the page builder from the
plugins page instead if you do not wish to delete the data.#Collage#Collapse
Inactive#Colon#Color#Color Picker#Color
Presets#Color.#Dark#Color.#Light#Colors#Column#Column Settings#Column
Width#Columns#Come by and share a project, ask a question, or just say hi! For news
about new features and updates, like our <a
href="https://www.facebook.com/wpbeaverbuilder/" target="_blank">Facebook Page</a>
or follow us <a href="https://twitter.com/beaverbuilder" target="_blank">on
Twitter</a>.#Come by the Beaver Builder Homepage to learn more about what our
premium features can do for you!#Comment Count#Comments#Compact#Connect#Connection
data such as an API key.#Error: Missing service data.#Contact Form#Contact Form
Submission#Contact Support#Contact Support URL#Contact form field
label.#Name#Content#Content Alignment#Content Layout#Content Pages#Content
Slider#Content Type#Content Width#Content type.#None#Control Bar#Control Bar
Buttons#Control Bar Overlay#Control bar overlay specifies if the control bar
buttons you choose overlay your slideshow images or site below the slideshow
completely.#Controls#Countdown#Create Gallery#Crop#Crop set to no will fit the
slideshow images to the height you specify and keep the width proportional, whereas
crop set to yes will fit the slideshow images to all sides of the content area
while cropping the left and right to fit the height you specify.#Current
Page#Custom#Custom Alignment#Custom Font Size#Custom Letter Spacing#Custom Line
Height#Custom Medium Device Width#Custom Small Device Width#Custom URL#Custom
Width#Custom post type label.#Add New#Custom post type label.#Template#Custom post
type label.#Templates#Custom taxonomy label.#Categories#Custom taxonomy
label.#Type#Dark#Date#Date Format#Date Last Modified#Day#Days#Deactivated!
#Default#Default Page Heading#Default Row Content Width#Default Row Width#Default
user template category.#Uncategorized#Delay#Delete#Delete Column#Descending#Disable
All Templates#Disable Right-Click#Disabled#Discard Changes and Exit#Display#Display
a Google map.#Display a WordPress sidebar that has been registered by the current
theme.#Display a WordPress widget.#Display a carousel of your WordPress
posts.#Display a collapsible accordion of items.#Display a collection of tabbed
content.#Display a grid of your WordPress posts.#Display a group of linked Font
Awesome icons.#Display a heading, subheading and a button.#Display a slider of your
WordPress posts.#Display a title/page heading.#Display an icon and optional
title.#Display multiple photos in a gallery view.#Display multiple photos in a
slideshow view.#Display products or categories from your WooCommerce store.#Display
raw HTML code.#Displays multiple slides with an optional heading and call to
action.#Displays social buttons.#Do you really want to delete this column?#Do you
really want to delete this item?#Do you really want to delete this module?#Do you
really want to delete this row?#Do you really want to delete this template?#Do you
really want to discard these changes? All of your changes that are not published
will be lost.#Done#Dot Color#Drop a row layout or module to get started!#Drop us a
line today for a free quote!#Duplicate#Duplicate page/post action label.#Duplicate
Layout#Duration#ERROR! We were unable to connect to the update server. If the issue
persists, please contact your host and let them know your website cannot connect to
updates.wpbeaverbuilder.com.#Edit#Edit Column#Edit Content#Edit Gallery#Edit
Playlist#Email#Email Address#Email Field#Embed#Enable All Templates#Enable
Audio#Enable Contact Support#Enable Core Templates Only#Enable Help Button#Enable
Help Tour#Enable Help Video#Enable Knowledge Base#Enable Templates#Enable User
Templates Only#Enabled#Enabled Modules#Enter License Key#Enter a CSS selector for
the default page heading to hide it.#Enter a comma separated list of the post types
you would like the builder to work with.#Enter a post title to search.#Enter the ID
of a site on the network whose templates should override core builder templates.
Leave this field blank if you do not wish to override core templates.#Enter your <a
%s>license key</a> to enable remote updates and support.#Equal Heights#Equalize
Column Heights#Error! A site with that ID doesn't exist.#Error! Could not unzip
file.#Error! Please enter a date that is in the future.#Error! Please enter a
number for the site ID.#Error! Please enter a valid day.#Error! Please enter a
valid month.#Error! Please enter a valid year.#Error! Please enter an iframe for
the video embed code.#Error! Please upload an icon set from either Icomoon or
Fontello.#Error! You must have at least one feature of the help button
enabled.#Error! You must have at least one icon set enabled.#Error: Could not
connect to Campayn. %s#Error: Could not connect to Constant Contact. %s#Error:
Could not connect to MailerLite. %s#Error: Could not connect to Mailrelay.
%s#Error: Could not connect to SendinBlue. %s#Error: Could not connect to Sendy.
%s#Error: Could not connect to iContact. %s#Error: Could not subscribe to
SendinBlue. %s#Error: Invalid API data.#Error: Please check your API URL and API
key.#Error: Please check your API key.#Error: Please check your API key. %s#Error:
Please check your API token. %s#Error: Please check your Account ID. %s#Error:
Please enter a valid Authorization Code.#Error: You must provide a Host.#Error: You
must provide a app ID.#Error: You must provide a app password.#Error: You must
provide a list ID.#Error: You must provide a username.#Error: You must provide an
API URL.#Error: You must provide an API key.#Error: You must provide an API
token.#Error: You must provide an Access Key.#Error: You must provide an Account
ID.#Error: You must provide an Authorization Code.#Error: You must provide an
access token.#Error: You must provide an app ID.#Error: You must provide an email
address.#Error: You must provide your Sendy installation URL.#Example: page, post,
product#Excerpt#Expand First Item#Expanded#Expert support from our world-class
support team.#Facebook Button#Fade#Fade In On Hover#Fallback Photo#Fast#Featured
Image#Featured Products#Features Min Height#Feed URL#Field name to add.#Add
%s#Fill#Filter#First and last name.#Name#Fit#Fixed#Flat#Font#Font Size#For example,
if your number is 10%, your suffix would be "%".#For example, if your number is US$
10, your prefix would be "US$ ".#For more time-saving features and access to our
expert support team, <a href="%s" target="_blank">upgrade today</a>.#For multiple
tags, separate with comma.#Form#Found in your MailerLite account under Integrations
> Developer API.#Found in your Sendy application under Settings.#Full Height#Full
Size#Full Text#Full Width#Full height rows fill the height of the browser
window.#Full width content spans the width of the page from edge to edge. Fixed
content is no wider than the Row Max Width set in the Global Settings.#Full width
rows span the width of the page from edge to edge. Fixed rows are no wider than the
Row Max Width set in the Global Settings.#Fullscreen Button#Gallery#Gallery layout:
thumbnails.#Thumbs#General#General settings form field label. Intended meaning:
"Enable auto spacing for responsive layouts?"#Enable Auto Spacing#General settings
form field label. Intended meaning: "Responsive layout enabled?"#Enabled#General
settings form field label. Intended meaning: "Show page heading?"#Show#Get Help#Get
More Features#Get Started#Get started by choosing a layout template to customize,
or build a page from scratch by selecting the blank layout template.#Getting
Started - Building your first page.#Getting Started Video#Global Settings#Global
rows and modules can be added to multiple pages and edited in one place.#Google
Plus Button#Gradient#Grid#HTML#HTML Tag#Hamburger Icon#Hamburger Icon +
Label#Heading#Heading Color#Heading Custom Size#Heading Size#Heading
Structure#Heading Tag#Height#Help Button#Help Button Settings#Help Tour#Help
Video#Help Video Embed Code#Helpful Tools#Hide#Highlight#Horizontal#Horizontal
Padding#Host#Hour#Hours#Hover Color#Hover Transition#How many posts to
skip.#Offset#ID#Icon#Icon Colors#Icon Group#Icon Position#Icon Settings#Icon
Structure#Icon Visibility#Icons#Icons for the main site must be managed in the
network admin.#If you can't find an answer, consider upgrading to a premium version
of Beaver Builder. Our expert support team is waiting to answer your questions and
help you build your website. <a href="%s" target="_blank">Learn More</a>.#If you
can't find an answer, feel free to <a href="%s" target="_blank">send us a message
with your question.</a>#If your overall theme/images are lighter in color, light
will display buttons in a darker color scheme and vice versa for dark.#Image#Image
Type#Image size.#Full Size#Image size.#Large#Image size.#Medium#Image
size.#Thumbnail#Image type.#None#Import <strong>posts, pages, comments, custom
fields, categories, and tags</strong> from a WordPress export file.#Indicator for
global node templates.#Global#Inline#Insert#Inside Bar#Installation URL#Item#Item
Spacing#Items#JavaScript#Join the Community#Ken Burns#Knowledge Base#Knowledge Base
URL#Label#Label Size#Label size.#Large#Label size.#Medium#Label size.#Small#Landing
Pages#Landscape#Large#Large
&amp; Medium Devices Only#Large Devices Only#Launch Page Builder#Layout#Layout CSS
/ Javascript#Layout Preview#Layout Templates#Learn More#Left#Left &amp; Right
Sidebar#Left Bottom#Left Center#Left Margin#Left Sidebar#Left Top#Left Width#Left
of Heading#Left of Text and Heading#Let's Get Building!#Letter
Spacing#License#License key saved!#Light#Lightbox#Lightbox Content#Line#Line
Height#Link#Link Background Hover Color#Link Color#Link Format#Link Hover
Color#Link No Follow#Link Size#Link Target#Link Type#Link URL#Link
placeholder#http://www.example.com#Link type applies to how the image should be
linked on click. You can choose a specific URL, the individual photo or a separate
page with the photo.#Link type.#None#List#List ID#Locked#Logged In User#Logged Out
User#Loop#Lowercase#MailChimp list group.#Groups#Manage Templates#Map#Margins#Max
Content Width#Max Width#Media Library#Medium#Medium &amp; Small Devices Only#Medium
Device Breakpoint#Medium Device Width#Medium Devices Only#Menu#Menu Alignment#Menu
Background Color#Menu Background Color (Mobile)#Menu Background Opacity#Menu
Button#Menu Order#Message#Message Sent!#Message failed. Please try
again.#Minute#Minutes#Mobile Photo#Mobile Structure#Mobile Text
Colors#Module#Module Saved!#Module settings form tab. Display on mobile
devices.#Mobile#Modules#Month#More#More Link#More Link Text#Move#Move Column#Move
Parent#Move your mouse over rows, columns or modules to edit and interact with
them.#Multiple Products#My Account#NOTE:#NOTE: Not all custom post types may be
supported.#Name#Name Field#Nav Position#Nav Type#Nav type.#None#Navigation
Arrows#Navigational arrows allow the visitor to freely move through the images in
your slideshow. These are larger arrows that overlay your slideshow images and are
separate from the control bar navigational arrows.#Need Some Help?#Never#New
Column#New Row#New Window#New content page templates available in the template
selector.#Next#No#No Group#No Menus Found#No Photo#No Results Message#No Thanks#No
results found.#No saved modules found.#No saved rows found.#None#Not Active!#Now
that you know the basics, you're ready to start building! If at any time you need
help, click the help icon in the upper right corner to access the help menu. Happy
building!#Number#Number Background Color#Number Background Opacity#Number Border
Radius#Number Color#Number Counter#Number Position#Number Prefix#Number Size#Number
Spacing#Number Suffix#Number Type#Number of Posts#Number of Products#Number of
seconds to complete the animation.#Numbers#Numbers + Circles#Numbers and Text#OK#On
Hover#Once you're finished, click the Done button to publish your changes, save a
draft or revert back to the last published state.#One feature per line. HTML is
okay.#Only Numbers#Opacity#Optional. Set the <a%s>capability</a> required for users
to view this column.#Optional. Set the <a%s>capability</a> required for users to
view this module.#Optional. Set the <a%s>capability</a> required for users to view
this row.#Order#Order By#Order Tracking#Other Modules#Overall Alignment#Overlay
Color#Overlay Enabled#Overlay Hide#Overlay Hide Delay#Overlay Opacity#Overlay hide
will hide the control bar after however many seconds you specify below. They will
reappear upon mouse over.#Override Core Templates#Override network settings?
#Padding#Page Builder#Page Builder activated! <a%s>Click here</a> to enable remote
updates.#Page Builder activated! <a%s>Click here</a> to get started.#Pages → Add
New#Pagination Style#Pagination style.#None#Panorama#Parent Category ID#Parent
Settings#Paste color here...#Percent#Phone#Phone Field#Photo#Photo Count#Photo
Crop.#None#Photo File#Photo Link#Photo Page#Photo Selected#Photo Size#Photo
Source#Photo Spacing#Photo URL#Photo size.#Large#Photo size.#Medium#Photo
size.#Small#Photos#Photos Selected#Pinterest Button#Play Button#Playback#Please
Wait...#Please connect an account before saving.#Please enter a color first.#Please
enter a message.#Please enter a subject.#Please enter a valid email address.#Please
enter a valid email.#Please enter a valid phone number.#Please enter at least one
tag before saving.#Please enter your name.#Please register this website with AWeber
to get your Authorization Code. <a%s>Register Now</a>#Please select a list before
saving.#Please select an account before saving.#Please select either a background
layout or content layout before submitting.#Please subscribe to enable automatic
updates for this plugin.#Please type "uninstall" in the box below to confirm that
you really want to uninstall the page builder and all of its data.#Plugin
Branding#Plugin Icon URL#Plugin Name#Plugin action link label.#Upgrade#Plugin setup
page: Delete icon set.#Delete#Plugin setup page: Modules.#All#Plus
sign#Popularity#Portrait#Position#Position will tell the image where it should sit
in the background.#Post Hover Transition#Post Icon#Post Icon Color#Post Icon
Position#Post Icon Size#Post Info#Post Max Width#Post Spacing#Post Type#Post
Types#Post Width#Posts#Posts Carousel#Posts Per Page#Posts Slider#Premium
Features#Price#Price Box#Price Size#Price features displayed in pricing
box.#Features#Pricing Box#Pricing Boxes#Pricing Table#Product Category#Product
ID#Product IDs#Product Page#Products IDs#Products Source#Publish Changes#Publish
Your Changes#Pull images from the WordPress media library or a gallery on your
SmugMug site by inserting the RSS feed URL from SmugMug. The RSS feed URL can be
accessed by using the get a link function in your SmugMug gallery.#Random#Random
Bars#Random Boxes#Randomize Photos#Rating#Read More#Ready to find out more?#Ready
to start building? Add a new page and jump into Beaver Builder by clicking the Page
Builder tab shown on the image.#Recent Products#Redirect#Regular#Remove#Remove
Account#Render a Countdown module.#Render a WordPress audio shortcode.#Render a
WordPress or embedable video.#Renders a WordPress menu.#Renders an animated number
counter.#Repeat#Repeat applies to how the image should display in the background.
Choosing none will display the image as uploaded. Tile will repeat the image as
many times as needed to fill the background horizontally and vertically. You can
also specify the image to only repeat horizontally or vertically.#Replace#Replace
Existing Layout#Replace Video#Reset Column Widths#Responsive Layout#Responsive
settings for margins, paddings and borders.#Reversed#Right#Right Bottom#Right
Center#Right Margin#Right Sidebar#Right Top#Right Width#Right of Heading#Right of
Text and Heading#Round Corners#Rounded#Row#Row Layouts#Row Saved!#Row
Settings#Row/Module: %s#Rows#Sale Products#Same Window#Save#Save As...#Save
Branding#Save Changes and Exit#Save Core Template#Save Help Button Settings#Save
Icon Settings#Save License Key#Save Module Settings#Save Post Types#Save
Template#Save Template Settings#Save the current layout as a template that can be
reused under <strong>Templates &rarr; Your Templates</strong>.#Save, export, and
reuse full-page layouts, rows, and modules.#Saved Modules#Saved Rows#Scale#Scale
Down#Scale Up#Scale applies to how the image should display in the background. You
can select either fill or fit to the
background.#Scroll#Second#Seconds#Select#Select Audio#Select File#Select
Icon#Select Photo#Select Photos#Select Video#Select a WordPress menu that you
created in the admin under Appearance > Menus.#Select a city#Select a form a
ActiveCampaign.#Form#Select option for showing all icon libraries.#All
Libraries#Select the list type.#Type#Select the post types you would like the
builder to work with.#Send#Send To Email#Separator#Separator Color#Separator
Opacity#Separator Size#Separator Type#Service#Setting this to yes will make all of
the columns in this group the same height regardless of how much content is in each
of them.#Settings updated!#Show#Show Arrows#Show Artist Name#Show Caption#Show
Captions#Show Dots#Show Facebook#Show Featured Image?#Show Google+#Show
Message#Show Play/Pause#Show Playlist#Show Saved Module Categories?#Show Saved Row
Categories?#Show Separators#Show Thumbnail#Show Time Separators#Show Track
Numbers#Show Twitter#Show saved row and module categories as sections in the page
builder sidebar. A new section will be created for category.#Sidebar#Single
Product#Size#Skin Color#Skip this many posts that match the specified
criteria.#Slide#Slide Down#Slide Horizontal#Slide Label#Slide Settings#Slide
Up#Slide Vertical#Slider#Slider Controls#Slider Settings#Slides#Slideshow#Slideshow
transition type.#None#Slideshow transition.#None#Slow#Small Device Breakpoint#Small
Device Width#Small Devices Only#Social#Social Button#Social Buttons#Something went
wrong. Please check your entries and try again.#Sort By#Sort Direction#Sort
by.#Default#Source#Spacing#Speed#Speed.#Medium#Square#Stacked#Stacking
Order#Standard#Start typing...#Straight#Structure#Style#Subject#Subject
Field#Submenu Background Color#Submenu Background Opacity#Submenu Drop
Shadow#Submenu Icon#Submenu Icon click#Submit for Review#Subscribe Form#Subscribe
Form Signup#Subscribe Now#Subscribe!#Success#Success Action#Success URL#Tabs#Take a
Tour#Target URL#Template Exporter#Template Saved!#Template Settings#Template
name.#Blank#Template name.#Name#Templates#Testimonial#Testimonials#Text#Text &amp;
Photo#Text &amp; Video#Text After Number#Text Background Color#Text Background
Gradient#Text Background Height#Text Background Opacity#Text Before Number#Text
Color#Text Colors#Text Editor#Text Hover Color#Text Padding#Text Position#Text
Shadow#Text Size#Text Width#Text to appear above the number. Leave it empty for
none.#Text to appear after the number. Leave it empty for none.#Thank you for
choosing Beaver Builder and welcome to the colony! Find some helpful information
below. Also, to the left are the Page Builder settings options.#Thanks for
subscribing! Please check your email for further instructions.#Thanks
for your message! We’ll be in touch soon.#The <strong>Page Builder</strong> plugin
requires WordPress version 3.5 or greater. Please update WordPress before
activating the plugin.#The Beaver Builder Booster plugin is not compatible with
your host.#The ID of the list you would like users to subscribe to. The ID of a
list can be found under "View all lists" in the section named ID.#The Target URL
field correlates to the page you would like your social icons to interface with.
For example, if you show Facebook, the user will "Like" whatever you put in this
field.#The Tools button lets you save a template, duplicate a layout, edit the
settings for a layout or edit the global settings.#The URL where your Sendy
application is installed (e.g. http://mywebsite.com/sendy).#The ability to drag,
drop and nest columns.#The alignment that will apply to all elements within the
callout.#The amount of time in seconds before this animation starts.#The browser
width at which the layout will adjust for medium devices such as tablets.#The
browser width at which the layout will adjust for small devices such as phones.#The
builder does not delete the post meta <code>_fl_builder_data</code>,
<code>_fl_builder_draft</code> and <code>_fl_builder_enabled</code> in case you
want to reinstall it later. If you do, the builder will rebuild all of its data
using those meta values.#The caption pulls from whatever text you put in the
caption area in the media manager for each image. The caption is also pulled
directly from SmugMug if you have captions set in your gallery.#The color applies
to the overlay behind text over the background selections.#The contact form will
send to this e-mail. Defaults to the admin email.#The email address associated with
your Mad Mimi account.#The fastest way to find an answer to a question is to see if
someone's already answered it!#The first %s stands for custom branded "Page
Builder" name. The second %s stands for the post type name.#%1$s is currently
active for this %2$s.#The host you chose when you signed up for your account. Check
your welcome email if you forgot it. Please enter it without the initial http://
(e.g. demo.ip-zone.com).#The host you chose when you signed up for your account.
Check your welcome email if you forgot it. Please enter it without the initial
http:// (for example: demo.campayn.com).#The link applies to the entire module. If
choosing a call to action type below, this link will also be used for the text or
button.#The link applies to the entire slide. If choosing a call to action type
below, this link will also be used for the text or button.#The max width that the
content area will be within your slides.#The order of the columns in this group
when they are stacked for small devices.#The position will move the content layout
selections left or right or center of the thumbnail of the slide.#The position will
move the content layout selections left, right or bottom over the background of the
slide.#The position will move the content layout selections left, right or center
over the background of the slide.#The settings you are currently editing will not
be saved if you navigate away from this page.#The total number of units for this
counter. For example, if the Number is set to 250 and the Total is set to 500, the
counter will animate to 50%.#The type of border to use. Double borders must have a
height of at least 3px to render properly.#The type of border to use. Double
borders must have a width of at least 3px to render properly.#The width of this
column on medium devices such as tablets.#The width of this column on small devices
such as phones.#Theme Branding#Theme Company Name#Theme Company URL#Theme
Description#Theme Name#Theme Screenshot URL#There was a problem retrieving your
lists. Please check your API credentials.#There was an error connecting to AWeber.
Please try again.#There was an error connecting to Infusionsoft. %s#There was an
error connecting to SendinBlue. Please try again.#There was an error retrieveing
your lists.#There was an error searching contact from Drip. %s#There was an error
subscribing to AWeber. %s#There was an error subscribing to AWeber. The account is
no longer connected.#There was an error subscribing to ActiveCampaign. The account
is no longer connected.#There was an error subscribing to Campaign Monitor.#There
was an error subscribing to Campaign Monitor. The account is no longer
connected.#There was an error subscribing to Campayn. %s#There was an error
subscribing to Campayn. The account is no longer connected.#There was an error
subscribing to Constant Contact. %s#There was an error subscribing to Constant
Contact. The account is no longer connected.#There was an error subscribing to
ConvertKit.#There was an error subscribing to ConvertKit. The account is no longer
connected.#There was an error subscribing to Drip. %s#There was an error
subscribing to Drip. The account is no longer connected.#There was an error
subscribing to GetResponse. %s#There was an error subscribing to GetResponse. The
account is no longer connected.#There was an error subscribing to Hatchbuck.#There
was an error subscribing to Hatchbuck. The API key is invalid.#There was an error
subscribing to Hatchbuck. The account is no longer connected.#There was an error
subscribing to Infusionsoft. %s#There was an error subscribing to Infusionsoft. The
account is no longer connected.#There was an error subscribing to Mad Mimi. The
account is no longer connected.#There was an error subscribing to MailChimp.
%s#There was an error subscribing to MailChimp. The account is no longer
connected.#There was an error subscribing to MailerLite. Code: %s#There was an
error subscribing to MailerLite. The account is no longer connected.#There was an
error subscribing to Mailrelay. %s#There was an error subscribing to Mailrelay. The
account is no longer connected.#There was an error subscribing to SendinBlue.
Please try again.#There was an error subscribing to SendinBlue. The account is no
longer connected.#There was an error subscribing to Sendy. %s#There was an error
subscribing to Sendy. The account is no longer connected.#There was an error
subscribing to iContact. %s#There was an error subscribing to iContact. The account
is no longer connected.#There was an error subscribing. MailPoet is not
installed.#There was an error subscribing. Please try again.#There was an error
subscribing. The account is no longer connected.#There's a wonderful community of
"Beaver Builders" out there and we'd love it if <em>you</em> joined us!#Third party
service such as MailChimp.#Error: Missing service type.#This allows you to add
content over or in addition to the background selection above. The location of the
content layout can be selected in the style tab.#This applies to all sites on the
network.#This does not appear to be a WXR file, missing/invalid WXR version
number#This field is required.#This only applies to this site. Please visit the
Network Admin Settings to clear the cache for all sites on the network.#This
setting is for the entire background of your slide.#This setting is the minimum
height of the content slider. Content will expand the height automatically.#This
setting is the minimum height of the post slider. Content will expand the height
automatically.#This version of the <strong>Page Builder</strong> plugin is not
compatible with WordPress Multisite. <a%s>Please upgrade</a> to the Multisite
version of this plugin.#Thumbnail#Thumbs#Thumbs Button#Thumbs Size#Time#Time
Zone#Title#Title Size#Tools#Top#Top Margin#Top Rated Products#Top
Width#Total#Transition#Transition Speed#Transition type.#Slide#Transparent#Twitter
Button#Type#UPDATES UNAVAILABLE! Please subscribe or enter your license key below
to enable automatic updates.#UPDATES UNAVAILABLE! Your subscription is active but
this domain has been deactivated. Please reactivate this domain in your account to
enable automatic updates.#URL#UTC#Unable to connect to Mad Mimi. Please check your
credentials.#Uninstall#Updates &amp; Support Subscription#Upgrade#Upgrade Today <i
class="fa fa-external-link-square"></i>#Upload Icon Set#Upload a photo or display
one from the media library.#Uppercase#Use Icon for Posts#Use Main Photo#Use an easy
drag-and-drop builder to edit content on this page.#Use the Add Content button to
open the content panel and add new row layouts, modules or widgets.#Use the
Templates button to pick a new template or append one to your layout. Appending
will insert a new template at the end of your existing page content.#Use the action
buttons to perform actions such as moving, editing, duplicating or deleting rows,
columns and modules.#Use this setting to enable or disable templates in the builder
interface.#Use this setting to override core builder templates with your
templates.#Use this to normalize the height of your boxes when they have different
numbers of features.#Used to identify this connection within the accounts list and
can be anything you like.#User Capability#Username#Value unit for form field of
time in seconds. Such as: "5 seconds"#seconds#Vertical#Vertical Padding#Video#Video
(MP4)#Video (WebM)#Video Embed Code#Video Link#Video Type#Video URL (MP4)#Video URL
(WebM)#Video preview/fallback image.#Poster#View the Knowledge
Base#Visibility#Visit Account#WARNING! You are about to delete a global template
that may be linked to other pages. Do you really want to delete this template and
unlink it?#Warning! Changing the template will replace your existing layout. Do you
really want to do this?#Watch the Video#We take pride in offering outstanding
support.#Welcome#Welcome to Beaver Builder!#Welcome! It looks like this might be
your first time using the builder. Would you like to take a tour?#What would you
like to do?#What's New in Beaver Builder 1.9 Shasta#When auto spacing is enabled,
the builder will automatically adjust
the margins and padding in your layout once the small device breakpoint is
reached. Most users will want to leave this enabled.#Where to display the number in
relation to the bar.#Whether this is a global row or module.#Global#White label the
page builder plugin using the settings below.#White label the page builder theme
using the settings below.#Wide#Wide is for 1 column rows, compact is for multi-
column rows.#Widget#Width#Width.#Auto#WooCommerce#WordPress Widgets#Year#Yes#Yes
Please!#You can choose a different photo that the slide will change to on mobile
devices or no photo if desired.#You currently have two versions of Beaver Builder
active on this site. Please <a href="%s">deactivate one</a> before continuing.#You
haven't saved any templates yet! To do so, create a layout and save it as a
template under <strong>Tools &rarr; Save Template</strong>.#YouTube or Vimeo#Your
API Token can be found in your Drip account under Settings > My User Settings. Or,
you can click this <a%s>direct link</a>.#Your API key can be found in your
ActiveCampaign account under My Settings > Developer > API.#Your API key can be
found in your Campaign Monitor account under Account Settings > API Key.#Your API
key can be found in your Campayn account under Settings > API Key.#Your API key can
be found in your ConvertKit account under Account > Account Settings > API
Key.#Your API key can be found in your GetResponse account under My Account >
GetResponse API.#Your API key can be found in your Hatchbuck account under Account
Settings > Web API.#Your API key can be found in your Infusionsoft account under
Admin > Settings > Application > API > Encrypted Key.#Your API key can be found in
your Mad Mimi account under Account > Settings &amp; Billing > API.#Your API key
can be found in your MailChimp account under Account > Extras > API Keys.#Your API
key can be found in your Mailrelay account under Menu > Settings > API access.#Your
API url can be found in your ActiveCampaign account under My Settings > Developer >
API.#Your Access Key can be found in your SendinBlue account under API &
Integration > Manager Your Keys > Version 2.0 > Access Key.#Your Account ID can be
found in your Drip account under Settings > Site Setup.#Your App ID can be found in
‫‪the URL for your account. For example, if the URL for your account is‬‬
‫‪myaccount.infusionsoft.com, your App ID would be <strong>myaccount</strong>.#Your‬‬
‫‪Constant Contact API key.#Your Constant Contact access token.#Your Message#Your‬‬
‫‪Templates#Your email#Your iContact app ID.#Your iContact app password.#Your‬‬
‫‪iContact username.#Your message#Your name#Your phone#Youtube Or Vimeo‬‬
‫‪URL#example@mail.com#http://www.example.com#http://www.example.com/my-photo.jpg#per‬‬
‫‪Year#second(s)#PO-Revision-Date: 2017-08-14 22:42:41+0000‬‬
‫‪MIME-Version: 1.0‬‬
‫‪Content-Type: text/plain; charset=UTF-8‬‬
‫‪Content-Transfer-Encoding: 8bit‬‬
‫;‪Plural-Forms: nplurals=1; plural=0‬‬
‫‪X-Generator: GlotPress/2.3.1‬‬
‫‪Language: fa‬‬
‫‪Project-Id-Version: BB-Plugin‬‬
‫به تنظیم شده‌ها اضافه شد ‪%s‬کامنت‌ها‪ {file}.#% #‬از }‪ {line‬در خط ”}‪“{message‬دکمه‌ی “افزودن به سبد خرید”‪##‬‬
‫در حال ‪ %s.php‬ماژولی با نام‪ %s#‬کپی از‪ %s#‬ویرایش‪ %s#‬تنظیمات‪#‬اجرای ‪: %s#%s‬قبل ل ذخیره شده است‪#.‬توسط ‪#%s‬‬
‫دیگر وجود ‪ %s#%s‬حاضر وجود دارد‪ .‬با لحاظ کردن نام جدید در نام‌گذاری خود از ساز‌گاری با صفحه‌ساز مطمئن شوید‪#.‬ذخیره‬
‫ندارد‪#.‬هنوز کامنتی گذاشته نشده‪ 1#‬ستونه‪ ۱#‬کامنت‪#‬تهران‪ ،‬میدان ولی‌عصر‪ ،‬خیابان ولی عصر‪ ،‬پلک ‪ 2#16‬ستونه‪ 3#‬ستونه‪4#‬‬
‫"‪#<a href="https://www.wpbeaverbuilder.com/go/bb-facebook‬ستونه‪ 5#‬ستونه‪ 6#‬ستونه‬
‫‪</a>#<a‬به گروه ما در فیس‌بوک بپیوندید>"‪target="_blank‬‬
‫به گروه صفحه‌ساز در >"‪href="https://www.wpbeaverbuilder.com/go/bb-slack" target="_blank‬‬
‫به روز رسانی موجود>‪.#<strong‬نکته‪ :‬این تنظیمات به همه پست ها و صفحات اعمال می شود‪</a>#‬برنامه اسلک بپیوندید‬
‫بصورت اتومات در زمان ساخت هر لیه جدیدی ساخته می شود‪ JavaScript .‬و ‪ CSS‬یک فایل‪!</strong>#‬نیست‬
‫بعضی اوقات کش نیاز دارد در زمان آپدیت یا انتقال سایت به سرور دیگر نوسازی شود‪ .‬اگر با مشکلی مواجه شدید دکمه پایین را‬
‫این ستون اعمال ‪ HTML‬یکتا که بر ‪ Class‬امتحان کنید‪ ،‬شاید با خالی کردن کش مشکل حل می شود‪#.‬ویرایشگر دیداری‪#‬یک‬
‫خواهد شد‪ .‬باید با یک حرف شروع شود و میتواند شامل خط‌تیره‪ ،‬خط‌تیره‌ی بلند‪ ،‬حرف و یا عدد باشد‪ .‬بدون فاصله‪#.‬یک‬
‫این ستون اعمال خواهد شد‪ .‬باید با یک حرف شروع شود و میتواند شامل خط‌تیره‪ ،‬خط‌تیره‌ی بلند‪ HTML ،‬یکتا که بر ‪Class‬‬
‫این ردیف اعمال خواهد شد‪ .‬باید با یک حرف شروع ‪ HTML‬یکتا که بر ‪ Class‬حرف و یا عدد باشد‪ .‬بدون فاصله‪#.‬یک‬
‫را با فاصله از هم جدا کرده و وارد ‪ Class‬شود و میتواند شامل خط‌تیره‪ ،‬خط‌تیره‌ی بلند‪ ،‬حرف و یا عدد باشد‪ .‬می توانید چند‬
‫کنید‪#.‬مشتری‪#‬لیستی از کلیدواژه‌هایی که با کاما ) ‪ ( ,‬از هم جدا باشند‪#.‬کلیدواژه‌ها‪#‬خط جدا کننده برای جدا کردن محتوا‪#.‬یک‬
‫عنوان و یک متن کوتاه به همراه لینک و آیکون و عکس اختیاری‪#.‬یک برچسب برای شناسایی این اسلید در برگه تنظیمات‬
‫اسلیدر محتوا‪#.‬گروه‪#‬تصویری که که در صورت نمایش داده نشدن ویدئو نمابش داده می شود‪#.‬ادیتوری جدید با دقتی بیشتر در‬
‫موقع گرفتن و رها کردن ردیف‌ها و ماژول‌ها‪#.‬دکمه فراخوانی ساده‪#‬سازنده ساده‌ی جدول قیمت‌گذاری‪#‬برچسب ها‪#‬برچسب‬
‫این ستون اعمال خواهد شد‪ .‬باید با یک حرف شروع شود و میتواند شامل خط‌تیره‪ HTML ،‬یکتا که بر ‪) ID‬تگ(‪#‬یک‬
‫این ماژول اعمال خواهد شد‪ .‬باید با یک حرف ‪ HTML‬یکتا که بر ‪ ID‬خط‌تیره‌ی بلند‪ ،‬حرف و یا عدد باشد‪ .‬بدون فاصله‪#.‬یک‬
‫این ردیف ‪ HTML‬یکتا که بر ‪ ID‬شروع شود و میتواند شامل خط‌تیره‪ ،‬خط‌تیره‌ی بلند‪ ،‬حرف و یا عدد باشد‪ .‬بدون فاصله‪#.‬یک‬
‫اعمال خواهد شد‪ .‬باید با یک حرف شروع شود و میتواند شامل خط‌تیره‪ ،‬خط‌تیره‌ی بلند‪ ،‬حرف و یا عدد باشد‪ .‬بدون‬
‫فاصله‪#.‬فرم تماس بسیار ساده‪#.‬استفاده از یک فیلم از یوتیوب یا ویمئو برای پس‌زمینه این ردیف‪ .‬اکثر مرورگرهای امروزی از این‬
‫برای نمایش در پس زمینه این ردیف انتخاب کنید‪ .‬اغلب مرورگرهای ‪ MP4‬امکان پشتیبانی می‌کنند‪#.‬ویدیو پس زمینه را با فرمت‬
‫اکثر مرورگرهای مدرن این فرمت را پشتیبانی ‪ MP4.‬به روز این امکان را پشتیبانی می کنند‪#.‬یک فایل ویدیویی با فرمت‬
‫برای استفاده در پس‌زمینه این ردیف‪ .‬اکثر مرورگرهای امروزی این امکان را پشتیبانی ‪ MP4‬می‌کنند‪#.‬استفاده از یک فیلم‬
‫را به عنوان پشتیبان استفاده کنید‪ .‬این فرمت برای پخش کردن در مرورگرهایی مثل فایرفاکس ‪ WebM‬می‌کنند‪#.‬یک ویدیو با فرمت‬
‫برای نمایش در پس زمینه این ردیف انتخاب کنید‪ .‬این فرمت ‪ WebM‬و اپرا می‌تواند ضروری باشد‪#.‬ویدیو پس زمینه را با فرمت‬
‫بالی ‪ API#‬آدرس لینک‪ API#‬کلید‪ API#‬برای پخش کردن در مرورگرهایی مثل فایرفاکس و اپرا می‌تواند ضروری باشد‪#.‬کلید‬
‫‪ID‬میله‪#‬بالی عنوان‪#‬بالی متن‪#‬بالی عنوان‪#‬شدت رنگ‪#‬شدت رنگ متن‪#‬کلید دسترسی‪#‬کد دسترسی‪#‬آکاردئون‪#‬حساب کاربری‪#‬‬
‫اکانت‪#‬نام کاربری‪#‬خطا‪ :‬حسابی با این نام از قبل وجود دارد‪#.‬خطا‪ :‬نام حساب قابل شناسایی نیست‪#.‬فعال‪#‬افزودن ح‬

Potrebbero piacerti anche