Loco Translate - Version 2.6.0

Version Description

  • Dropped support for WordPress < 5.2
  • Code upgrades for >
Download this release

Release Info

Developer timwhitlock
Plugin Icon 128x128 Loco Translate
Version 2.6.0
Comparing to
See all releases

Code changes from version 2.5.8 to 2.6.0

Files changed (138) hide show
  1. languages/loco-translate.pot +14 -18
  2. lib/compiled/gettext.php +70 -69
  3. lib/compiled/locales.php +3 -2
  4. lib/compiled/phpunit.php +10 -9
  5. lib/data/gp.php +1 -1
  6. lib/data/languages.php +1 -1
  7. lib/data/locales.php +1 -1
  8. lib/data/plurals.php +1 -1
  9. lib/data/regions.php +1 -1
  10. loco.php +6 -8
  11. pub/css/admin.css +1 -1
  12. pub/css/editor.css +1 -1
  13. pub/css/podiff.css +1 -1
  14. pub/css/poview.css +1 -1
  15. pub/css/skins/blue.css +1 -1
  16. pub/css/skins/coffee.css +1 -1
  17. pub/css/skins/ectoplasm.css +1 -1
  18. pub/css/skins/light.css +1 -1
  19. pub/css/skins/midnight.css +1 -1
  20. pub/css/skins/modern.css +1 -1
  21. pub/css/skins/ocean.css +1 -1
  22. pub/css/skins/sunrise.css +1 -1
  23. pub/font/loco.eot +0 -0
  24. pub/font/loco.svg +1 -1
  25. pub/font/loco.ttf +0 -0
  26. pub/font/loco.woff +0 -0
  27. pub/js/min/admin.js +466 -522
  28. readme.txt +13 -5
  29. src/Locale.php +7 -7
  30. src/admin/DebugController.php +6 -6
  31. src/admin/ErrorController.php +1 -1
  32. src/admin/Navigation.php +3 -3
  33. src/admin/RootController.php +10 -10
  34. src/admin/bundle/BaseController.php +5 -5
  35. src/admin/bundle/ConfController.php +8 -8
  36. src/admin/bundle/DebugController.php +4 -4
  37. src/admin/bundle/LocaleController.php +17 -17
  38. src/admin/bundle/SetupController.php +6 -6
  39. src/admin/bundle/ViewController.php +29 -29
  40. src/admin/config/ApisController.php +5 -5
  41. src/admin/config/BaseController.php +4 -4
  42. src/admin/config/DebugController.php +15 -15
  43. src/admin/config/SettingsController.php +7 -7
  44. src/admin/config/VersionController.php +7 -15
  45. src/admin/file/BaseController.php +13 -13
  46. src/admin/file/DeleteController.php +3 -3
  47. src/admin/file/DiffController.php +7 -7
  48. src/admin/file/EditController.php +13 -13
  49. src/admin/file/HeadController.php +2 -2
  50. src/admin/file/InfoController.php +7 -7
  51. src/admin/file/MoveController.php +16 -16
  52. src/admin/file/ViewController.php +8 -8
  53. src/admin/init/InitPoController.php +33 -33
  54. src/admin/init/InitPotController.php +6 -6
  55. src/admin/init/UploadController.php +11 -11
  56. src/admin/list/BaseController.php +11 -11
  57. src/admin/list/LocalesController.php +7 -7
  58. src/ajax/ApisController.php +4 -20
  59. src/ajax/DiffController.php +2 -2
  60. src/ajax/FsConnectController.php +2 -2
  61. src/ajax/FsReferenceController.php +3 -3
  62. src/ajax/MsginitController.php +5 -5
  63. src/ajax/SyncController.php +1 -1
  64. src/ajax/UploadController.php +2 -2
  65. src/ajax/XgettextController.php +4 -4
  66. src/api/Providers.php +12 -17
  67. src/api/WordPressFileSystem.php +7 -7
  68. src/api/WordPressTranslations.php +1 -1
  69. src/api/YandexClient.php +0 -85
  70. src/cli/Commands.php +2 -2
  71. src/cli/ExtractCommand.php +1 -1
  72. src/cli/FetchCommand.php +6 -6
  73. src/cli/SyncCommand.php +1 -1
  74. src/cli/Utils.php +9 -9
  75. src/compat/Failure.php +1 -1
  76. src/compat/MbstringExtension.php +2 -2
  77. src/compat/PosixExtension.php +1 -1
  78. src/compat/TokenizerExtension.php +1 -1
  79. src/config/ArrayModel.php +5 -5
  80. src/config/FormModel.php +19 -19
  81. src/config/Model.php +2 -2
  82. src/data/Cookie.php +1 -1
  83. src/data/Permissions.php +4 -4
  84. src/data/Preferences.php +4 -4
  85. src/data/RecentItems.php +3 -3
  86. src/data/Serializable.php +3 -3
  87. src/data/Session.php +4 -4
  88. src/data/Settings.php +11 -13
  89. src/error/AdminNotices.php +9 -9
  90. src/error/Exception.php +3 -3
  91. src/error/ParseException.php +1 -1
  92. src/fs/File.php +7 -14
  93. src/fs/FileFinder.php +2 -2
  94. src/fs/FileList.php +4 -4
  95. src/fs/FileWriter.php +1 -1
  96. src/fs/LocaleFile.php +1 -1
  97. src/fs/LocaleFileList.php +2 -2
  98. src/fs/Locations.php +11 -11
  99. src/fs/Revisions.php +2 -2
  100. src/fs/Siblings.php +2 -2
  101. src/gettext/Compiler.php +23 -23
  102. src/gettext/Data.php +29 -17
  103. src/gettext/Extraction.php +6 -6
  104. src/gettext/Matcher.php +10 -10
  105. src/gettext/Metadata.php +6 -6
  106. src/gettext/SearchPaths.php +1 -1
  107. src/gettext/String.php +5 -5
  108. src/hooks/AdminHooks.php +5 -5
  109. src/hooks/Hookable.php +4 -4
  110. src/hooks/LoadHelper.php +7 -7
  111. src/hooks/TranslateBuffer.php +2 -2
  112. src/mvc/AdminController.php +12 -16
  113. src/mvc/AdminRouter.php +8 -8
  114. src/mvc/AjaxController.php +2 -2
  115. src/mvc/AjaxRouter.php +10 -10
  116. src/mvc/FileParams.php +6 -6
  117. src/mvc/PostParams.php +3 -3
  118. src/mvc/View.php +4 -4
  119. src/output/DiffRenderer.php +4 -4
  120. src/package/Bundle.php +8 -8
  121. src/package/Core.php +5 -5
  122. src/package/Debugger.php +8 -8
  123. src/package/Inverter.php +7 -7
  124. src/package/Listener.php +11 -11
  125. src/package/Locale.php +2 -2
  126. src/package/Plugin.php +10 -10
  127. src/package/Project.php +7 -7
  128. src/package/Theme.php +9 -9
  129. src/test/DummyFtpConnect.php +2 -2
  130. src/test/WordPressTestCase.php +25 -25
  131. tpl/admin/bundle/view.php +6 -6
  132. tpl/admin/config/apis.php +0 -21
  133. tpl/admin/config/version.php +4 -5
  134. tpl/admin/errors/no-tokenizer.php +2 -2
  135. tpl/admin/file/view-mo.php +2 -2
  136. tpl/admin/init/upload.php +1 -1
  137. tpl/admin/layout.php +0 -9
  138. tpl/admin/root.php +3 -3
languages/loco-translate.pot CHANGED
@@ -1,9 +1,9 @@
1
  #, fuzzy
2
  msgid ""
3
  msgstr ""
4
- "Project-Id-Version: Loco Translate 2.5.8-dev\n"
5
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/loco-translate/\n"
6
- "POT-Creation-Date: 2022-01-26 14:38+0000\n"
7
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
  "Language-Team: \n"
@@ -13,7 +13,7 @@ msgstr ""
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
  "X-Generator: Loco https://localise.biz/\n"
16
- "X-Loco-Version: 2.5.8-dev; wp-5.9\n"
17
  "X-Domain: loco-translate"
18
 
19
  #: src/fs/FileWriter.php:214
@@ -538,9 +538,9 @@ msgstr ""
538
  msgid "Disallow"
539
  msgstr ""
540
 
541
- #: src/data/Settings.php:180 src/admin/file/EditController.php:166
542
  #: src/admin/bundle/LocaleController.php:130 tpl/admin/config/settings.php:234
543
- #: tpl/admin/config/apis.php:149 tpl/admin/config/prefs.php:45
544
  #: tpl/admin/common/inc-fsconn.php:16 tpl/admin/common/inc-fsconn.php:41
545
  #: tpl/admin/errors/no-backups.php:22
546
  msgid "Documentation"
@@ -1003,7 +1003,7 @@ msgstr ""
1003
  msgid "Import config from XML"
1004
  msgstr ""
1005
 
1006
- #: tpl/admin/config/apis.php:139
1007
  msgid "Important"
1008
  msgstr ""
1009
 
@@ -1152,15 +1152,11 @@ msgstr ""
1152
  msgid "Loco Translate %s"
1153
  msgstr ""
1154
 
1155
- #: src/data/Settings.php:179
1156
- msgid "Loco Translate 2.5 adds supports for JSON language pack generation."
1157
- msgstr ""
1158
-
1159
  #: src/mvc/AdminController.php:115
1160
  msgid "Loco Translate is powered by"
1161
  msgstr ""
1162
 
1163
- #: loco.php:143
1164
  #, php-format
1165
  msgid ""
1166
  "Loco Translate requires the \"%s\" PHP extension. Ask your hosting provider "
@@ -1552,7 +1548,7 @@ msgstr ""
1552
  msgid "Save credentials in session"
1553
  msgstr ""
1554
 
1555
- #: tpl/admin/config/settings.php:233 tpl/admin/config/apis.php:148
1556
  #: tpl/admin/config/prefs.php:44
1557
  msgid "Save settings"
1558
  msgstr ""
@@ -1589,7 +1585,7 @@ msgstr ""
1589
  msgid "See FAQ"
1590
  msgstr ""
1591
 
1592
- #: tpl/admin/config/apis.php:142
1593
  msgid "See full disclaimer"
1594
  msgstr ""
1595
 
@@ -1791,7 +1787,7 @@ msgid ""
1791
  "extract strings directly from source code."
1792
  msgstr ""
1793
 
1794
- #: tpl/admin/config/apis.php:141
1795
  msgid ""
1796
  "Third party services are subject to their own terms of use and may incur "
1797
  "costs from the provider"
@@ -2094,7 +2090,7 @@ msgid "WordPress"
2094
  msgstr ""
2095
 
2096
  #. Where %s is the full version number of WordPress
2097
- #: tpl/admin/config/version.php:69
2098
  #, php-format
2099
  msgid "WordPress %s"
2100
  msgstr ""
@@ -2196,9 +2192,9 @@ msgid ""
2196
  msgstr ""
2197
 
2198
  #. (1) Name of software, e.g. "WordPress" (2) Version number, e.g. "5.6"
2199
- #: tpl/admin/config/version.php:53 tpl/admin/config/version.php:72
2200
  #, php-format
2201
  msgid ""
2202
- "Your version of %1$s is very old. We recommend you upgrade to at least v%2$s,"
2203
- " but preferably to the latest stable version."
2204
  msgstr ""
1
  #, fuzzy
2
  msgid ""
3
  msgstr ""
4
+ "Project-Id-Version: Loco Translate 2.6.0\n"
5
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/loco-translate/\n"
6
+ "POT-Creation-Date: 2022-03-08 13:53+0000\n"
7
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
  "Language-Team: \n"
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
  "X-Generator: Loco https://localise.biz/\n"
16
+ "X-Loco-Version: 2.6.0; wp-5.9.1\n"
17
  "X-Domain: loco-translate"
18
 
19
  #: src/fs/FileWriter.php:214
538
  msgid "Disallow"
539
  msgstr ""
540
 
541
+ #: src/admin/file/EditController.php:166
542
  #: src/admin/bundle/LocaleController.php:130 tpl/admin/config/settings.php:234
543
+ #: tpl/admin/config/apis.php:128 tpl/admin/config/prefs.php:45
544
  #: tpl/admin/common/inc-fsconn.php:16 tpl/admin/common/inc-fsconn.php:41
545
  #: tpl/admin/errors/no-backups.php:22
546
  msgid "Documentation"
1003
  msgid "Import config from XML"
1004
  msgstr ""
1005
 
1006
+ #: tpl/admin/config/apis.php:118
1007
  msgid "Important"
1008
  msgstr ""
1009
 
1152
  msgid "Loco Translate %s"
1153
  msgstr ""
1154
 
 
 
 
 
1155
  #: src/mvc/AdminController.php:115
1156
  msgid "Loco Translate is powered by"
1157
  msgstr ""
1158
 
1159
+ #: loco.php:141
1160
  #, php-format
1161
  msgid ""
1162
  "Loco Translate requires the \"%s\" PHP extension. Ask your hosting provider "
1548
  msgid "Save credentials in session"
1549
  msgstr ""
1550
 
1551
+ #: tpl/admin/config/settings.php:233 tpl/admin/config/apis.php:127
1552
  #: tpl/admin/config/prefs.php:44
1553
  msgid "Save settings"
1554
  msgstr ""
1585
  msgid "See FAQ"
1586
  msgstr ""
1587
 
1588
+ #: tpl/admin/config/apis.php:121
1589
  msgid "See full disclaimer"
1590
  msgstr ""
1591
 
1787
  "extract strings directly from source code."
1788
  msgstr ""
1789
 
1790
+ #: tpl/admin/config/apis.php:120
1791
  msgid ""
1792
  "Third party services are subject to their own terms of use and may incur "
1793
  "costs from the provider"
2090
  msgstr ""
2091
 
2092
  #. Where %s is the full version number of WordPress
2093
+ #: tpl/admin/config/version.php:68
2094
  #, php-format
2095
  msgid "WordPress %s"
2096
  msgstr ""
2192
  msgstr ""
2193
 
2194
  #. (1) Name of software, e.g. "WordPress" (2) Version number, e.g. "5.6"
2195
+ #: tpl/admin/config/version.php:53 tpl/admin/config/version.php:71
2196
  #, php-format
2197
  msgid ""
2198
+ "Your version of %1$s is out of date. We recommend you upgrade to at least "
2199
+ "v%2$s, but preferably to the latest stable version."
2200
  msgstr ""
lib/compiled/gettext.php CHANGED
@@ -1,15 +1,16 @@
1
  <?php
2
  /**
3
- * Downgraded for PHP 5.2 compatibility. Do not edit.
 
4
  */
5
  interface LocoArrayInterface extends ArrayAccess, Iterator, Countable, JsonSerializable {
6
  public function getArrayCopy(); }
7
  class LocoHeaders extends ArrayIterator implements LocoArrayInterface {
8
- private $map = array();
9
- public function __construct(array $raw = array() ){ if( $raw ){ $keys = array_keys( $raw ); $this->map = array_combine( array_map( 'strtolower', $keys ), $keys ); parent::__construct($raw); } }
10
  public function normalize( $key ){ $k = strtolower($key); return isset($this->map[$k]) ? $this->map[$k] : null; }
11
  public function add($key, $val ){ $this->offsetSet( $key, $val ); return $this; }
12
- public function __toString(){ $pairs = array(); foreach( $this as $key => $val ){ $pairs[] = $key.': '.$val; } return implode("\n", $pairs ); }
13
  public function trimmed($prop ){ return trim( $this->__get($prop) ); }
14
  public function has($key ){ $k = strtolower($key); return isset($this->map[$k]); }
15
  public function __get($key ){ return $this->offsetGet( $key ); }
@@ -29,7 +30,7 @@ class LocoPoHeaders extends LocoHeaders {
29
  private $cs = null;
30
  public function getCharset(){ $cs = $this->cs; if( is_null($cs) ){ $cs = ''; $raw = $this->offsetGet('content-type'); if( $raw && preg_match('!\\bcharset[= ]+([-\\w]+)!',$raw,$r) ){ try { $cs = loco_normalize_charset($r[1]); } catch( InvalidArgumentException $e ){ $cs = null; } catch( Throwable $e ){ trigger_error( $e->getMessage(), E_USER_NOTICE ); $cs = null; } } $this->cs = $cs; } return $cs; }
31
  public function setCharset( $to ){ $to = loco_normalize_charset($to); $from = $this->getCharset(); $this->cs = $to; $this['Content-Type'] = 'text/plain; charset='.$to; if( $from && $from !== $to ){ foreach( $this as $key => $val ){ $this[$key] = mb_convert_encoding($val,$to,$from); } } return $to; }
32
- public static function fromMsgstr( $str ){ $headers = new LocoPoHeaders; $key = ''; foreach( preg_split('/[\\r\\n]+/',$str) as $line ){ $i = strpos($line,':'); if( is_int($i) ){ $key = trim( substr($line,0,$i), " \t" ); $headers->offsetSet( $key, ltrim( substr($line,++$i)," \t" ) ); } else if( '' !== $key ){ $headers->offsetSet( $key, $headers->offsetGet($key)."\n".$line ); } } $cs = $headers->getCharset(); if( $cs && 'UTF-8' !== $cs && 'UTF-8' !== mb_detect_encoding($str,array('UTF-8',$cs),true) ){ foreach( $headers as $key => $val ){ $headers[$key] = mb_convert_encoding($val,'UTF-8',array($cs)); } } return $headers; }
33
  public static function fromSource( $raw ){ $po = new LocoPoParser($raw); $po->parse(0); return $po->getHeader(); } }
34
  function loco_convert_utf8( $str, $enc, $strict ){ if( '' === $enc || 'UTF-8' === $enc || 'US-ASCII' === $enc ){ if( false === preg_match('//u',$str) ){ if( $strict ){ $e = new Loco_error_ParseException( $enc ? 'Invalid '.$enc.' encoding' : 'Unknown character encoding' ); if( preg_match('/^(?:[\\x00-\\x7F]|[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xFF][\\x80-\\xBF]{3})*/',$str,$r) && $str !== $r[0] ){ $e->setOffsetContext( strlen($r[0]), $str ); } throw $e; } $str = loco_fix_utf8($str); } } else if( 'ISO-8859-1' === $enc ) { $str = mb_convert_encoding( $str, 'UTF-8', 'cp1252' ); } else { $str = mb_convert_encoding( $str, 'UTF-8', $enc ); } return $str; }
35
  function loco_fix_utf8( $str ){ $fix = ''; while( is_string($str) && '' !== $str ){ if( preg_match('/^(?:[\\x00-\\x7F]|[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xFF][\\x80-\\xBF]{3})+/',$str,$r) ){ $fix .= $r[0]; $str = substr($str, strlen($r[0]) ); } else { $fix.= mb_convert_encoding( $str[0], 'UTF-8', 'cp1252' ); $str = substr($str,1); } } return loco_convert_utf8($fix,'',true); }
@@ -45,7 +46,7 @@ protected function str( $str ){ if( '' !== $str ){ $str = loco_convert_utf8($st
45
  function loco_remove_bom( $s, &$c ){ $bom = substr($s,0,2); if( "\xFF\xFE" === $bom ){ $c = 'UTF-16LE'; return substr($s,2); } if( "\xFE\xFF" === $bom ){ $c = 'UTF-16BE'; return substr($s,2); } if( "\xEF\xBB" === $bom && "\xBF" === $s[2] ){ $c = 'UTF-8'; return substr($s,3); } $c = ''; return $s; }
46
  function loco_parse_reference_id( $refs, &$_id ){ if( false === ( $n = strpos($refs,'loco:') ) ){ $_id = ''; return $refs; } $_id = substr($refs, $n+5, 24 ); $refs = substr_replace( $refs, '', $n, 29 ); return trim( $refs ); }
47
  class LocoPoParser extends LocoGettextParser implements Iterator {
48
- private $lines = array();
49
  private $i;
50
  private $k;
51
  private $m;
@@ -59,8 +60,8 @@ public function key(){ return $this->k; }
59
  #[ReturnTypeWillChange]
60
  public function current(){ return $this->m; }
61
  #[ReturnTypeWillChange]
62
- public function next(){ $valid = false; $entry = array( '#' => array(), 'id' => array(null), 'str' => array(null) ); $i = $this->i; while( array_key_exists(++$i,$this->lines) ){ $line = $this->lines[$i]; try { if( '' === $line ){ if( $valid ){ break; } continue; } $c = $line[0]; if( '#' === $c ){ if( $valid ){ $i--; break; } if( '#' === $line ){ continue; } $f = $line[1]; $entry['#'][$f][] = trim( substr( $line, 1+strlen($f) ), "/ \n\r\t" ); } else if( preg_match('/^msg(id(?:_plural)?|ctxt|str(?:\\[(\\d+)])?)[ \\t]*/', $line, $r ) ){ if( isset($r[2]) ){ $key = 'str'; $idx = (int) $r[2]; } else { $key = $r[1]; $idx = 0; } if( $valid && 'str' !== $key && null !== $entry['str'][0] ){ $i--; break; } $snip = strlen($r[0]); if( '"' !== substr($line,$snip,1) ){ throw new Exception('Expected " to follow msg'.$key); } $val = ''; $line = substr($line,$snip); while( true ){ if( '"' === $line || '"' !== substr($line,-1) ){ throw new Exception('Unterminated msg'.$key ); } $val .= substr( $line, 1, -1 ); $j = $i + 1; if( array_key_exists($j,$this->lines) && ( $line = $this->lines[$j] ) && '"' === $line[0] ){ $i = $j; } else { break; } } if( ! $valid ){ $valid = true; } if( 'id_plural' === $key ){ $key = 'id'; $idx = 1; } $entry[$key][$idx] = stripcslashes($val); } else if( preg_match('/^[ \\t]+$/',$line) ){ if( $valid ) { break; } } else if( '"' === $c ){ throw new Exception('String encountered without keyword'); } else { throw new Exception('Junk'); } } catch( Exception $e ){ } } if( $valid ){ ++$this->k; $this->i = $i; $this->m = $entry; } else { $this->i = null; $this->k = null; $this->m = null; } }
63
- public function parse( $limit = -1 ){ $this->rewind(); if( ! $this->valid() ){ throw new Loco_error_ParseException('Invalid PO file'); } $entry = $this->current(); if( '' !== $entry['id'][0] || isset($entry['ctxt']) || is_null($entry['str'][0]) ){ $head = $this->setHeader( new LocoPoHeaders ); } else { $head = $this->setHeader( LocoPoHeaders::fromMsgstr($entry['str'][0]) ); } if( 0 === $limit ){ return array(); } $i = -1; $assets = array(); $lk = $head['X-Loco-Lookup']; while( $this->valid() ){ $entry = $this->current(); $msgid = $entry['id'][0]; if( is_null($msgid) ){ $this->next(); continue; } if( ++$i === $limit ){ return $assets; } $asset = array( 'source' => $this->str( $msgid ), 'target' => $this->str( (string) $entry['str'][0] ), 'context' => null, ); $prev_entry = null; if( isset($entry['ctxt']) ){ $asset['context'] = $this->str( $entry['ctxt'][0] ); } $cmt = $entry['#']; if( isset($cmt[' ']) ){ $asset['comment'] = $this->str( implode("\n", $cmt[' '] ) ); } if( isset($cmt['.']) ){ $asset['notes'] = $this->str( implode("\n", $cmt['.'] ) ); } if( isset($cmt[':']) ){ if( $refs = implode( ' ', $cmt[':'] ) ) { $refs = $this->str($refs); if( $refs = loco_parse_reference_id( $refs, $_id ) ){ $asset['refs'] = $refs; } if( $_id ){ $asset['_id'] = $_id; } } } if( isset($cmt[',']) ){ foreach( $cmt[','] as $flags ){ foreach( explode(',',$flags) as $flag ){ if( $flag = trim($flag," \t") ){ if( preg_match('/^((?:no-)?\w+)-format/', $flag, $r ) ){ $asset['format'] = $r[1]; } else if( 'fuzzy' === $flag ){ $asset['flag'] = 4; } } } } } if( isset($cmt['|']) ){ $p = new LocoPoParser(''); $p->lines = $cmt['|']; $p->setCharset( $this->getCharset() ); try { $prev_entry = $p->parse(); } catch( Loco_error_ParseException $e ){ } if( $prev_entry ){ $msgid = $prev_entry[0]['source']; if( $lk && 'text' !== $lk ){ $asset[$lk] = $asset['source']; $asset['source'] = $msgid; } else if( 'loco:' === substr($msgid,0,5) ){ $asset['_id'] = substr($msgid,5); } else { $asset['prev'] = $prev_entry; $prev_entry = null; } } } $assets[] = $asset; if( isset($entry['id'][1]) ){ $idx = 0; $pidx = count($assets) - 1; $num = max( 2, count($entry['str']) ); while( ++$idx < $num ){ $plural = array( 'source' => '', 'target' => isset($entry['str'][$idx]) ? $this->str($entry['str'][$idx]) : '', 'plural' => $idx, 'parent' => $pidx, ); if( 1 === $idx ){ $plural['source'] = $this->str($entry['id'][1]); if( is_array($prev_entry) && isset($prev_entry[1]) ){ if( $lk && 'text' !== $lk ){ $plural[$lk] = $plural['source']; $plural['source'] = $prev_entry[1]['source']; } } } if( isset($asset['flag']) ){ $plural['flag'] = $asset['flag']; } $assets[] = $plural; } } $this->next(); } if( -1 === $i ){ throw new Loco_error_ParseException('Invalid PO file'); } else if( 0 === $i && '' === $assets[0]['source'] && '' === $assets[0]['target'] ){ throw new Loco_error_ParseException('Invalid PO file' ); } return $assets; } }
64
  class LocoMoParser extends LocoGettextParser {
65
  private $bin;
66
  private $be;
@@ -70,7 +71,7 @@ private $t;
70
  private $v;
71
  public function __construct( $bin ){ $this->bin = $bin; }
72
  public function getAt( $idx ){ $offset = $this->targetOffset(); $offset += ( $idx * 8 ); $len = $this->integerAt( $offset ); $idx = $this->integerAt( $offset + 4 ); $txt = $this->bytes( $idx, $len ); if( false === strpos( $txt, "\0") ){ return $txt; } return explode( "\0", $txt ); }
73
- public function parse( $limit = -1 ){ $i = -1; $r = array(); $sourceOffset = $this->sourceOffset(); $targetOffset = $this->targetOffset(); $soffset = $sourceOffset; $toffset = $targetOffset; while( $soffset < $targetOffset ){ $len = $this->integerAt( $soffset ); $idx = $this->integerAt( $soffset + 4 ); $src = $this->bytes( $idx, $len ); $eot = strpos( $src, "\x04" ); if( false === $eot ){ $context = null; } else { $context = $this->str( substr($src, 0, $eot ) ); $src = substr( $src, $eot+1 ); } $sources = explode( "\0", $src, 2 ); $len = $this->integerAt( $toffset ); $idx = $this->integerAt( $toffset + 4 ); $targets = explode( "\0", $this->bytes( $idx, $len ) ); if( -1 === $i && '' === $sources[0] && is_null($context) ){ $this->setHeader( LocoPoHeaders::fromMsgstr($targets[0]) ); } if( ++$i === $limit ){ break; } $r[$i] = array( 'source' => $this->str( $sources[0] ), 'target' => $this->str( $targets[0] ), 'context' => $context, ); if( isset($sources[1]) ){ $p = count($r) - 1; $nforms = max( 2, count($targets) ); for( $i = 1; $i < $nforms; $i++ ){ $r[] = array( 'source' => isset($sources[$i]) ? $this->str( $sources[$i] ) : sprintf('%s (plural %u)',$r[$p]['source'],$i), 'target' => isset($targets[$i]) ? $this->str( $targets[$i] ) : '', 'parent' => $p, 'plural' => $i, ); } } $soffset += 8; $toffset += 8; } return $r; }
74
  public function isBigendian(){ if( is_null($this->be) ){ $str = $this->words( 0, 1 ); if( "\xDE\x12\x04\x95" === $str ){ $this->be = false; } else if( "\x95\x04\x12\xDE" === $str ){ $this->be = true; } else { throw new Loco_error_ParseException('Invalid MO format'); } } return $this->be; }
75
  public function version(){ if( is_null($this->v) ){ $this->v = $this->integerWord(1); } return $this->v; }
76
  #[ReturnTypeWillChange]
@@ -83,27 +84,27 @@ private function words( $offset, $length ){ return $this->bytes( $offset * 4, $l
83
  private function integerWord( $offset ){ return $this->integerAt( $offset * 4 ); }
84
  private function integerAt( $offset ){ $str = $this->bytes( $offset, 4 ); $fmt = $this->isBigendian() ? 'N' : 'V'; $arr = unpack( $fmt, $str ); if( ! isset($arr[1]) || ! is_int($arr[1]) ){ throw new Loco_error_ParseException('Failed to read integer at byte '.$offset); } return $arr[1]; } }
85
  abstract class LocoPo {
86
- public static function pair( $key, $text, $width = 79, $eol = "\n", $esc = '\\n' ){ if( '' === $text ){ return $key.' ""'; } $text = addcslashes( $text, "\t\x0B\x0C\x07\x08\\\"" ); if( $esc ) { $text = preg_replace('/(?:\\r\\n?|\\n)/', $esc.$eol, $text, -1, $nbr ); } else { $eol = "\n"; $text = preg_replace_callback('/(?:\\r\\n?|\\n)/',array(__CLASS__,'replace_br'), $text, -1, $nbr ); } if( $nbr ){ } else if( $width && $width < mb_strlen($text,'UTF-8') + strlen($key) + 3 ){ } else { return $key.' "'.$text.'"'; } $lines = array( $key.' "' ); if( $width ){ $width -= 2; $a = '/^.{0,'.($width-1).'}[-– \\.,:;\\?!\\)\\]\\}\\>]/u'; $b = '/^[^-– \\.,:;\\?!\\)\\]\\}\\>]+/u'; foreach( explode($eol,$text) as $unwrapped ){ $length = mb_strlen( $unwrapped, 'UTF-8' ); while( $length > $width ){ if( preg_match( $a, $unwrapped, $r ) ){ $line = $r[0]; } else if( preg_match( $b, $unwrapped, $r ) ){ $line = $r[0]; } else { throw new Exception('Wrapping error'); } $lines[] = $line; $trunc = mb_strlen($line,'UTF-8'); $length -= $trunc; $unwrapped = (string) substr( $unwrapped, strlen($line) ); if( ( '' === $unwrapped && 0 !== $length ) || ( 0 === $length && '' !== $unwrapped ) ){ throw new Exception('Truncation error'); } } if( 0 !== $length ){ $lines[] = $unwrapped; } } } else { foreach( explode($eol,$text) as $unwrapped ){ $lines[] = $unwrapped; } } return implode('"'.$eol.'"',$lines).'"'; }
87
- private static function replace_br( array $r ){ return addcslashes($r[0],"\r\n")."\n"; }
88
- public static function refs( $text, $width = 76, $eol = "\n" ){ $text = preg_replace('/\\s+/u', ' ', $text ); if( $width ){ $text = wordwrap( $text, $width, $eol.'#: ', false ); } return '#: '.$text; }
89
- public static function prefix( $text, $prefix, $eol = "\n" ){ return $prefix . implode($eol.$prefix, self::split($text) ); }
90
- public static function split( $text ){ $lines = preg_split('/\\R/u', $text ); if( false === $lines ){ if( false === preg_match('//u',$text) ){ $text = mb_convert_encoding( $text, 'UTF-8', 'cp1252' ); } $lines = preg_split('/\\r?\\n+/', $text ); } return $lines; }
91
- public static function trim( $text ){ $lines = array(); $deferred = null; foreach( explode("\n",$text) as $line ){ if( '' === $line ){ continue; } if( preg_match('/^msg[a-z]+(?:\\[\\d+])? ""/',$line) ){ $deferred = $line; continue; } if( $deferred && '"' === $line[0] ){ $lines[] = $deferred; $deferred = null; } $lines[] = $line; } return implode("\n",$lines); } }
92
  class LocoPoIndex extends ArrayIterator {
93
  public function compare( LocoPoMessage $a, LocoPoMessage $b ){ $h = $a->getHash(); if( ! isset($this[$h]) ){ return 1; } $j = $b->getHash(); if( ! isset($this[$j]) ){ return -1; } return $this[$h] > $this[$j] ? 1 : -1; } }
94
  class LocoPoMessage extends ArrayObject {
95
  public function __construct( array $r ){ $r['key'] = $r['source']; parent::__construct($r); }
96
  public function __get( $prop ){ return $this->offsetExists($prop) ? $this->offsetGet($prop) : null; }
97
- private function _getFlags(){ $flags = array(); $plurals = $this->__get('plurals'); if( 4 === $this->__get('flag') ){ $flags[] = 'fuzzy'; } else if( $plurals ){ foreach( $plurals as $child ){ if( 4 === $child->__get('flag') ){ $flags[] = 'fuzzy'; break; } } } if( $f = $this->__get('format') ){ $flags[] = $f.'-format'; } else if( isset($plurals[0]) && ( $f = $plurals[0]->format ) ){ $flags[] = $f.'-format'; } return $flags; }
98
  public function getHash(){ $hash = $this->getKey(); if( $this->offsetExists('plurals') ){ foreach( $this->offsetGet('plurals') as $p ){ $hash .= "\0".$p->getHash(); break; } } return $hash; }
99
  public function getKey(){ $msgid = (string) $this['source']; $msgctxt = (string) $this->__get('context'); if( '' !== $msgctxt ){ if( '' === $msgid ){ $msgid = '('.$msgctxt.')'; } $msgid = $msgctxt."\4".$msgid; } return $msgid; }
100
- public function exportSerial(){ $a = array( $this['target'] ); if( $this->offsetExists('plurals') ){ $plurals = $this->offsetGet('plurals'); if( is_array($plurals) ){ foreach( $plurals as $i => $p ){ $a[] = $p['target']; } } } return $a; }
101
  public function __toString(){ return $this->render( 79, 76 ); }
102
- public function render( $width, $ref_width, $max_forms = 0 ){ $s = array(); try { if( $text = $this->__get('comment') ) { $s[] = LocoPo::prefix( $text, '# '); } if( $text = $this->__get('notes') ) { $s[] = LocoPo::prefix( $text, '#. '); } if( $text = $this->__get('refs') ){ $s[] = LocoPo::refs( $text, $ref_width ); } if( $texts = $this->_getFlags() ){ $s[] = '#, '.implode(', ',$texts); } $prev = $this->__get('prev'); if( is_array($prev) && $prev ){ foreach( new LocoPoIterator($prev) as $p ){ $text = $p->render( max(0,$width-3), 0 ); $s[] = LocoPo::prefix( LocoPo::trim($text),'#| '); break; } } $text = $this->__get('context'); if( is_string($text) && '' !== $text ){ $s[] = LocoPo::pair('msgctxt', $text, $width ); } $s[] = LocoPo::pair( 'msgid', $this['source'], $width ); $target = $this['target']; $plurals = $this->__get('plurals'); if( is_array($plurals) ){ if( array_key_exists(0,$plurals) ){ $p = $plurals[0]; $s[] = LocoPo::pair('msgid_plural', $p['source'], $width ); $s[] = LocoPo::pair('msgstr[0]', $target, $width ); $i = 0; while( array_key_exists($i,$plurals) ){ $p = $plurals[$i]; if( ++$i === $max_forms ){ break; } $s[] = LocoPo::pair('msgstr['.$i.']', $p['target'], $width ); } } else if( isset($this['plural_key']) ){ $s[] = LocoPo::pair('msgid_plural', $this['plural_key'], $width ); $s[] = LocoPo::pair('msgstr[0]', $target, $width ); } else { trigger_error('Missing plural_key in zero plural export'); $s[] = LocoPo::pair('msgstr', $target, $width ); } } else { $s[] = LocoPo::pair('msgstr', $target, $width ); } } catch( Exception $e ){ trigger_error( $e->getMessage(), E_USER_WARNING ); } return implode("\n",$s)."\n"; }
103
- public function merge( LocoPoMessage $def, $translate = false ){ if( $def->getHash() !== $this->getHash() ){ $prev = array( 'source' => '', 'target' => '' ); $prev = $this->diff('source',$def,$prev); $prev = $this->diff('context',$def,$prev); $this['flag'] = 4; $this['prev'] = array( $prev ); $defPlural = $def->getPlural(0); $ourPlural = $this->getPlural(0); if( $defPlural && $ourPlural ) { $ourPlural->merge($defPlural); if( $ourPlural->offsetExists('prev') ) { $this['prev'][] = $ourPlural->prev[0]+array('parent'=>0,'plural'=>1); $ourPlural->offsetUnset('prev'); } } else if( $defPlural ){ $this['plurals'] = array( clone $defPlural ); } else if( $ourPlural ){ $this['prev'][] = $ourPlural->exportBasic() + array('parent'=>0,'plural'=>1); $this->offsetUnset('plurals'); } } foreach( array('notes','refs') as $f ){ if( $def->offsetExists($f) ){ $this->offsetSet($f,$def->offsetGet($f)); } else if( $this->offsetExists($f) ){ $this->offsetUnset($f); } } if( $translate && '' === $this['target'] && '' !== $def['target'] ){ $this['target'] = $def['target']; if( $def->offsetExists('comment') ) { $this['comment'] = $def['comment']; } if( $this->offsetExists('plurals') ){ foreach( $this['plurals'] as $i => $ourPlural ){ if( '' === $ourPlural['target'] ){ $defPlural = $def->getPlural($i); if( $defPlural ){ $ourPlural['target'] = $defPlural['target']; } } } } } }
104
  private function diff( $key, LocoPoMessage $def, array $prev ){ $old = $this->__get($key); $new = $def->__get($key); if( $new !== $old ){ $this->offsetSet($key,$new); if( is_string($old) && '' !== $old ){ $prev[$key] = $old; } } return $prev; }
105
  private function getPlural( $i ){ if( $this->offsetExists('plurals') ){ $plurals = $this->offsetGet('plurals'); if( is_array($plurals) && array_key_exists($i,$plurals) ){ return $plurals[$i]; } } return null; }
106
- private function exportBasic(){ return array( 'source' => $this['source'], 'context' => $this->context, 'target' => '', ); }
107
  public function export(){ $a = $this->getArrayCopy(); unset($a['key']); if( array_key_exists('plurals',$a) ){ foreach( $a['plurals'] as $i => $p ){ if( $p instanceof ArrayObject ){ $a['plurals'][$i] = $p->getArrayCopy(); } } } return $a; }
108
  public function countForms(){ $len = 1; if( $this->offsetExists('plurals') ){ $plurals = $this->offsetGet('plurals'); $len += count($plurals); } return $len; }
109
  public function strip(){ $this['target'] = ''; $plurals = $this->plurals; if( is_array($plurals) ){ foreach( $plurals as $p ){ $p->strip(); } } return $this; }
@@ -132,26 +133,26 @@ public function valid(){ return is_int($this->i); }
132
  #[ReturnTypeWillChange]
133
  public function next(){ $i = $this->i; while( ++$i < $this->t ){ if( array_key_exists('parent',$this->po[$i]) ){ continue; } $this->j++; $this->i = $i; return; } $this->i = null; $this->j = null; }
134
  #[ReturnTypeWillChange]
135
- public function current(){ $i = $this->i; $po = $this->po; $parent = new LocoPoMessage( $po[$i] ); $plurals = array(); $nonseq = $parent->offsetExists('child'); $j = $nonseq ? $parent['child'] : $i+1; while( isset($po[$j]['parent']) && $i === $po[$j]['parent'] ){ $plurals[] = new LocoPoMessage($po[$j++]); } if( $plurals ){ $parent['plurals'] = $plurals; } return $parent; }
136
  public function getArrayCopy(){ $po = $this->po; if( 0 === $this->z ){ $po[0]['target'] = (string) $this->getHeaders(); } return $po; }
137
- public function clear(){ if( 0 === $this->z ){ $this->po = array( $this->po[0] ); $this->t = 1; } else { $this->po = array(); $this->t = 0; } }
138
  public function getHeaders(){ if( is_null($this->headers) ){ $header = $this->po[0]; if( 0 === $this->z ){ $this->headers = LocoPoHeaders::fromMsgstr( $header['target'] ); } else { $this->headers = new LocoPoHeaders; } } return $this->headers; }
139
  public function setHeaders( LocoPoHeaders $head ){ $this->headers = $head; if( 0 === $this->z ){ $this->po[0]['target'] = null; } return $this; }
140
  public function initPo(){ if( 0 === $this->z ){ unset( $this->po[0]['flag'] ); } return $this; }
141
  public function initPot(){ if( 0 === $this->z ){ $this->po[0]['flag'] = 4; } return $this; }
142
  public function strip(){ $po = $this->po; $i = count($po); $z = $this->z; while( --$i > $z ){ $po[$i]['target'] = ''; } $this->po = $po; return $this; }
143
  public function __toString(){ try { return $this->render(); } catch( Exception $e ){ trigger_error( $e->getMessage(), E_USER_WARNING ); return ''; } }
144
- public function render( $sorter = null ){ $width = $this->w; $ref_width = max( 0, $width - 3 ); $h = $this->exportHeader(); $msg = new LocoPoMessage( $h ); $s = $msg->render( $width, $ref_width ); if( $sorter ){ if( ! is_callable($sorter) ){ throw new InvalidArgumentException('Bad callback'); } $msgs = array(); foreach( $this as $msg ){ $msgs[] = $msg; } usort( $msgs, $sorter ); } else { $msgs = $this; } $h = $this->getHeaders()->offsetGet('Plural-Forms'); if( is_string($h) && preg_match('/nplurals\\s*=\\s*(\\d)/',$h,$r) ){ $max_pl = (int) $r[1]; } else { $max_pl = 0; } foreach( $msgs as $msg ){ $s .= "\n".$msg->render( $width, $ref_width, $max_pl ); } return $s; }
145
- public function exportJed(){ $head = $this->getHeaders(); $a = array( '' => array( 'domain' => $head['domain'], 'lang' => $head['language'], 'plural-forms' => $head['plural-forms'], ) ); foreach( $this as $message ){ if( $message->translated() ){ $a[ $message->getKey() ] = $message->exportSerial(); } } return $a; }
146
- private function exportHeader(){ if( 0 === $this->z ){ $h = $this->po[0]; } else { $h = array( 'source' => '', 'target' => '' ); } if( $this->headers ){ $h['target'] = (string) $this->headers; } return $h; }
147
- public function exportRefs( $grep = '' ){ $a = array(); if( '' === $grep ) { $grep = '/(\\S+):\\d+/'; } else { $grep = '/(\\S*'.$grep.'):\\d+/'; } $self = get_class($this); $base = array( $this->exportHeader() ); foreach( $this as $message ){ if( preg_match_all( $grep, (string) $message->refs, $r ) ){ foreach( $r[1] as $ref ) { if( array_key_exists($ref,$a) ){ $po = $a[$ref]; } else { $po = new $self($base); $a[$ref] = $po; } $po->push($message); } } } return $a; }
148
- public function splitRefs( array $map = null ){ $a = array(); $self = get_class($this); $base = array( $this->exportHeader() ); if( is_array($map) ){ $grep = implode('|',array_keys($map)); } else { $grep = '[a-z]+'; } foreach( $this as $message ){ $refs = ltrim( (string) $message->refs ); if( '' !== $refs ){ if( preg_match_all('/\\S+\\.('.$grep.'):\\d+/', $refs, $r, PREG_SET_ORDER ) ){ $tmp = array(); foreach( $r as $rr ) { list( $ref, $ext ) = $rr; $tmp[$ext][$ref] = true; } foreach( $tmp as $ext => $refs ){ if( is_array($map) ){ $ext = $map[$ext]; } if( array_key_exists($ext,$a) ){ $po = $a[$ext]; } else { $po = new $self($base); $a[$ext] = $po; } $message = clone $message; $message['refs'] = implode(' ',array_keys($refs) ); $po->push($message); } } } } return $a; }
149
- public function getHashes(){ $a = array(); foreach( $this as $msg ){ $a[] = $msg->getHash(); } sort( $a, SORT_STRING ); return $a; }
150
  public function equalSource( LocoPoIterator $that ){ $a = $this->getHashes(); $b = $that->getHashes(); if( count($a) !== count($b) ){ return false; } foreach( $a as $i => $hash ){ if( $hash !== $b[$i] ){ return false; } } return true; }
151
- public function equal( LocoPoIterator $that ){ if( $this->t !== $that->t ){ return false; } $i = $this->z; $fields = array( 'source', 'context', 'notes', 'refs', 'target', 'comment', 'flag', 'parent', 'plural' ); while( ++$i < $this->t ){ $a = $this->po[$i]; $b = $that->po[$i]; foreach( $fields as $f ){ $af = isset($a[$f]) ? $a[$f] : ''; $bf = isset($b[$f]) ? $b[$f] : ''; if( $af !== $bf ){ return false; } } } return true; }
152
- public function sort( $func = null ){ $order = array(); foreach( $this as $msg ){ $order[] = $msg; } if( is_null($func) ){ $func = array( __CLASS__, 'compare' ); } else if( ! is_callable($func) ){ throw new InvalidArgumentException('Bad callback'); } usort( $order, $func ); $this->clear(); foreach( $order as $p ){ $this->push($p); } return $this; }
153
  public static function compare( LocoPoMessage $a, LocoPoMessage $b ){ $h = $a->getHash(); $j = $b->getHash(); $n = strcasecmp( $h, $j ); if( 0 === $n ){ $n = strcmp( $h, $j ); if( 0 === $n ){ return 0; } } return $n > 0 ? 1 : -1; }
154
- public function createSorter(){ $index = array(); foreach( $this as $i => $msg ){ $index[ $msg->getHash() ] = $i; } $obj = new LocoPoIndex( $index ); return array( $obj, 'compare' ); } }
155
  class LocoMoTable {
156
  private $size = 0;
157
  private $bin = '';
@@ -181,8 +182,8 @@ public function setCharset( $cs ){ $cs = $this->head->setCharset($cs); $this->c
181
  public function enableHash() { $this->hash = new LocoMoTable; }
182
  public function useFuzzy() { $this->use_fuzzy = true; }
183
  public function setHeader( $key, $val ){ $this->head->add($key, $val); return $this; }
184
- private function str( $s ){ if( $cs = $this->cs ){ $s = mb_convert_encoding($s,$cs,array('UTF-8')); } return $s; }
185
- public function compile(){ $table = array(''); $sources = array(''); $targets = array( (string) $this->head ); $fuzzy_flag = 4; $skip_fuzzy = ! $this->use_fuzzy; if( $this->head->has('Plural-Forms') && preg_match('/^nplurals=(\\d)/',$this->head->trimmed('Plural-Forms'), $r) ){ $nplurals = (int) $r[1]; $maxplural = max( 0, $nplurals-1 ); } else { $maxplural = 1; } foreach( $this->msgs as $r ){ if( $skip_fuzzy && isset($r['flag']) && $fuzzy_flag === $r['flag'] ){ continue; } $msgid = $this->str( $r['key'] ); if( isset($r['context']) ){ $msgctxt = $this->str( $r['context'] ); if( '' !== $msgctxt ){ if( '' === $msgid ){ $msgid = '('.$msgctxt.')'; } $msgid = $msgctxt."\x04".$msgid; } } if( '' === $msgid ){ continue; } $msgstr = $this->str( $r['target'] ); if( '' === $msgstr ){ continue; } $table[] = $msgid; if( isset($r['plurals']) ){ if( $r['plurals'] ){ $i = 0; foreach( $r['plurals'] as $i => $p ){ if( $i === 0 ){ $msgid .= "\0".$this->str($p['key']); } $msgstr .= "\0".$this->str($p['target']); } while( $maxplural > ++$i ){ $msgstr .= "\0"; } } else if( isset($r['plural_key']) ){ $msgid .= "\0".$this->str($r['plural_key']); } } $sources[] = $msgid; $targets[] = $msgstr; } asort( $sources, SORT_STRING ); $this->bin = "\xDE\x12\x04\x95\x00\x00\x00\x00"; $n = count($sources); $this->writeInteger( $n ); $offset = 28; $this->writeInteger( $offset ); $offset += $n * 8; $this->writeInteger( $offset ); if( $this->hash ){ sort( $table, SORT_STRING ); $this->hash->compile( $table ); $s = $this->hash->count(); } else { $s = 0; } $this->writeInteger( $s ); $offset += $n * 8; $this->writeInteger( $offset ); if( $s ){ $offset += $s * 4; } $source = ''; foreach( $sources as $i => $str ){ $source .= $str."\0"; $this->writeInteger( $strlen = strlen($str) ); $this->writeInteger( $offset ); $offset += $strlen + 1; } $target = ''; foreach( array_keys($sources) as $i ){ $str = $targets[$i]; $target .= $str."\0"; $this->writeInteger( $strlen = strlen($str) ); $this->writeInteger( $offset ); $offset += $strlen + 1; } if( $this->hash ){ $this->bin .= $this->hash->__toString(); } $this->bin .= $source; $this->bin .= $target; return $this->bin; }
186
  private function writeInteger( $num ){ $this->bin .= pack( 'V', $num ); return $this; } }
187
  interface LocoTokensInterface extends Iterator {
188
  public function advance();
@@ -193,20 +194,20 @@ private $pos;
193
  private $line;
194
  private $col;
195
  private $max;
196
- private $rules = array();
197
- private $skip = array();
198
  private $tok;
199
  private $len;
200
  public function __construct( $src = '' ){ $this->init($src); }
201
- public function parse( $src ){ $tokens = array(); $this->init($src); while( $tok = $this->advance() ){ $tokens[] = $tok; } return $tokens; }
202
  public function init( $src ){ $this->src = $src; $this->rewind(); return $this; }
203
- public function define( $grep, $t = 0 ){ if('^' !== $grep[1] ){ throw new InvalidArgumentException('Expression '.$grep.' isn\'t anchored'); } if( ! is_int($t) && ! is_callable($t) ){ throw new InvalidArgumentException('Non-integer token must be valid callback'); } $sniff = $grep[2]; if( $sniff === preg_quote($sniff,$grep[0]) ){ $this->rules[$sniff][] = array( $grep, $t ); } else { $this->rules[''][] = array( $grep, $t ); } return $this; }
204
  public function ignore( array $a ){ foreach( $a as $t ){ $this->skip[$t] = true; } return $this; }
205
  #[ReturnTypeWillChange]
206
  public function current(){ return $this->tok; }
207
  public function advance(){ $tok = $this->current(); $this->next(); return $tok; }
208
  #[ReturnTypeWillChange]
209
- public function next(){ $tok = null; $offset = $this->pos; $column = $this->col; $line = $this->line; while( $offset <= $this->max ){ $t = null; $s = ''; $text = substr($this->src,$offset); foreach( array($text[0],'') as $k ){ if( isset($this->rules[$k]) ) { foreach( $this->rules[$k] as $rule) { if( preg_match($rule[0], $text, $match ) ) { $s = $match[0]; $t = $rule[1]; if( ! is_int($t) ) { $t = call_user_func( $t, $s, $match ); } break 2; } } } } if( is_null($t) ){ $n = preg_match('/^./u',$text,$match); if( false === $n ){ $s = $text[0]; $match = array( mb_convert_encoding($s,'UTF-8','cp1252') ); } $s = (string) $match[0]; $t = self::T_UNKNOWN; } $length = strlen($s); if( 0 === $length ){ throw new Loco_error_ParseException('Failed to match anything'); } $offset += $length; $lines = preg_split('/\\r?\\n/',$s); $nlines = count($lines); if( $nlines > 1 ){ $next_line = $line + ( $nlines - 1 ); $next_column = strlen( end($lines) ); } else { $next_line = $line; $next_column = $column + $length; } if( array_key_exists($t,$this->skip) ){ $line = $next_line; $column = $next_column; continue; } $tok = self::T_LITERAL === $t ? $s : array( $t, $s, $line, $column ); $line = $next_line; $column = $next_column; $this->len++; break; } $this->tok = $tok; $this->pos = $offset; $this->col = $column; $this->line = $line; }
210
  #[ReturnTypeWillChange]
211
  public function key(){ return $this->len ? $this->len-1 : null; }
212
  #[ReturnTypeWillChange]
@@ -219,21 +220,21 @@ function _loco_resolve_surrogates( array $r ){ return loco_utf8_chr ( ( ( ( ( 83
219
  class LocoEscapeParser {
220
  private $map;
221
  private $grep;
222
- public function __construct( array $map = array() ){ $this->map = $map; $rules = array('\\\\'); if( $map ){ $rules[] = '['.implode(array_keys($map)).']'; } if( ! isset($map['U']) ) { $rules[] = 'U[0-9A-Fa-f]{5,8}'; } if( ! isset($map['u']) ) { $rules[] = 'u(?:\\{[0-9A-Fa-f]+\\}|[0-9A-Fa-f]{1,4})(?:\\\\u(?:\\{[0-9A-Fa-f]+\\}|[0-9A-Fa-f]{1,4}))*'; } $this->grep = '/\\\\('.implode('|',$rules).')/'; }
223
- final public function unescape( $s ) { if( '' !== $s ) { return $this->stripSlashes( preg_replace_callback($this->grep, array($this, 'unescapeMatch'), $s) ); } return ''; }
224
  final public function unescapeMatch( array $r ) { $s = $r[0]; $c = $s[1]; if( isset($this->map[$c]) ){ return $this->map[$c]; } if( 'u' === $c ){ $str = ''; $surrogates = false; foreach( explode('\\u',$s) as $i => $h ){ if( '' !== $h ){ $h = ltrim( trim($h,'{}'),'0'); $u = intval($h,16); $str.= loco_utf8_chr($u); if( ! $surrogates ){ $surrogates = $u >= 0xD800 && $u <= 0xDBFF; } } } if( $surrogates ){ $str = loco_resolve_surrogates($str); } return $str; } if( 'U' === $c ){ return loco_utf8_chr( intval(substr($s,2),16) ); } if( 'x' === $c ){ return chr( intval(substr($s,2),16) ); } if( ctype_digit($c) ){ return chr( intval(substr($s,1),8) ); } return $s; }
225
  protected function stripSlashes( $s ) { return stripcslashes($s); } }
226
  class LocoJsTokens extends LocoTokenizer { const T_KWORD = 1; const T_REGEX = 2;
227
  private static $lex;
228
- protected static $words = array( 'true' => 1, 'false' => 1, 'null' => 1, 'break' => T_BREAK, 'else' => T_ELSE, 'new' => T_NEW, 'var' => 1, 'case' => T_CASE, 'finally' => T_FINALLY, 'return' => T_RETURN, 'void' => 1, 'catch' => T_CATCH, 'for' => T_FOR, 'switch' => T_SWITCH, 'while' => T_WHILE, 'continue' => T_CONTINUE, 'function' => T_FUNCTION, 'this' => T_STRING, 'with' => 1, 'default' => T_DEFAULT, 'if' => T_IF, 'throw' => T_THROW, 'delete' => 1, 'in' => 1, 'try' => T_TRY, 'do' => T_DO, 'instanceof' => 1, 'typeof' => 1, );
229
- public static function decapse( $encapsed ){ $s = substr($encapsed,1,-1); $l = self::$lex; if( is_null($l) ){ $l = new LocoEscapeParser( array( 'U' => 'U', 'a' => 'a', ) ); self::$lex = $l; } return $l->unescape($s); }
230
- public function __construct( $src = '' ){ $this->define('/^(?:\\\\u[0-9A-F]{4,4}|[$_\\pL\\p{Nl}])(?:\\\\u[0-9A-F]{4}|[$_\\pL\\pN\\p{Mn}\\p{Mc}\\p{Pc}])*/ui', array($this,'matchWord') ); $this->define('/^\\s+/u', T_WHITESPACE ); $this->define('!^//.*!', T_COMMENT ); $this->define('!^/\\*.*\\*/!Us', array($this,'matchComment') ); $this->define('/^"(?:\\\\.|[^\\r\\n\\p{Zl}\\p{Zp}"\\\\])*"/u', T_CONSTANT_ENCAPSED_STRING ); $this->define('/^\'(?:\\\\.|[^\\r\\n\\p{Zl}\\p{Zp}\'\\\\])*\'/u', T_CONSTANT_ENCAPSED_STRING ); $this->define('/^[-+;,<>.=:|&^!?*%~(){}[\\]]/'); parent::__construct($src); }
231
  public function matchWord( $s ){ if( array_key_exists($s,self::$words) ){ return self::$words[$s]; } return T_STRING; }
232
  public function matchComment( $s ){ if( '/**' === substr($s,0,3) ){ return T_DOC_COMMENT; } return T_COMMENT; } }
233
  class LocoExtracted implements Countable {
234
- private $exp = array();
235
- private $reg = array();
236
- private $dom = array();
237
  private $dflt = '';
238
  public function extractSource( LocoExtractor $ext, $src, $fileref = '' ){ $ext->extract( $this, $ext->tokenize($src), $fileref ); return $this; }
239
  public function export(){ return $this->exp; }
@@ -242,15 +243,15 @@ public function count(){ return count( $this->exp ); }
242
  public function getDomainCounts(){ return $this->dom; }
243
  public function setDomain( $default ){ $this->dflt = (string) $default; return $this; }
244
  public function getDomain(){ return $this->dflt; }
245
- private function key( array $entry ){ $key = (string) $entry['source']; foreach( array('context','domain') as $i => $prop ){ if( array_key_exists($prop,$entry) ) { $add = (string) $entry[$prop]; if( '' !== $add ){ $key .= ord($i).$add; } } } return $key; }
246
- public function pushMeta( $source, $notes, $domain = '' ){ if( '' === $domain || '*' === $domain ){ $domain = $this->dflt; } return $this->pushEntry( array( 'source' => $source, 'notes' => $notes, ), $domain ); }
247
  public function pushEntry( array $entry, $domain = '' ){ $entry['id'] = ''; $entry['target'] = ''; $entry['domain'] = $domain; $key = $this->key($entry); if( isset($this->reg[$key]) ){ $index = $this->reg[$key]; $clash = $this->exp[$index]; if( $value = $this->mergeField( $clash, $entry, 'refs', ' ') ){ $this->exp[$index]['refs'] = $value; } if( $value = $this->mergeField( $clash, $entry, 'notes', "\n") ){ $this->exp[$index]['notes'] = $value; } } else { $index = count($this->exp); $this->reg[$key] = $index; $this->exp[$index] = $entry; if( isset($this->dom[$domain]) ){ $this->dom[$domain]++; } else { $this->dom[$domain] = 1; } } return $index; }
248
- public function pushPlural( array $entry, $sindex ){ $parent = $this->exp[$sindex]; $domain = $parent['domain']; $pkey = $this->key($parent)."\2"; if( ! array_key_exists($pkey,$this->reg) ){ $pindex = count($this->exp); $this->reg[$pkey] = $pindex; $entry += array( 'id' => '', 'target' => '', 'plural' => 1, 'parent' => $sindex, 'domain' => $domain, ); $this->exp[$pindex] = $entry; if( isset($entry['format']) && ! isset( $parent['format']) ) { $this->exp[$sindex]['format'] = $entry['format']; } if( $pindex !== $sindex + $entry['plural']) { $this->exp[$sindex]['child'] = $pindex; } } }
249
  public function mergeField( array $old, array $new, $field, $glue ){ $prev = isset($old[$field]) ? $old[$field] : ''; if( isset($new[$field]) ){ $text = $new[$field]; if( '' !== $prev && $prev !== $text ){ if( 'notes' === $field && preg_match( '/^'.preg_quote( rtrim($text,'. '),'/').'[. ]*$/mu', $prev ) ) { $text = $prev; } else { $text = $prev.$glue.$text; } } return $text; } return $prev; }
250
- public function filter( $domain ){ $map = array(); $newOffset = 1; $matchAll = '*' === $domain; $raw = array( array( 'id' => '', 'source' => '', 'target' => '', 'domain' => $matchAll ? '' : $domain, ) ); foreach( $this->exp as $oldOffset => $r ){ if( isset($r['parent']) ){ if( isset($map[$r['parent']]) ){ $r['parent'] = $map[ $r['parent'] ]; $raw[ $newOffset++ ] = $r; } } else { if( $matchAll ){ $match = true; } else if( isset($r['domain']) ){ $match = $domain === $r['domain']; } else { $match = $domain === ''; } if( $match ){ $map[ $oldOffset ] = $newOffset; $raw[ $newOffset++ ] = $r; } } } return $raw; } }
251
  abstract class LocoExtractor {
252
  private $rules;
253
- private $wp = array();
254
  private $domain = '';
255
  abstract public function tokenize( $src );
256
  abstract public function extract( LocoExtracted $strings, LocoTokensInterface $tokens, $fileref = '' );
@@ -263,17 +264,17 @@ public function headerize( array $tags, $domain = '' ){ if( isset($this->wp[$dom
263
  protected function getHeaders(){ return $this->wp; }
264
  final public function extractSource( $src, $fileref ){ $strings = new LocoExtracted; $this->extract( $strings, $this->tokenize($src), $fileref ); return $strings; }
265
  public function rule( $s ){ return isset($this->rules[$s]) ? $this->rules[$s] : ''; }
266
- protected function push( LocoExtracted $strings, $rule, array $args, $comment = '', $ref = '' ){ $s = strpos( $rule, 's'); $p = strpos( $rule, 'p'); $c = strpos( $rule, 'c'); $d = strpos( $rule, 'd'); if( false === $s || ! isset($args[$s]) ){ return null; } $msgid = $args[$s]; if( ! is_string($msgid) ){ return null; } $entry = array( 'source' => $msgid, ); if( is_int($c) && isset($args[$c]) ){ $entry['context'] = $args[$c]; } else if( '' === $msgid ){ return null; } if( $ref ){ $entry['refs'] = $ref; } if( is_int($d) && array_key_exists($d,$args) ){ $domain = $args[$d]; if( is_null($domain) ){ $domain = ''; } } else if( '' === $this->domain ) { $domain = $strings->getDomain(); } else { $domain = $this->domain; } $parse_printf = true; if( $comment = $this->comment($comment) ){ if( preg_match('/^xgettext:\\s*([-a-z]+)-format\\s*/mi', $comment, $r, PREG_OFFSET_CAPTURE ) ){ $entry['format'] = $r[1][0]; $comment = trim( substr_replace( $comment,'', $r[0][1], strlen($r[0][0]) ) ); $parse_printf = ( 'no-' === substr($entry['format'],0,3) ) ? false : null; } if( preg_match('/^references?:( *.+:\\d+)*\\s*/mi', $comment, $r, PREG_OFFSET_CAPTURE ) ){ $entry['refs'] = trim($r[1][0],' '); $comment = trim( substr_replace( $comment, '', $r[0][1], strlen($r[0][0]) ) ); } $entry['notes'] = $comment; } if( $parse_printf && ( $format = $this->fsniff($msgid) ) ){ $entry['format'] = $format; } $index = $strings->pushEntry($entry,$domain); if( is_int($p) && isset($args[$p]) ){ $msgid_plural = $args[$p]; $entry = array( 'source' => $msgid_plural, ); if( false !== $parse_printf && ( $format = $this->fsniff($msgid_plural) ) ){ $entry['format'] = $format; } $strings->pushPlural($entry,$index); } return $index; }
267
  protected function utf8( $str ){ if( false === preg_match('//u',$str) ){ $str = mb_convert_encoding( $str, 'UTF-8', 'cp1252' ); } return $str; } }
268
  class LocoPHPTokens implements LocoTokensInterface, Countable {
269
  private $i;
270
  private $tokens;
271
- private $skip_tokens = array();
272
- private $literal_tokens = array();
273
  public function __construct( array $tokens ){ $this->tokens = $tokens; $this->rewind(); }
274
  public function literal( array $a ){ foreach( $a as $t ){ $this->literal_tokens[ $t ] = 1; } return $this; }
275
  public function ignore( array $a ){ foreach( $a as $t ){ $this->skip_tokens[$t] = true; } return $this; }
276
- public function export(){ $arr = array(); $this->rewind(); while( $tok = $this->advance() ){ $arr[] = $tok; } return $arr; }
277
  public function advance(){ $tok = $this->current(); $this->next(); return $tok; }
278
  #[ReturnTypeWillChange]
279
  public function rewind(){ $this->i = ( false === reset($this->tokens) ? null : key($this->tokens) ); }
@@ -285,26 +286,26 @@ public function key(){ return $this->i; }
285
  public function next(){ $this->i = ( false === next($this->tokens) ? null : key($this->tokens) ); }
286
  #[ReturnTypeWillChange]
287
  public function current(){ if( ! $this->valid() ){ return false; } $tok = $this->tokens[$this->i]; if( is_array($tok) && isset($this->literal_tokens[$tok[0]]) ){ return $tok[1]; } return $tok; }
288
- public function __toString(){ $s = array(); foreach( $this as $token ){ $s[] = is_array($token) ? $token[1] : $token; } return implode('',$s); }
289
  #[ReturnTypeWillChange]
290
  public function count(){ return count($this->tokens); } }
291
  class LocoPHPEscapeParser extends LocoEscapeParser {
292
- public function __construct(){ parent::__construct( array( 'n' => "\n", 'r' => "\r", 't' => "\t", 'v' => "\x0B", 'f' => "\x0C", 'e' => "\x1B", '$' => '$', '\\' => '\\', '"' => '"', ) ); }
293
- protected function stripSlashes( $s ) { return preg_replace_callback('/\\\\(x[0-9A-Fa-f]{1,2}|[0-3]?[0-7]{1,2})/', array($this,'unescapeMatch'), $s, -1, $n ); } }
294
  function loco_unescape_php_string( $s ){ static $l; if( is_null($l) ) { $l = new LocoPHPEscapeParser; } return $l->unescape($s); }
295
- function loco_decapse_php_string( $s ){ if( ! $s ){ return (string) $s; } $q = $s[0]; if( "'" === $q ){ return str_replace( array('\\'.$q, '\\\\'), array($q, '\\'), substr( $s, 1, -1 ) ); } if( '"' !== $q ){ return $s; } return loco_unescape_php_string( substr($s,1,-1) ); }
296
- function loco_parse_php_comment($comment){ $comment = trim( $comment,"/ \n\r\t" ); if( '' !== $comment && '*' === $comment[0] ){ $lines = array(); $junk = "\r\t/ *"; foreach( explode("\n",$comment) as $line ){ $line = trim($line,$junk); if( '' !== $line ){ $lines[] = $line; } } $comment = implode("\n", $lines); } return $comment; }
297
- function loco_parse_wp_comment( $block ){ $header = array(); if( '/*' === substr($block,0,2) ){ $junk = "\r\t/ *"; foreach( explode("\n", $block) as $line ){ if( false !== ( $i = strpos($line,':') ) ){ $key = substr($line,0,$i); $val = substr($line,++$i); $header[ trim($key,$junk) ] = trim($val,$junk); } } } return $header; }
298
  function loco_sniff_printf( $s, $p, $limit = 0, $offset = 0 ){ $n = 0; while( is_string($s) && '' !== $s && false !== ( $i = strpos($s,'%',$offset) ) ){ if( 0 !== $i ){ $s = substr( $s, $i ); } if( preg_match( $p, $s, $r ) ){ $match = $r[0]; if( 0 < $n && isset($r[1]) && '' === $r[1] && '%' !== substr($match,-1) ){ return 0; } if( ++$n === $limit ){ break; } $offset = strlen($match); } else { return 0; } } return $n; }
299
  function loco_sniff_php_printf( $s, $limit = 0 ){ return loco_sniff_printf( $s, '/^%(?:[1-9]\\d*\\$)?(?:\'.|[-+0 ])*\\d*(?:\\.\\d+)?[suxXbcdeEfFgGo%]/', $limit ); }
300
  class LocoPHPExtractor extends LocoExtractor {
301
- private $defs = array();
302
  public function tokenize( $src ){ return new LocoPHPTokens( token_get_all($src) ); }
303
  public function decapse( $raw ){ return loco_decapse_php_string( $raw ); }
304
  public function fsniff( $str ){ return loco_sniff_php_printf($str) ? 'php' : ''; }
305
  protected function comment( $comment ){ $comment = loco_parse_php_comment($comment); $comment = preg_replace('/^translators:\\s+/mi', '', $comment ); return $comment; }
306
  public function define( $name, $value ){ if( is_string($value) ){ $this->defs[$name] = $value; } return $this; }
307
- public function extract( LocoExtracted $strings, LocoTokensInterface $tokens, $fileref = '' ){ $tokens->ignore( array(T_WHITESPACE) ); $n = 0; $depth = 0; $comment = ''; $narg = 0; $args = array(); $ref = ''; $rule = ''; $wp = $this->getHeaders(); $tokens->rewind(); while( $tok = $tokens->advance() ){ if( is_string($tok) ){ $s = $tok; $t = null; } else { $t = $tok[0]; $s = $tok[1]; } if( $depth ){ if( ')' === $s || ']' === $s ){ if( 0 === --$depth ){ if( $this->push( $strings, $rule, $args, $comment, $ref ) ){ $n++; } $comment = ''; } } else if( '(' === $s || '[' === $s ){ $depth++; $args[$narg] = null; } else if( 1 === $depth ){ if( ',' === $s ){ $narg++; } else if( T_CONSTANT_ENCAPSED_STRING === $t ){ $s = self::utf8($s); $args[$narg] = $this->decapse($s); } else if( T_STRING === $t && array_key_exists($s,$this->defs) ){ $args[$narg] = $this->defs[$s]; } else { $args[$narg] = null; } } } else if( T_COMMENT === $t || T_DOC_COMMENT === $t ){ $was_header = false; $s = self::utf8($s); if( 0 === $n ){ if( false !== strpos($s,'* @package') ){ $was_header = true; } if( $wp && ( $header = loco_parse_wp_comment($s) ) ){ foreach( $wp as $domain => $tags ){ foreach( array_intersect_key($header,$tags) as $tag => $source ){ $strings->pushMeta( $source, $tags[$tag], (string) $domain ); $was_header = true; } } } } if( ! $was_header ) { $comment = $s; } } else if( T_STRING === $t && '(' === $tokens->advance() && ( $rule = $this->rule($s) ) ){ $ref = $fileref ? $fileref.':'.$tok[2]: ''; $depth = 1; $args = array(); $narg = 0; } else if( $comment ){ if( false === stripos($comment, 'translators:') && false === strpos($comment, 'xgettext:') ){ $comment = ''; } } } return $this; } }
308
  function loco_sniff_js_printf( $s, $limit = 0 ){ return loco_sniff_printf( $s, '/^%(?:[1-9]\\d*\\$)?\\+?(?:0|\'[^$])?-?\\d*(?:\\.\\d+)?[b-gijostTuvxX%]/', $limit ); }
309
  class LocoJsExtractor extends LocoPHPExtractor {
310
  public function tokenize( $src ){ return new LocoJsTokens($src); }
@@ -312,13 +313,13 @@ public function fsniff( $str ){ return loco_sniff_js_printf($str) ? 'javascript'
312
  public function decapse( $encapsed ){ return LocoJsTokens::decapse($encapsed); } }
313
  class LocoTwigExtractor extends LocoPHPExtractor {
314
  public function tokenize( $src ){ $src = '<?php '.preg_replace('/{#([^#]+)#}/su','/*\\1*/',$src); return parent::tokenize($src); } }
315
- function loco_wp_extractor( $type = 'php' ){ static $rules = array( '__' => 'sd', '_e' => 'sd', '_c' => 'sd', '_n' => 'sp_d', '_n_noop' => 'spd', '_nc' => 'sp_d', '__ngettext' => 'spd', '__ngettext_noop' => 'spd', '_x' => 'scd', '_ex' => 'scd', '_nx' => 'sp_cd', '_nx_noop' => 'spcd', 'esc_attr__' => 'sd', 'esc_html__' => 'sd', 'esc_attr_e' => 'sd', 'esc_html_e' => 'sd', 'esc_attr_x' => 'scd', 'esc_html_x' => 'scd', ); if( 'php' === $type ){ $extr = new LocoPHPExtractor($rules); } else if( 'twig' === $type ){ $extr = new LocoTwigExtractor($rules); } else if( 'js' === $type ){ $extr = new LocoJsExtractor($rules); } else { throw new InvalidArgumentException('No string extractor for '.$type); } return $extr; }
316
  function loco_string_percent( $n, $t ) { if( ! $t || ! $n ){ $s = '0'; } else if( $t === $n ){ $s = '100'; } else { $dp = 0; $n = 100 * $n / $t; if( $n > 99 ){ $s = number_format( min( $n, 99.9 ), ++$dp ); } else if( $n < 0.5 ){ $n = max( $n, 0.0001 ); do { $s = number_format( $n, ++$dp ); } while( preg_match('/^0\\.0+$/',$s) && $dp < 4 ); $s = substr($s,1); } else { $s = number_format( $n, $dp ); } } return $s; }
317
  function loco_print_progress( $translated, $untranslated, $flagged ) { $total = $translated + $untranslated; $complete = loco_string_percent( $translated - $flagged, $total ); $class = 'progress'; if( ! $translated && ! $flagged ){ $class .= ' empty'; } else if( '100' === $complete ){ $class .= ' done'; } echo '<div class="',$class,'"><div class="t">'; if( $flagged ){ $s = loco_string_percent( $flagged, $total ); echo '<div class="bar f" style="width:',$s,'%">&nbsp;</div>'; } if( '0' === $complete ){ echo '&nbsp;'; } else { $class = 'bar p'; $p = (int) $complete; $class .= sprintf(' p-%u', 10*floor($p/10) ); $style = 'width:'.$complete.'%'; if( $flagged ){ $remain = 100.0 - (float) $s; $style .= '; max-width: '.sprintf('%s',$remain).'%'; } echo '<div class="',$class,'" style="'.$style.'">&nbsp;</div>'; } echo '</div><div class="l">',$complete,'%</div></div>'; }
318
  class LocoFuzzyMatcher implements Countable {
319
- private $pot = array();
320
- private $po = array();
321
- private $diff = array();
322
  private $dmax = .20;
323
  #[ReturnTypeWillChange]
324
  public function count(){ return count($this->pot); }
@@ -328,8 +329,8 @@ public function setFuzziness( $s ){ if( $this->po ){ throw new LogicException('C
328
  public function add( $a ){ $source = isset($a['source']) ? (string) $a['source'] : ''; $context = isset($a['context']) ? (string) $a['context'] : ''; $key = $source."\4".$context; $this->pot[$key] = $a; }
329
  private function key( $a ){ $source = isset($a['source']) ? (string) $a['source'] : ''; $context = isset($a['context']) ? (string) $a['context'] : ''; return $source."\4".$context; }
330
  protected function getRef( $a ){ $key = $this->key($a); return array_key_exists($key,$this->pot) ? $this->pot[$key] : null; }
331
- public function match( $a ) { $old = $this->key($a); if( isset($this->pot[$old]) ){ $new = $this->pot[$old]; unset($this->pot[$old]); return $new; } $this->po[$old] = $a; $target = isset($a['target']) ? (string) $a['target'] : ''; $comment = isset($a['comment']) ? (string) $a['comment'] : ''; if( '' === $target && '' === $comment ){ return null; } if( 0 < $this->dmax ){ foreach( $this->pot as $new => $_ ){ $dist = $this->distance($old,$new); if( -1 !== $dist ){ $this->diff[] = array( $old, $new, $dist ); } } } return null; }
332
  private function distance( $a, $b ){ $a = strtolower($a); $b = strtolower($b); if( $a === $b ){ return 0; } $lenA = strlen($a); $lenB = strlen($b); $lenDiff = abs($lenA-$lenB); $max = min($lenA,$lenB) + $lenDiff; $max = (int) ceil( $this->dmax * $max ); if( $max < $lenDiff ) { return -1; } $len = max($lenA,$lenB); if( $len < 256 ){ $d = levenshtein($a,$b); return $d > $max ? -1 : $d; } $d = 0; for( $i = 0; $i < $len; $i+=$max ){ $aa = substr($a,$i,$max); $bb = substr($b,$i,$max); $d += levenshtein($aa,$bb); if( $d > $max ){ return -1; } } return $d; }
333
- public function getFuzzyMatches(){ $pairs = array(); usort( $this->diff, array(__CLASS__,'compareDistance') ); foreach( $this->diff as $pair ){ list($old,$new) = $pair; if( ! array_key_exists($new,$this->pot) || ! array_key_exists($old,$this->po) ){ continue; } $pairs[] = array( $this->po[$old], $this->pot[$new], ); unset($this->po[$old]); unset($this->pot[$new]); if( ! $this->po || ! $this->pot ){ break; } } $this->diff = array(); return $pairs; }
334
  private static function compareDistance( array $a, array $b ){ return $a[2] - $b[2]; } }
335
  defined('T_FINALLY') || define('T_FINALLY',500); if( function_exists('loco_check_extension') ) { loco_check_extension('mbstring'); }
1
  <?php
2
  /**
3
+ * Downgraded for PHP 5.6 compatibility. Do not edit.
4
+ * @noinspection ALL
5
  */
6
  interface LocoArrayInterface extends ArrayAccess, Iterator, Countable, JsonSerializable {
7
  public function getArrayCopy(); }
8
  class LocoHeaders extends ArrayIterator implements LocoArrayInterface {
9
+ private $map = [];
10
+ public function __construct(array $raw = [] ){ if( $raw ){ $keys = array_keys( $raw ); $this->map = array_combine( array_map( 'strtolower', $keys ), $keys ); parent::__construct($raw); } }
11
  public function normalize( $key ){ $k = strtolower($key); return isset($this->map[$k]) ? $this->map[$k] : null; }
12
  public function add($key, $val ){ $this->offsetSet( $key, $val ); return $this; }
13
+ public function __toString(){ $pairs = []; foreach( $this as $key => $val ){ $pairs[] = $key.': '.$val; } return implode("\n", $pairs ); }
14
  public function trimmed($prop ){ return trim( $this->__get($prop) ); }
15
  public function has($key ){ $k = strtolower($key); return isset($this->map[$k]); }
16
  public function __get($key ){ return $this->offsetGet( $key ); }
30
  private $cs = null;
31
  public function getCharset(){ $cs = $this->cs; if( is_null($cs) ){ $cs = ''; $raw = $this->offsetGet('content-type'); if( $raw && preg_match('!\\bcharset[= ]+([-\\w]+)!',$raw,$r) ){ try { $cs = loco_normalize_charset($r[1]); } catch( InvalidArgumentException $e ){ $cs = null; } catch( Throwable $e ){ trigger_error( $e->getMessage(), E_USER_NOTICE ); $cs = null; } } $this->cs = $cs; } return $cs; }
32
  public function setCharset( $to ){ $to = loco_normalize_charset($to); $from = $this->getCharset(); $this->cs = $to; $this['Content-Type'] = 'text/plain; charset='.$to; if( $from && $from !== $to ){ foreach( $this as $key => $val ){ $this[$key] = mb_convert_encoding($val,$to,$from); } } return $to; }
33
+ public static function fromMsgstr( $str ){ $headers = new LocoPoHeaders; $key = ''; foreach( preg_split('/[\\r\\n]+/',$str) as $line ){ $i = strpos($line,':'); if( is_int($i) ){ $key = trim( substr($line,0,$i), " \t" ); $headers->offsetSet( $key, ltrim( substr($line,++$i)," \t" ) ); } else if( '' !== $key ){ $headers->offsetSet( $key, $headers->offsetGet($key)."\n".$line ); } } $cs = $headers->getCharset(); if( $cs && 'UTF-8' !== $cs && 'UTF-8' !== mb_detect_encoding($str,['UTF-8',$cs],true) ){ foreach( $headers as $key => $val ){ $headers[$key] = mb_convert_encoding($val,'UTF-8',[$cs]); } } return $headers; }
34
  public static function fromSource( $raw ){ $po = new LocoPoParser($raw); $po->parse(0); return $po->getHeader(); } }
35
  function loco_convert_utf8( $str, $enc, $strict ){ if( '' === $enc || 'UTF-8' === $enc || 'US-ASCII' === $enc ){ if( false === preg_match('//u',$str) ){ if( $strict ){ $e = new Loco_error_ParseException( $enc ? 'Invalid '.$enc.' encoding' : 'Unknown character encoding' ); if( preg_match('/^(?:[\\x00-\\x7F]|[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xFF][\\x80-\\xBF]{3})*/',$str,$r) && $str !== $r[0] ){ $e->setOffsetContext( strlen($r[0]), $str ); } throw $e; } $str = loco_fix_utf8($str); } } else if( 'ISO-8859-1' === $enc ) { $str = mb_convert_encoding( $str, 'UTF-8', 'cp1252' ); } else { $str = mb_convert_encoding( $str, 'UTF-8', $enc ); } return $str; }
36
  function loco_fix_utf8( $str ){ $fix = ''; while( is_string($str) && '' !== $str ){ if( preg_match('/^(?:[\\x00-\\x7F]|[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xFF][\\x80-\\xBF]{3})+/',$str,$r) ){ $fix .= $r[0]; $str = substr($str, strlen($r[0]) ); } else { $fix.= mb_convert_encoding( $str[0], 'UTF-8', 'cp1252' ); $str = substr($str,1); } } return loco_convert_utf8($fix,'',true); }
46
  function loco_remove_bom( $s, &$c ){ $bom = substr($s,0,2); if( "\xFF\xFE" === $bom ){ $c = 'UTF-16LE'; return substr($s,2); } if( "\xFE\xFF" === $bom ){ $c = 'UTF-16BE'; return substr($s,2); } if( "\xEF\xBB" === $bom && "\xBF" === $s[2] ){ $c = 'UTF-8'; return substr($s,3); } $c = ''; return $s; }
47
  function loco_parse_reference_id( $refs, &$_id ){ if( false === ( $n = strpos($refs,'loco:') ) ){ $_id = ''; return $refs; } $_id = substr($refs, $n+5, 24 ); $refs = substr_replace( $refs, '', $n, 29 ); return trim( $refs ); }
48
  class LocoPoParser extends LocoGettextParser implements Iterator {
49
+ private $lines = [];
50
  private $i;
51
  private $k;
52
  private $m;
60
  #[ReturnTypeWillChange]
61
  public function current(){ return $this->m; }
62
  #[ReturnTypeWillChange]
63
+ public function next(){ $valid = false; $entry = [ '#' => [], 'id' => [null], 'str' => [null] ]; $i = $this->i; while( array_key_exists(++$i,$this->lines) ){ $line = $this->lines[$i]; try { if( '' === $line ){ if( $valid ){ break; } continue; } $c = $line[0]; if( '#' === $c ){ if( $valid ){ $i--; break; } if( '#' === $line ){ continue; } $f = $line[1]; $entry['#'][$f][] = trim( substr( $line, 1+strlen($f) ), "/ \n\r\t" ); } else if( preg_match('/^msg(id(?:_plural)?|ctxt|str(?:\\[(\\d+)])?)[ \\t]*/', $line, $r ) ){ if( isset($r[2]) ){ $key = 'str'; $idx = (int) $r[2]; } else { $key = $r[1]; $idx = 0; } if( $valid && 'str' !== $key && null !== $entry['str'][0] ){ $i--; break; } $snip = strlen($r[0]); if( '"' !== substr($line,$snip,1) ){ throw new Exception('Expected " to follow msg'.$key); } $val = ''; $line = substr($line,$snip); while( true ){ if( '"' === $line || '"' !== substr($line,-1) ){ throw new Exception('Unterminated msg'.$key ); } $val .= substr( $line, 1, -1 ); $j = $i + 1; if( array_key_exists($j,$this->lines) && ( $line = $this->lines[$j] ) && '"' === $line[0] ){ $i = $j; } else { break; } } if( ! $valid ){ $valid = true; } if( 'id_plural' === $key ){ $key = 'id'; $idx = 1; } $entry[$key][$idx] = stripcslashes($val); } else if( preg_match('/^[ \\t]+$/',$line) ){ if( $valid ) { break; } } else if( '"' === $c ){ throw new Exception('String encountered without keyword'); } else { throw new Exception('Junk'); } } catch( Exception $e ){ } } if( $valid ){ ++$this->k; $this->i = $i; $this->m = $entry; } else { $this->i = null; $this->k = null; $this->m = null; } }
64
+ public function parse( $limit = -1 ){ $this->rewind(); if( ! $this->valid() ){ throw new Loco_error_ParseException('Invalid PO file'); } $entry = $this->current(); if( '' !== $entry['id'][0] || isset($entry['ctxt']) || is_null($entry['str'][0]) ){ $head = $this->setHeader( new LocoPoHeaders ); } else { $head = $this->setHeader( LocoPoHeaders::fromMsgstr($entry['str'][0]) ); } if( 0 === $limit ){ return []; } $i = -1; $assets = []; $lk = $head['X-Loco-Lookup']; while( $this->valid() ){ $entry = $this->current(); $msgid = $entry['id'][0]; if( is_null($msgid) ){ $this->next(); continue; } if( ++$i === $limit ){ return $assets; } $asset = [ 'source' => $this->str( $msgid ), 'target' => $this->str( (string) $entry['str'][0] ), 'context' => null, ]; $prev_entry = null; if( isset($entry['ctxt']) ){ $asset['context'] = $this->str( $entry['ctxt'][0] ); } $cmt = $entry['#']; if( isset($cmt[' ']) ){ $asset['comment'] = $this->str( implode("\n", $cmt[' '] ) ); } if( isset($cmt['.']) ){ $asset['notes'] = $this->str( implode("\n", $cmt['.'] ) ); } if( isset($cmt[':']) ){ if( $refs = implode( ' ', $cmt[':'] ) ) { $refs = $this->str($refs); if( $refs = loco_parse_reference_id( $refs, $_id ) ){ $asset['refs'] = $refs; } if( $_id ){ $asset['_id'] = $_id; } } } if( isset($cmt[',']) ){ foreach( $cmt[','] as $flags ){ foreach( explode(',',$flags) as $flag ){ if( $flag = trim($flag," \t") ){ if( preg_match('/^((?:no-)?\w+)-format/', $flag, $r ) ){ $asset['format'] = $r[1]; } else if( 'fuzzy' === $flag ){ $asset['flag'] = 4; } } } } } if( isset($cmt['|']) ){ $p = new LocoPoParser(''); $p->lines = $cmt['|']; $p->setCharset( $this->getCharset() ); try { $prev_entry = $p->parse(); } catch( Loco_error_ParseException $e ){ } if( $prev_entry ){ $msgid = $prev_entry[0]['source']; if( $lk && 'text' !== $lk ){ $asset[$lk] = $asset['source']; $asset['source'] = $msgid; } else if( 'loco:' === substr($msgid,0,5) ){ $asset['_id'] = substr($msgid,5); } else { $asset['prev'] = $prev_entry; $prev_entry = null; } } } $assets[] = $asset; if( isset($entry['id'][1]) ){ $idx = 0; $pidx = count($assets) - 1; $num = max( 2, count($entry['str']) ); while( ++$idx < $num ){ $plural = [ 'source' => '', 'target' => isset($entry['str'][$idx]) ? $this->str($entry['str'][$idx]) : '', 'plural' => $idx, 'parent' => $pidx, ]; if( 1 === $idx ){ $plural['source'] = $this->str($entry['id'][1]); if( is_array($prev_entry) && isset($prev_entry[1]) ){ if( $lk && 'text' !== $lk ){ $plural[$lk] = $plural['source']; $plural['source'] = $prev_entry[1]['source']; } } } if( isset($asset['flag']) ){ $plural['flag'] = $asset['flag']; } $assets[] = $plural; } } $this->next(); } if( -1 === $i ){ throw new Loco_error_ParseException('Invalid PO file'); } else if( 0 === $i && '' === $assets[0]['source'] && '' === $assets[0]['target'] ){ throw new Loco_error_ParseException('Invalid PO file' ); } return $assets; } }
65
  class LocoMoParser extends LocoGettextParser {
66
  private $bin;
67
  private $be;
71
  private $v;
72
  public function __construct( $bin ){ $this->bin = $bin; }
73
  public function getAt( $idx ){ $offset = $this->targetOffset(); $offset += ( $idx * 8 ); $len = $this->integerAt( $offset ); $idx = $this->integerAt( $offset + 4 ); $txt = $this->bytes( $idx, $len ); if( false === strpos( $txt, "\0") ){ return $txt; } return explode( "\0", $txt ); }
74
+ public function parse( $limit = -1 ){ $i = -1; $r = []; $sourceOffset = $this->sourceOffset(); $targetOffset = $this->targetOffset(); $soffset = $sourceOffset; $toffset = $targetOffset; while( $soffset < $targetOffset ){ $len = $this->integerAt( $soffset ); $idx = $this->integerAt( $soffset + 4 ); $src = $this->bytes( $idx, $len ); $eot = strpos( $src, "\x04" ); if( false === $eot ){ $context = null; } else { $context = $this->str( substr($src, 0, $eot ) ); $src = substr( $src, $eot+1 ); } $sources = explode( "\0", $src, 2 ); $len = $this->integerAt( $toffset ); $idx = $this->integerAt( $toffset + 4 ); $targets = explode( "\0", $this->bytes( $idx, $len ) ); if( -1 === $i && '' === $sources[0] && is_null($context) ){ $this->setHeader( LocoPoHeaders::fromMsgstr($targets[0]) ); } if( ++$i === $limit ){ break; } $r[$i] = [ 'source' => $this->str( $sources[0] ), 'target' => $this->str( $targets[0] ), 'context' => $context, ]; if( isset($sources[1]) ){ $p = count($r) - 1; $nforms = max( 2, count($targets) ); for( $i = 1; $i < $nforms; $i++ ){ $r[] = [ 'source' => isset($sources[$i]) ? $this->str( $sources[$i] ) : sprintf('%s (plural %u)',$r[$p]['source'],$i), 'target' => isset($targets[$i]) ? $this->str( $targets[$i] ) : '', 'parent' => $p, 'plural' => $i, ]; } } $soffset += 8; $toffset += 8; } return $r; }
75
  public function isBigendian(){ if( is_null($this->be) ){ $str = $this->words( 0, 1 ); if( "\xDE\x12\x04\x95" === $str ){ $this->be = false; } else if( "\x95\x04\x12\xDE" === $str ){ $this->be = true; } else { throw new Loco_error_ParseException('Invalid MO format'); } } return $this->be; }
76
  public function version(){ if( is_null($this->v) ){ $this->v = $this->integerWord(1); } return $this->v; }
77
  #[ReturnTypeWillChange]
84
  private function integerWord( $offset ){ return $this->integerAt( $offset * 4 ); }
85
  private function integerAt( $offset ){ $str = $this->bytes( $offset, 4 ); $fmt = $this->isBigendian() ? 'N' : 'V'; $arr = unpack( $fmt, $str ); if( ! isset($arr[1]) || ! is_int($arr[1]) ){ throw new Loco_error_ParseException('Failed to read integer at byte '.$offset); } return $arr[1]; } }
86
  abstract class LocoPo {
87
+ public static function pair( $key, $text, $width = 79, $eol = "\n", $esc = '\\n' ) { if( '' === $text ){ return $key.' ""'; } $text = addcslashes( $text, "\t\x0B\x0C\x07\x08\\\"" ); if( $esc ) { $text = preg_replace('/\\r\\n?|\\n/', $esc.$eol, $text, -1, $nbr ); } else { $eol = "\n"; $text = preg_replace_callback('/\\r\\n?|\\n/',[__CLASS__,'replace_br'], $text, -1, $nbr ); } if( $nbr ){ } else if( $width && $width < mb_strlen($text,'UTF-8') + strlen($key) + 3 ){ } else { return $key.' "'.$text.'"'; } $lines = [ $key.' "' ]; if( $width ){ $width -= 2; $a = '/^.{0,'.($width-1).'}[-– .,:;?!)\\]}>]/u'; $b = '/^[^-– .,:;?!)\\]}>]+/u'; foreach( explode($eol,$text) as $unwrapped ){ $length = mb_strlen( $unwrapped, 'UTF-8' ); while( $length > $width ){ if( preg_match( $a, $unwrapped, $r ) ){ $line = $r[0]; } else if( preg_match( $b, $unwrapped, $r ) ){ $line = $r[0]; } else { throw new Exception('Wrapping error'); } $lines[] = $line; $trunc = mb_strlen($line,'UTF-8'); $length -= $trunc; $unwrapped = (string) substr( $unwrapped, strlen($line) ); if( ( '' === $unwrapped && 0 !== $length ) || ( 0 === $length && '' !== $unwrapped ) ){ throw new Exception('Truncation error'); } } if( 0 !== $length ){ $lines[] = $unwrapped; } } } else { foreach( explode($eol,$text) as $unwrapped ){ $lines[] = $unwrapped; } } return implode('"'.$eol.'"',$lines).'"'; }
88
+ private static function replace_br( array $r ) { return addcslashes($r[0],"\r\n")."\n"; }
89
+ public static function refs( $text, $width = 76, $eol = "\n" ) { $text = preg_replace('/\\s+/u', ' ', $text ); if( $width ){ $text = wordwrap( $text, $width, $eol.'#: ' ); } return '#: '.$text; }
90
+ public static function prefix( $text, $prefix, $eol = "\n" ) { return $prefix . implode($eol.$prefix, self::split($text) ); }
91
+ public static function split( $text ) { $lines = preg_split('/\\R/u', $text ); if( false === $lines ){ if( false === preg_match('//u',$text) ){ $text = mb_convert_encoding( $text, 'UTF-8', 'cp1252' ); } $lines = preg_split('/\\r?\\n+/', $text ); } return $lines; }
92
+ public static function trim( $text ) { $lines = []; $deferred = null; foreach( explode("\n",$text) as $line ){ if( '' === $line ){ continue; } if( preg_match('/^msg[a-z]+(?:\\[\\d+])? ""/',$line) ){ $deferred = $line; continue; } if( $deferred && '"' === $line[0] ){ $lines[] = $deferred; $deferred = null; } $lines[] = $line; } return implode("\n",$lines); } }
93
  class LocoPoIndex extends ArrayIterator {
94
  public function compare( LocoPoMessage $a, LocoPoMessage $b ){ $h = $a->getHash(); if( ! isset($this[$h]) ){ return 1; } $j = $b->getHash(); if( ! isset($this[$j]) ){ return -1; } return $this[$h] > $this[$j] ? 1 : -1; } }
95
  class LocoPoMessage extends ArrayObject {
96
  public function __construct( array $r ){ $r['key'] = $r['source']; parent::__construct($r); }
97
  public function __get( $prop ){ return $this->offsetExists($prop) ? $this->offsetGet($prop) : null; }
98
+ private function _getFlags(){ $flags = []; $plurals = $this->__get('plurals'); if( 4 === $this->__get('flag') ){ $flags[] = 'fuzzy'; } else if( $plurals ){ foreach( $plurals as $child ){ if( 4 === $child->__get('flag') ){ $flags[] = 'fuzzy'; break; } } } if( $f = $this->__get('format') ){ $flags[] = $f.'-format'; } else if( isset($plurals[0]) && ( $f = $plurals[0]->format ) ){ $flags[] = $f.'-format'; } return $flags; }
99
  public function getHash(){ $hash = $this->getKey(); if( $this->offsetExists('plurals') ){ foreach( $this->offsetGet('plurals') as $p ){ $hash .= "\0".$p->getHash(); break; } } return $hash; }
100
  public function getKey(){ $msgid = (string) $this['source']; $msgctxt = (string) $this->__get('context'); if( '' !== $msgctxt ){ if( '' === $msgid ){ $msgid = '('.$msgctxt.')'; } $msgid = $msgctxt."\4".$msgid; } return $msgid; }
101
+ public function exportSerial(){ $a = [ $this['target'] ]; if( $this->offsetExists('plurals') ){ $plurals = $this->offsetGet('plurals'); if( is_array($plurals) ){ foreach( $plurals as $i => $p ){ $a[] = $p['target']; } } } return $a; }
102
  public function __toString(){ return $this->render( 79, 76 ); }
103
+ public function render( $width, $ref_width, $max_forms = 0 ){ $s = []; try { if( $text = $this->__get('comment') ) { $s[] = LocoPo::prefix( $text, '# '); } if( $text = $this->__get('notes') ) { $s[] = LocoPo::prefix( $text, '#. '); } if( $text = $this->__get('refs') ){ $s[] = LocoPo::refs( $text, $ref_width ); } if( $texts = $this->_getFlags() ){ $s[] = '#, '.implode(', ',$texts); } $prev = $this->__get('prev'); if( is_array($prev) && $prev ){ foreach( new LocoPoIterator($prev) as $p ){ $text = $p->render( max(0,$width-3), 0 ); $s[] = LocoPo::prefix( LocoPo::trim($text),'#| '); break; } } $text = $this->__get('context'); if( is_string($text) && '' !== $text ){ $s[] = LocoPo::pair('msgctxt', $text, $width ); } $s[] = LocoPo::pair( 'msgid', $this['source'], $width ); $target = $this['target']; $plurals = $this->__get('plurals'); if( is_array($plurals) ){ if( array_key_exists(0,$plurals) ){ $p = $plurals[0]; $s[] = LocoPo::pair('msgid_plural', $p['source'], $width ); $s[] = LocoPo::pair('msgstr[0]', $target, $width ); $i = 0; while( array_key_exists($i,$plurals) ){ $p = $plurals[$i]; if( ++$i === $max_forms ){ break; } $s[] = LocoPo::pair('msgstr['.$i.']', $p['target'], $width ); } } else if( isset($this['plural_key']) ){ $s[] = LocoPo::pair('msgid_plural', $this['plural_key'], $width ); $s[] = LocoPo::pair('msgstr[0]', $target, $width ); } else { trigger_error('Missing plural_key in zero plural export'); $s[] = LocoPo::pair('msgstr', $target, $width ); } } else { $s[] = LocoPo::pair('msgstr', $target, $width ); } } catch( Exception $e ){ trigger_error( $e->getMessage(), E_USER_WARNING ); } return implode("\n",$s)."\n"; }
104
+ public function merge( LocoPoMessage $def, $translate = false ){ if( $def->getHash() !== $this->getHash() ){ $prev = [ 'source' => '', 'target' => '' ]; $prev = $this->diff('source',$def,$prev); $prev = $this->diff('context',$def,$prev); $this['flag'] = 4; $this['prev'] = [ $prev ]; $defPlural = $def->getPlural(0); $ourPlural = $this->getPlural(0); if( $defPlural && $ourPlural ) { $ourPlural->merge($defPlural); if( $ourPlural->offsetExists('prev') ) { $this['prev'][] = $ourPlural->prev[0]+['parent'=>0,'plural'=>1]; $ourPlural->offsetUnset('prev'); } } else if( $defPlural ){ $this['plurals'] = [ clone $defPlural ]; } else if( $ourPlural ){ $this['prev'][] = $ourPlural->exportBasic() + ['parent'=>0,'plural'=>1]; $this->offsetUnset('plurals'); } } foreach( ['notes','refs'] as $f ){ if( $def->offsetExists($f) ){ $this->offsetSet($f,$def->offsetGet($f)); } else if( $this->offsetExists($f) ){ $this->offsetUnset($f); } } if( $translate && '' === $this['target'] && '' !== $def['target'] ){ $this['target'] = $def['target']; if( $def->offsetExists('comment') ) { $this['comment'] = $def['comment']; } if( $this->offsetExists('plurals') ){ foreach( $this['plurals'] as $i => $ourPlural ){ if( '' === $ourPlural['target'] ){ $defPlural = $def->getPlural($i); if( $defPlural ){ $ourPlural['target'] = $defPlural['target']; } } } } } }
105
  private function diff( $key, LocoPoMessage $def, array $prev ){ $old = $this->__get($key); $new = $def->__get($key); if( $new !== $old ){ $this->offsetSet($key,$new); if( is_string($old) && '' !== $old ){ $prev[$key] = $old; } } return $prev; }
106
  private function getPlural( $i ){ if( $this->offsetExists('plurals') ){ $plurals = $this->offsetGet('plurals'); if( is_array($plurals) && array_key_exists($i,$plurals) ){ return $plurals[$i]; } } return null; }
107
+ private function exportBasic(){ return [ 'source' => $this['source'], 'context' => $this->context, 'target' => '', ]; }
108
  public function export(){ $a = $this->getArrayCopy(); unset($a['key']); if( array_key_exists('plurals',$a) ){ foreach( $a['plurals'] as $i => $p ){ if( $p instanceof ArrayObject ){ $a['plurals'][$i] = $p->getArrayCopy(); } } } return $a; }
109
  public function countForms(){ $len = 1; if( $this->offsetExists('plurals') ){ $plurals = $this->offsetGet('plurals'); $len += count($plurals); } return $len; }
110
  public function strip(){ $this['target'] = ''; $plurals = $this->plurals; if( is_array($plurals) ){ foreach( $plurals as $p ){ $p->strip(); } } return $this; }
133
  #[ReturnTypeWillChange]
134
  public function next(){ $i = $this->i; while( ++$i < $this->t ){ if( array_key_exists('parent',$this->po[$i]) ){ continue; } $this->j++; $this->i = $i; return; } $this->i = null; $this->j = null; }
135
  #[ReturnTypeWillChange]
136
+ public function current(){ $i = $this->i; $po = $this->po; $parent = new LocoPoMessage( $po[$i] ); $plurals = []; $nonseq = $parent->offsetExists('child'); $j = $nonseq ? $parent['child'] : $i+1; while( isset($po[$j]['parent']) && $i === $po[$j]['parent'] ){ $plurals[] = new LocoPoMessage($po[$j++]); } if( $plurals ){ $parent['plurals'] = $plurals; } return $parent; }
137
  public function getArrayCopy(){ $po = $this->po; if( 0 === $this->z ){ $po[0]['target'] = (string) $this->getHeaders(); } return $po; }
138
+ public function clear(){ if( 0 === $this->z ){ $this->po = [ $this->po[0] ]; $this->t = 1; } else { $this->po = []; $this->t = 0; } }
139
  public function getHeaders(){ if( is_null($this->headers) ){ $header = $this->po[0]; if( 0 === $this->z ){ $this->headers = LocoPoHeaders::fromMsgstr( $header['target'] ); } else { $this->headers = new LocoPoHeaders; } } return $this->headers; }
140
  public function setHeaders( LocoPoHeaders $head ){ $this->headers = $head; if( 0 === $this->z ){ $this->po[0]['target'] = null; } return $this; }
141
  public function initPo(){ if( 0 === $this->z ){ unset( $this->po[0]['flag'] ); } return $this; }
142
  public function initPot(){ if( 0 === $this->z ){ $this->po[0]['flag'] = 4; } return $this; }
143
  public function strip(){ $po = $this->po; $i = count($po); $z = $this->z; while( --$i > $z ){ $po[$i]['target'] = ''; } $this->po = $po; return $this; }
144
  public function __toString(){ try { return $this->render(); } catch( Exception $e ){ trigger_error( $e->getMessage(), E_USER_WARNING ); return ''; } }
145
+ public function render( $sorter = null ){ $width = $this->w; $ref_width = max( 0, $width - 3 ); $h = $this->exportHeader(); $msg = new LocoPoMessage( $h ); $s = $msg->render( $width, $ref_width ); if( $sorter ){ if( ! is_callable($sorter) ){ throw new InvalidArgumentException('Bad callback'); } $msgs = []; foreach( $this as $msg ){ $msgs[] = $msg; } usort( $msgs, $sorter ); } else { $msgs = $this; } $h = $this->getHeaders()->offsetGet('Plural-Forms'); if( is_string($h) && preg_match('/nplurals\\s*=\\s*(\\d)/',$h,$r) ){ $max_pl = (int) $r[1]; } else { $max_pl = 0; } foreach( $msgs as $msg ){ $s .= "\n".$msg->render( $width, $ref_width, $max_pl ); } return $s; }
146
+ public function exportJed(){ $head = $this->getHeaders(); $a = [ '' => [ 'domain' => $head['domain'], 'lang' => $head['language'], 'plural-forms' => $head['plural-forms'], ] ]; foreach( $this as $message ){ if( $message->translated() ){ $a[ $message->getKey() ] = $message->exportSerial(); } } return $a; }
147
+ private function exportHeader(){ if( 0 === $this->z ){ $h = $this->po[0]; } else { $h = [ 'source' => '', 'target' => '' ]; } if( $this->headers ){ $h['target'] = (string) $this->headers; } return $h; }
148
+ public function exportRefs( $grep = '' ){ $a = []; if( '' === $grep ) { $grep = '/(\\S+):\\d+/'; } else { $grep = '/(\\S*'.$grep.'):\\d+/'; } $self = get_class($this); $base = [ $this->exportHeader() ]; foreach( $this as $message ){ if( preg_match_all( $grep, (string) $message->refs, $r ) ){ foreach( $r[1] as $ref ) { if( array_key_exists($ref,$a) ){ $po = $a[$ref]; } else { $po = new $self($base); $a[$ref] = $po; } $po->push($message); } } } return $a; }
149
+ public function splitRefs( array $map = null ){ $a = []; $self = get_class($this); $base = [ $this->exportHeader() ]; if( is_array($map) ){ $grep = implode('|',array_keys($map)); } else { $grep = '[a-z]+'; } foreach( $this as $message ){ $refs = ltrim( (string) $message->refs ); if( '' !== $refs ){ if( preg_match_all('/\\S+\\.('.$grep.'):\\d+/', $refs, $r, PREG_SET_ORDER ) ){ $tmp = []; foreach( $r as $rr ) { list( $ref, $ext ) = $rr; $tmp[$ext][$ref] = true; } foreach( $tmp as $ext => $refs ){ if( is_array($map) ){ $ext = $map[$ext]; } if( array_key_exists($ext,$a) ){ $po = $a[$ext]; } else { $po = new $self($base); $a[$ext] = $po; } $message = clone $message; $message['refs'] = implode(' ',array_keys($refs) ); $po->push($message); } } } } return $a; }
150
+ public function getHashes(){ $a = []; foreach( $this as $msg ){ $a[] = $msg->getHash(); } sort( $a, SORT_STRING ); return $a; }
151
  public function equalSource( LocoPoIterator $that ){ $a = $this->getHashes(); $b = $that->getHashes(); if( count($a) !== count($b) ){ return false; } foreach( $a as $i => $hash ){ if( $hash !== $b[$i] ){ return false; } } return true; }
152
+ public function equal( LocoPoIterator $that ){ if( $this->t !== $that->t ){ return false; } $i = $this->z; $fields = [ 'source', 'context', 'notes', 'refs', 'target', 'comment', 'flag', 'parent', 'plural' ]; while( ++$i < $this->t ){ $a = $this->po[$i]; $b = $that->po[$i]; foreach( $fields as $f ){ $af = isset($a[$f]) ? $a[$f] : ''; $bf = isset($b[$f]) ? $b[$f] : ''; if( $af !== $bf ){ return false; } } } return true; }
153
+ public function sort( $func = null ){ $order = []; foreach( $this as $msg ){ $order[] = $msg; } if( is_null($func) ){ $func = [ __CLASS__, 'compare' ]; } else if( ! is_callable($func) ){ throw new InvalidArgumentException('Bad callback'); } usort( $order, $func ); $this->clear(); foreach( $order as $p ){ $this->push($p); } return $this; }
154
  public static function compare( LocoPoMessage $a, LocoPoMessage $b ){ $h = $a->getHash(); $j = $b->getHash(); $n = strcasecmp( $h, $j ); if( 0 === $n ){ $n = strcmp( $h, $j ); if( 0 === $n ){ return 0; } } return $n > 0 ? 1 : -1; }
155
+ public function createSorter(){ $index = []; foreach( $this as $i => $msg ){ $index[ $msg->getHash() ] = $i; } $obj = new LocoPoIndex( $index ); return [ $obj, 'compare' ]; } }
156
  class LocoMoTable {
157
  private $size = 0;
158
  private $bin = '';
182
  public function enableHash() { $this->hash = new LocoMoTable; }
183
  public function useFuzzy() { $this->use_fuzzy = true; }
184
  public function setHeader( $key, $val ){ $this->head->add($key, $val); return $this; }
185
+ private function str( $s ){ if( $cs = $this->cs ){ $s = mb_convert_encoding($s,$cs,['UTF-8']); } return $s; }
186
+ public function compile(){ $table = ['']; $sources = ['']; $targets = [ (string) $this->head ]; $fuzzy_flag = 4; $skip_fuzzy = ! $this->use_fuzzy; if( $this->head->has('Plural-Forms') && preg_match('/^nplurals=(\\d)/',$this->head->trimmed('Plural-Forms'), $r) ){ $nplurals = (int) $r[1]; $maxplural = max( 0, $nplurals-1 ); } else { $maxplural = 1; } foreach( $this->msgs as $r ){ if( $skip_fuzzy && isset($r['flag']) && $fuzzy_flag === $r['flag'] ){ continue; } $msgid = $this->str( $r['key'] ); if( isset($r['context']) ){ $msgctxt = $this->str( $r['context'] ); if( '' !== $msgctxt ){ if( '' === $msgid ){ $msgid = '('.$msgctxt.')'; } $msgid = $msgctxt."\x04".$msgid; } } if( '' === $msgid ){ continue; } $msgstr = $this->str( $r['target'] ); if( '' === $msgstr ){ continue; } $table[] = $msgid; if( isset($r['plurals']) ){ if( $r['plurals'] ){ $i = 0; foreach( $r['plurals'] as $i => $p ){ if( $i === 0 ){ $msgid .= "\0".$this->str($p['key']); } $msgstr .= "\0".$this->str($p['target']); } while( $maxplural > ++$i ){ $msgstr .= "\0"; } } else if( isset($r['plural_key']) ){ $msgid .= "\0".$this->str($r['plural_key']); } } $sources[] = $msgid; $targets[] = $msgstr; } asort( $sources, SORT_STRING ); $this->bin = "\xDE\x12\x04\x95\x00\x00\x00\x00"; $n = count($sources); $this->writeInteger( $n ); $offset = 28; $this->writeInteger( $offset ); $offset += $n * 8; $this->writeInteger( $offset ); if( $this->hash ){ sort( $table, SORT_STRING ); $this->hash->compile( $table ); $s = $this->hash->count(); } else { $s = 0; } $this->writeInteger( $s ); $offset += $n * 8; $this->writeInteger( $offset ); if( $s ){ $offset += $s * 4; } $source = ''; foreach( $sources as $i => $str ){ $source .= $str."\0"; $this->writeInteger( $strlen = strlen($str) ); $this->writeInteger( $offset ); $offset += $strlen + 1; } $target = ''; foreach( array_keys($sources) as $i ){ $str = $targets[$i]; $target .= $str."\0"; $this->writeInteger( $strlen = strlen($str) ); $this->writeInteger( $offset ); $offset += $strlen + 1; } if( $this->hash ){ $this->bin .= $this->hash->__toString(); } $this->bin .= $source; $this->bin .= $target; return $this->bin; }
187
  private function writeInteger( $num ){ $this->bin .= pack( 'V', $num ); return $this; } }
188
  interface LocoTokensInterface extends Iterator {
189
  public function advance();
194
  private $line;
195
  private $col;
196
  private $max;
197
+ private $rules = [];
198
+ private $skip = [];
199
  private $tok;
200
  private $len;
201
  public function __construct( $src = '' ){ $this->init($src); }
202
+ public function parse( $src ){ $tokens = []; $this->init($src); while( $tok = $this->advance() ){ $tokens[] = $tok; } return $tokens; }
203
  public function init( $src ){ $this->src = $src; $this->rewind(); return $this; }
204
+ public function define( $grep, $t = 0 ){ if('^' !== $grep[1] ){ throw new InvalidArgumentException('Expression '.$grep.' isn\'t anchored'); } if( ! is_int($t) && ! is_callable($t) ){ throw new InvalidArgumentException('Non-integer token must be valid callback'); } $sniff = $grep[2]; if( $sniff === preg_quote($sniff,$grep[0]) ){ $this->rules[$sniff][] = [ $grep, $t ]; } else { $this->rules[''][] = [ $grep, $t ]; } return $this; }
205
  public function ignore( array $a ){ foreach( $a as $t ){ $this->skip[$t] = true; } return $this; }
206
  #[ReturnTypeWillChange]
207
  public function current(){ return $this->tok; }
208
  public function advance(){ $tok = $this->current(); $this->next(); return $tok; }
209
  #[ReturnTypeWillChange]
210
+ public function next(){ $tok = null; $offset = $this->pos; $column = $this->col; $line = $this->line; while( $offset <= $this->max ){ $t = null; $s = ''; $text = substr($this->src,$offset); foreach( [$text[0],''] as $k ){ if( isset($this->rules[$k]) ) { foreach( $this->rules[$k] as $rule) { if( preg_match($rule[0], $text, $match ) ) { $s = $match[0]; $t = $rule[1]; if( ! is_int($t) ) { $t = call_user_func( $t, $s, $match ); } break 2; } } } } if( is_null($t) ){ $n = preg_match('/^./u',$text,$match); if( false === $n ){ $s = $text[0]; $match = [ mb_convert_encoding($s,'UTF-8','cp1252') ]; } $s = (string) $match[0]; $t = self::T_UNKNOWN; } $length = strlen($s); if( 0 === $length ){ throw new Loco_error_ParseException('Failed to match anything'); } $offset += $length; $lines = preg_split('/\\r?\\n/',$s); $nlines = count($lines); if( $nlines > 1 ){ $next_line = $line + ( $nlines - 1 ); $next_column = strlen( end($lines) ); } else { $next_line = $line; $next_column = $column + $length; } if( array_key_exists($t,$this->skip) ){ $line = $next_line; $column = $next_column; continue; } $tok = self::T_LITERAL === $t ? $s : [ $t, $s, $line, $column ]; $line = $next_line; $column = $next_column; $this->len++; break; } $this->tok = $tok; $this->pos = $offset; $this->col = $column; $this->line = $line; }
211
  #[ReturnTypeWillChange]
212
  public function key(){ return $this->len ? $this->len-1 : null; }
213
  #[ReturnTypeWillChange]
220
  class LocoEscapeParser {
221
  private $map;
222
  private $grep;
223
+ public function __construct( array $map = [] ){ $this->map = $map; $rules = ['\\\\']; if( $map ){ $rules[] = '['.implode(array_keys($map)).']'; } if( ! isset($map['U']) ) { $rules[] = 'U[0-9A-Fa-f]{5,8}'; } if( ! isset($map['u']) ) { $rules[] = 'u(?:\\{[0-9A-Fa-f]+\\}|[0-9A-Fa-f]{1,4})(?:\\\\u(?:\\{[0-9A-Fa-f]+\\}|[0-9A-Fa-f]{1,4}))*'; } $this->grep = '/\\\\('.implode('|',$rules).')/'; }
224
+ final public function unescape( $s ) { if( '' !== $s ) { return $this->stripSlashes( preg_replace_callback($this->grep, [$this, 'unescapeMatch'], $s) ); } return ''; }
225
  final public function unescapeMatch( array $r ) { $s = $r[0]; $c = $s[1]; if( isset($this->map[$c]) ){ return $this->map[$c]; } if( 'u' === $c ){ $str = ''; $surrogates = false; foreach( explode('\\u',$s) as $i => $h ){ if( '' !== $h ){ $h = ltrim( trim($h,'{}'),'0'); $u = intval($h,16); $str.= loco_utf8_chr($u); if( ! $surrogates ){ $surrogates = $u >= 0xD800 && $u <= 0xDBFF; } } } if( $surrogates ){ $str = loco_resolve_surrogates($str); } return $str; } if( 'U' === $c ){ return loco_utf8_chr( intval(substr($s,2),16) ); } if( 'x' === $c ){ return chr( intval(substr($s,2),16) ); } if( ctype_digit($c) ){ return chr( intval(substr($s,1),8) ); } return $s; }
226
  protected function stripSlashes( $s ) { return stripcslashes($s); } }
227
  class LocoJsTokens extends LocoTokenizer { const T_KWORD = 1; const T_REGEX = 2;
228
  private static $lex;
229
+ protected static $words = [ 'true' => 1, 'false' => 1, 'null' => 1, 'break' => T_BREAK, 'else' => T_ELSE, 'new' => T_NEW, 'var' => 1, 'case' => T_CASE, 'finally' => T_FINALLY, 'return' => T_RETURN, 'void' => 1, 'catch' => T_CATCH, 'for' => T_FOR, 'switch' => T_SWITCH, 'while' => T_WHILE, 'continue' => T_CONTINUE, 'function' => T_FUNCTION, 'this' => T_STRING, 'with' => 1, 'default' => T_DEFAULT, 'if' => T_IF, 'throw' => T_THROW, 'delete' => 1, 'in' => 1, 'try' => T_TRY, 'do' => T_DO, 'instanceof' => 1, 'typeof' => 1, ];
230
+ public static function decapse( $encapsed ){ $s = substr($encapsed,1,-1); $l = self::$lex; if( is_null($l) ){ $l = new LocoEscapeParser( [ 'U' => 'U', 'a' => 'a', ] ); self::$lex = $l; } return $l->unescape($s); }
231
+ public function __construct( $src = '' ){ $this->define('/^(?:\\\\u[0-9A-F]{4,4}|[$_\\pL\\p{Nl}])(?:\\\\u[0-9A-F]{4}|[$_\\pL\\pN\\p{Mn}\\p{Mc}\\p{Pc}])*/ui', [$this,'matchWord'] ); $this->define('/^\\s+/u', T_WHITESPACE ); $this->define('!^//.*!', T_COMMENT ); $this->define('!^/\\*.*\\*/!Us', [$this,'matchComment'] ); $this->define('/^"(?:\\\\.|[^\\r\\n\\p{Zl}\\p{Zp}"\\\\])*"/u', T_CONSTANT_ENCAPSED_STRING ); $this->define('/^\'(?:\\\\.|[^\\r\\n\\p{Zl}\\p{Zp}\'\\\\])*\'/u', T_CONSTANT_ENCAPSED_STRING ); $this->define('/^[-+;,<>.=:|&^!?*%~(){}[\\]]/'); parent::__construct($src); }
232
  public function matchWord( $s ){ if( array_key_exists($s,self::$words) ){ return self::$words[$s]; } return T_STRING; }
233
  public function matchComment( $s ){ if( '/**' === substr($s,0,3) ){ return T_DOC_COMMENT; } return T_COMMENT; } }
234
  class LocoExtracted implements Countable {
235
+ private $exp = [];
236
+ private $reg = [];
237
+ private $dom = [];
238
  private $dflt = '';
239
  public function extractSource( LocoExtractor $ext, $src, $fileref = '' ){ $ext->extract( $this, $ext->tokenize($src), $fileref ); return $this; }
240
  public function export(){ return $this->exp; }
243
  public function getDomainCounts(){ return $this->dom; }
244
  public function setDomain( $default ){ $this->dflt = (string) $default; return $this; }
245
  public function getDomain(){ return $this->dflt; }
246
+ private function key( array $entry ){ $key = (string) $entry['source']; foreach( ['context','domain'] as $i => $prop ){ if( array_key_exists($prop,$entry) ) { $add = (string) $entry[$prop]; if( '' !== $add ){ $key .= ord($i).$add; } } } return $key; }
247
+ public function pushMeta( $source, $notes, $domain = '' ){ if( '' === $domain || '*' === $domain ){ $domain = $this->dflt; } return $this->pushEntry( [ 'source' => $source, 'notes' => $notes, ], $domain ); }
248
  public function pushEntry( array $entry, $domain = '' ){ $entry['id'] = ''; $entry['target'] = ''; $entry['domain'] = $domain; $key = $this->key($entry); if( isset($this->reg[$key]) ){ $index = $this->reg[$key]; $clash = $this->exp[$index]; if( $value = $this->mergeField( $clash, $entry, 'refs', ' ') ){ $this->exp[$index]['refs'] = $value; } if( $value = $this->mergeField( $clash, $entry, 'notes', "\n") ){ $this->exp[$index]['notes'] = $value; } } else { $index = count($this->exp); $this->reg[$key] = $index; $this->exp[$index] = $entry; if( isset($this->dom[$domain]) ){ $this->dom[$domain]++; } else { $this->dom[$domain] = 1; } } return $index; }
249
+ public function pushPlural( array $entry, $sindex ){ $parent = $this->exp[$sindex]; $domain = $parent['domain']; $pkey = $this->key($parent)."\2"; if( ! array_key_exists($pkey,$this->reg) ){ $pindex = count($this->exp); $this->reg[$pkey] = $pindex; $entry += [ 'id' => '', 'target' => '', 'plural' => 1, 'parent' => $sindex, 'domain' => $domain, ]; $this->exp[$pindex] = $entry; if( isset($entry['format']) && ! isset( $parent['format']) ) { $this->exp[$sindex]['format'] = $entry['format']; } if( $pindex !== $sindex + $entry['plural']) { $this->exp[$sindex]['child'] = $pindex; } } }
250
  public function mergeField( array $old, array $new, $field, $glue ){ $prev = isset($old[$field]) ? $old[$field] : ''; if( isset($new[$field]) ){ $text = $new[$field]; if( '' !== $prev && $prev !== $text ){ if( 'notes' === $field && preg_match( '/^'.preg_quote( rtrim($text,'. '),'/').'[. ]*$/mu', $prev ) ) { $text = $prev; } else { $text = $prev.$glue.$text; } } return $text; } return $prev; }
251
+ public function filter( $domain ){ $map = []; $newOffset = 1; $matchAll = '*' === $domain; $raw = [ [ 'id' => '', 'source' => '', 'target' => '', 'domain' => $matchAll ? '' : $domain, ] ]; foreach( $this->exp as $oldOffset => $r ){ if( isset($r['parent']) ){ if( isset($map[$r['parent']]) ){ $r['parent'] = $map[ $r['parent'] ]; $raw[ $newOffset++ ] = $r; } } else { if( $matchAll ){ $match = true; } else if( isset($r['domain']) ){ $match = $domain === $r['domain']; } else { $match = $domain === ''; } if( $match ){ $map[ $oldOffset ] = $newOffset; $raw[ $newOffset++ ] = $r; } } } return $raw; } }
252
  abstract class LocoExtractor {
253
  private $rules;
254
+ private $wp = [];
255
  private $domain = '';
256
  abstract public function tokenize( $src );
257
  abstract public function extract( LocoExtracted $strings, LocoTokensInterface $tokens, $fileref = '' );
264
  protected function getHeaders(){ return $this->wp; }
265
  final public function extractSource( $src, $fileref ){ $strings = new LocoExtracted; $this->extract( $strings, $this->tokenize($src), $fileref ); return $strings; }
266
  public function rule( $s ){ return isset($this->rules[$s]) ? $this->rules[$s] : ''; }
267
+ protected function push( LocoExtracted $strings, $rule, array $args, $comment = '', $ref = '' ){ $s = strpos( $rule, 's'); $p = strpos( $rule, 'p'); $c = strpos( $rule, 'c'); $d = strpos( $rule, 'd'); if( false === $s || ! isset($args[$s]) ){ return null; } $msgid = $args[$s]; if( ! is_string($msgid) ){ return null; } $entry = [ 'source' => $msgid, ]; if( is_int($c) && isset($args[$c]) ){ $entry['context'] = $args[$c]; } else if( '' === $msgid ){ return null; } if( $ref ){ $entry['refs'] = $ref; } if( is_int($d) && array_key_exists($d,$args) ){ $domain = $args[$d]; if( is_null($domain) ){ $domain = ''; } } else if( '' === $this->domain ) { $domain = $strings->getDomain(); } else { $domain = $this->domain; } $parse_printf = true; if( $comment = $this->comment($comment) ){ if( preg_match('/^xgettext:\\s*([-a-z]+)-format\\s*/mi', $comment, $r, PREG_OFFSET_CAPTURE ) ){ $entry['format'] = $r[1][0]; $comment = trim( substr_replace( $comment,'', $r[0][1], strlen($r[0][0]) ) ); $parse_printf = ( 'no-' === substr($entry['format'],0,3) ) ? false : null; } if( preg_match('/^references?:( *.+:\\d+)*\\s*/mi', $comment, $r, PREG_OFFSET_CAPTURE ) ){ $entry['refs'] = trim($r[1][0],' '); $comment = trim( substr_replace( $comment, '', $r[0][1], strlen($r[0][0]) ) ); } $entry['notes'] = $comment; } if( $parse_printf && ( $format = $this->fsniff($msgid) ) ){ $entry['format'] = $format; } $index = $strings->pushEntry($entry,$domain); if( is_int($p) && isset($args[$p]) ){ $msgid_plural = $args[$p]; $entry = [ 'source' => $msgid_plural, ]; if( false !== $parse_printf && ( $format = $this->fsniff($msgid_plural) ) ){ $entry['format'] = $format; } $strings->pushPlural($entry,$index); } return $index; }
268
  protected function utf8( $str ){ if( false === preg_match('//u',$str) ){ $str = mb_convert_encoding( $str, 'UTF-8', 'cp1252' ); } return $str; } }
269
  class LocoPHPTokens implements LocoTokensInterface, Countable {
270
  private $i;
271
  private $tokens;
272
+ private $skip_tokens = [];
273
+ private $literal_tokens = [];
274
  public function __construct( array $tokens ){ $this->tokens = $tokens; $this->rewind(); }
275
  public function literal( array $a ){ foreach( $a as $t ){ $this->literal_tokens[ $t ] = 1; } return $this; }
276
  public function ignore( array $a ){ foreach( $a as $t ){ $this->skip_tokens[$t] = true; } return $this; }
277
+ public function export(){ $arr = []; $this->rewind(); while( $tok = $this->advance() ){ $arr[] = $tok; } return $arr; }
278
  public function advance(){ $tok = $this->current(); $this->next(); return $tok; }
279
  #[ReturnTypeWillChange]
280
  public function rewind(){ $this->i = ( false === reset($this->tokens) ? null : key($this->tokens) ); }
286
  public function next(){ $this->i = ( false === next($this->tokens) ? null : key($this->tokens) ); }
287
  #[ReturnTypeWillChange]
288
  public function current(){ if( ! $this->valid() ){ return false; } $tok = $this->tokens[$this->i]; if( is_array($tok) && isset($this->literal_tokens[$tok[0]]) ){ return $tok[1]; } return $tok; }
289
+ public function __toString(){ $s = []; foreach( $this as $token ){ $s[] = is_array($token) ? $token[1] : $token; } return implode('',$s); }
290
  #[ReturnTypeWillChange]
291
  public function count(){ return count($this->tokens); } }
292
  class LocoPHPEscapeParser extends LocoEscapeParser {
293
+ public function __construct(){ parent::__construct( [ 'n' => "\n", 'r' => "\r", 't' => "\t", 'v' => "\x0B", 'f' => "\x0C", 'e' => "\x1B", '$' => '$', '\\' => '\\', '"' => '"', ] ); }
294
+ protected function stripSlashes( $s ) { return preg_replace_callback('/\\\\(x[0-9A-Fa-f]{1,2}|[0-3]?[0-7]{1,2})/', [$this,'unescapeMatch'], $s, -1, $n ); } }
295
  function loco_unescape_php_string( $s ){ static $l; if( is_null($l) ) { $l = new LocoPHPEscapeParser; } return $l->unescape($s); }
296
+ function loco_decapse_php_string( $s ){ if( ! $s ){ return (string) $s; } $q = $s[0]; if( "'" === $q ){ return str_replace( ['\\'.$q, '\\\\'], [$q, '\\'], substr( $s, 1, -1 ) ); } if( '"' !== $q ){ return $s; } return loco_unescape_php_string( substr($s,1,-1) ); }
297
+ function loco_parse_php_comment($comment){ $comment = trim( $comment,"/ \n\r\t" ); if( '' !== $comment && '*' === $comment[0] ){ $lines = []; $junk = "\r\t/ *"; foreach( explode("\n",$comment) as $line ){ $line = trim($line,$junk); if( '' !== $line ){ $lines[] = $line; } } $comment = implode("\n", $lines); } return $comment; }
298
+ function loco_parse_wp_comment( $block ){ $header = []; if( '/*' === substr($block,0,2) ){ $junk = "\r\t/ *"; foreach( explode("\n", $block) as $line ){ if( false !== ( $i = strpos($line,':') ) ){ $key = substr($line,0,$i); $val = substr($line,++$i); $header[ trim($key,$junk) ] = trim($val,$junk); } } } return $header; }
299
  function loco_sniff_printf( $s, $p, $limit = 0, $offset = 0 ){ $n = 0; while( is_string($s) && '' !== $s && false !== ( $i = strpos($s,'%',$offset) ) ){ if( 0 !== $i ){ $s = substr( $s, $i ); } if( preg_match( $p, $s, $r ) ){ $match = $r[0]; if( 0 < $n && isset($r[1]) && '' === $r[1] && '%' !== substr($match,-1) ){ return 0; } if( ++$n === $limit ){ break; } $offset = strlen($match); } else { return 0; } } return $n; }
300
  function loco_sniff_php_printf( $s, $limit = 0 ){ return loco_sniff_printf( $s, '/^%(?:[1-9]\\d*\\$)?(?:\'.|[-+0 ])*\\d*(?:\\.\\d+)?[suxXbcdeEfFgGo%]/', $limit ); }
301
  class LocoPHPExtractor extends LocoExtractor {
302
+ private $defs = [];
303
  public function tokenize( $src ){ return new LocoPHPTokens( token_get_all($src) ); }
304
  public function decapse( $raw ){ return loco_decapse_php_string( $raw ); }
305
  public function fsniff( $str ){ return loco_sniff_php_printf($str) ? 'php' : ''; }
306
  protected function comment( $comment ){ $comment = loco_parse_php_comment($comment); $comment = preg_replace('/^translators:\\s+/mi', '', $comment ); return $comment; }
307
  public function define( $name, $value ){ if( is_string($value) ){ $this->defs[$name] = $value; } return $this; }
308
+ public function extract( LocoExtracted $strings, LocoTokensInterface $tokens, $fileref = '' ){ $tokens->ignore( [T_WHITESPACE] ); $n = 0; $depth = 0; $comment = ''; $narg = 0; $args = []; $ref = ''; $rule = ''; $wp = $this->getHeaders(); $tokens->rewind(); while( $tok = $tokens->advance() ){ if( is_string($tok) ){ $s = $tok; $t = null; } else { $t = $tok[0]; $s = $tok[1]; } if( $depth ){ if( ')' === $s || ']' === $s ){ if( 0 === --$depth ){ if( $this->push( $strings, $rule, $args, $comment, $ref ) ){ $n++; } $comment = ''; } } else if( '(' === $s || '[' === $s ){ $depth++; $args[$narg] = null; } else if( 1 === $depth ){ if( ',' === $s ){ $narg++; } else if( T_CONSTANT_ENCAPSED_STRING === $t ){ $s = self::utf8($s); $args[$narg] = $this->decapse($s); } else if( T_STRING === $t && array_key_exists($s,$this->defs) ){ $args[$narg] = $this->defs[$s]; } else { $args[$narg] = null; } } } else if( T_COMMENT === $t || T_DOC_COMMENT === $t ){ $was_header = false; $s = self::utf8($s); if( 0 === $n ){ if( false !== strpos($s,'* @package') ){ $was_header = true; } if( $wp && ( $header = loco_parse_wp_comment($s) ) ){ foreach( $wp as $domain => $tags ){ foreach( array_intersect_key($header,$tags) as $tag => $source ){ $strings->pushMeta( $source, $tags[$tag], (string) $domain ); $was_header = true; } } } } if( ! $was_header ) { $comment = $s; } } else if( T_STRING === $t && '(' === $tokens->advance() && ( $rule = $this->rule($s) ) ){ $ref = $fileref ? $fileref.':'.$tok[2]: ''; $depth = 1; $args = []; $narg = 0; } else if( $comment ){ if( false === stripos($comment, 'translators:') && false === strpos($comment, 'xgettext:') ){ $comment = ''; } } } return $this; } }
309
  function loco_sniff_js_printf( $s, $limit = 0 ){ return loco_sniff_printf( $s, '/^%(?:[1-9]\\d*\\$)?\\+?(?:0|\'[^$])?-?\\d*(?:\\.\\d+)?[b-gijostTuvxX%]/', $limit ); }
310
  class LocoJsExtractor extends LocoPHPExtractor {
311
  public function tokenize( $src ){ return new LocoJsTokens($src); }
313
  public function decapse( $encapsed ){ return LocoJsTokens::decapse($encapsed); } }
314
  class LocoTwigExtractor extends LocoPHPExtractor {
315
  public function tokenize( $src ){ $src = '<?php '.preg_replace('/{#([^#]+)#}/su','/*\\1*/',$src); return parent::tokenize($src); } }
316
+ function loco_wp_extractor( $type = 'php' ){ static $rules = [ '__' => 'sd', '_e' => 'sd', '_c' => 'sd', '_n' => 'sp_d', '_n_noop' => 'spd', '_nc' => 'sp_d', '__ngettext' => 'spd', '__ngettext_noop' => 'spd', '_x' => 'scd', '_ex' => 'scd', '_nx' => 'sp_cd', '_nx_noop' => 'spcd', 'esc_attr__' => 'sd', 'esc_html__' => 'sd', 'esc_attr_e' => 'sd', 'esc_html_e' => 'sd', 'esc_attr_x' => 'scd', 'esc_html_x' => 'scd', ]; if( 'php' === $type ){ $extr = new LocoPHPExtractor($rules); } else if( 'twig' === $type ){ $extr = new LocoTwigExtractor($rules); } else if( 'js' === $type ){ $extr = new LocoJsExtractor($rules); } else { throw new InvalidArgumentException('No string extractor for '.$type); } return $extr; }
317
  function loco_string_percent( $n, $t ) { if( ! $t || ! $n ){ $s = '0'; } else if( $t === $n ){ $s = '100'; } else { $dp = 0; $n = 100 * $n / $t; if( $n > 99 ){ $s = number_format( min( $n, 99.9 ), ++$dp ); } else if( $n < 0.5 ){ $n = max( $n, 0.0001 ); do { $s = number_format( $n, ++$dp ); } while( preg_match('/^0\\.0+$/',$s) && $dp < 4 ); $s = substr($s,1); } else { $s = number_format( $n, $dp ); } } return $s; }
318
  function loco_print_progress( $translated, $untranslated, $flagged ) { $total = $translated + $untranslated; $complete = loco_string_percent( $translated - $flagged, $total ); $class = 'progress'; if( ! $translated && ! $flagged ){ $class .= ' empty'; } else if( '100' === $complete ){ $class .= ' done'; } echo '<div class="',$class,'"><div class="t">'; if( $flagged ){ $s = loco_string_percent( $flagged, $total ); echo '<div class="bar f" style="width:',$s,'%">&nbsp;</div>'; } if( '0' === $complete ){ echo '&nbsp;'; } else { $class = 'bar p'; $p = (int) $complete; $class .= sprintf(' p-%u', 10*floor($p/10) ); $style = 'width:'.$complete.'%'; if( $flagged ){ $remain = 100.0 - (float) $s; $style .= '; max-width: '.sprintf('%s',$remain).'%'; } echo '<div class="',$class,'" style="'.$style.'">&nbsp;</div>'; } echo '</div><div class="l">',$complete,'%</div></div>'; }
319
  class LocoFuzzyMatcher implements Countable {
320
+ private $pot = [];
321
+ private $po = [];
322
+ private $diff = [];
323
  private $dmax = .20;
324
  #[ReturnTypeWillChange]
325
  public function count(){ return count($this->pot); }
329
  public function add( $a ){ $source = isset($a['source']) ? (string) $a['source'] : ''; $context = isset($a['context']) ? (string) $a['context'] : ''; $key = $source."\4".$context; $this->pot[$key] = $a; }
330
  private function key( $a ){ $source = isset($a['source']) ? (string) $a['source'] : ''; $context = isset($a['context']) ? (string) $a['context'] : ''; return $source."\4".$context; }
331
  protected function getRef( $a ){ $key = $this->key($a); return array_key_exists($key,$this->pot) ? $this->pot[$key] : null; }
332
+ public function match( $a ) { $old = $this->key($a); if( isset($this->pot[$old]) ){ $new = $this->pot[$old]; unset($this->pot[$old]); return $new; } $this->po[$old] = $a; $target = isset($a['target']) ? (string) $a['target'] : ''; $comment = isset($a['comment']) ? (string) $a['comment'] : ''; if( '' === $target && '' === $comment ){ return null; } if( 0 < $this->dmax ){ foreach( $this->pot as $new => $_ ){ $dist = $this->distance($old,$new); if( -1 !== $dist ){ $this->diff[] = [ $old, $new, $dist ]; } } } return null; }
333
  private function distance( $a, $b ){ $a = strtolower($a); $b = strtolower($b); if( $a === $b ){ return 0; } $lenA = strlen($a); $lenB = strlen($b); $lenDiff = abs($lenA-$lenB); $max = min($lenA,$lenB) + $lenDiff; $max = (int) ceil( $this->dmax * $max ); if( $max < $lenDiff ) { return -1; } $len = max($lenA,$lenB); if( $len < 256 ){ $d = levenshtein($a,$b); return $d > $max ? -1 : $d; } $d = 0; for( $i = 0; $i < $len; $i+=$max ){ $aa = substr($a,$i,$max); $bb = substr($b,$i,$max); $d += levenshtein($aa,$bb); if( $d > $max ){ return -1; } } return $d; }
334
+ public function getFuzzyMatches(){ $pairs = []; usort( $this->diff, [__CLASS__,'compareDistance'] ); foreach( $this->diff as $pair ){ list($old,$new) = $pair; if( ! array_key_exists($new,$this->pot) || ! array_key_exists($old,$this->po) ){ continue; } $pairs[] = [ $this->po[$old], $this->pot[$new], ]; unset($this->po[$old]); unset($this->pot[$new]); if( ! $this->po || ! $this->pot ){ break; } } $this->diff = []; return $pairs; }
335
  private static function compareDistance( array $a, array $b ){ return $a[2] - $b[2]; } }
336
  defined('T_FINALLY') || define('T_FINALLY',500); if( function_exists('loco_check_extension') ) { loco_check_extension('mbstring'); }
lib/compiled/locales.php CHANGED
@@ -1,5 +1,6 @@
1
  <?php
2
  /**
3
- * Downgraded for PHP 5.2 compatibility. Do not edit.
 
4
  */
5
- function loco_parse_wp_locale( $tag ){ if( ! preg_match( '/^([a-z]{2,3})(?:[-_]([a-z]{2}))?(?:[-_]([a-z0-9]{3,8}))?$/i', $tag, $tags ) ){ throw new InvalidArgumentException('Invalid WordPress locale: '.json_encode($tag) ); } $data = array( 'lang' => strtolower( $tags[1] ), ); if( isset($tags[2]) && ( $subtag = $tags[2] ) ){ $data['region'] = strtoupper($tags[2]); } if( isset($tags[3]) && ( $subtag = $tags[3] ) ){ $data['variant'] = strtolower($tags[3]); } return $data; }
1
  <?php
2
  /**
3
+ * Downgraded for PHP 5.6 compatibility. Do not edit.
4
+ * @noinspection ALL
5
  */
6
+ function loco_parse_wp_locale( $tag ){ if( ! preg_match( '/^([a-z]{2,3})(?:[-_]([a-z]{2}))?(?:[-_]([a-z0-9]{3,8}))?$/i', $tag, $tags ) ){ throw new InvalidArgumentException('Invalid WordPress locale: '.json_encode($tag) ); } $data = [ 'lang' => strtolower( $tags[1] ), ]; if( isset($tags[2]) && ( $subtag = $tags[2] ) ){ $data['region'] = strtoupper($tags[2]); } if( isset($tags[3]) && ( $subtag = $tags[3] ) ){ $data['variant'] = strtolower($tags[3]); } return $data; }
lib/compiled/phpunit.php CHANGED
@@ -1,21 +1,22 @@
1
  <?php
2
  /**
3
- * Downgraded for PHP 5.2 compatibility. Do not edit.
 
4
  */
5
  class LocoDomQueryFilter {
6
  private $tag = '';
7
- private $attr = array();
8
- public function __construct( $value ){ $id = '[-_a-z][-_a-z0-9]*'; if( ! preg_match('/^([a-z1-6]*)(#'.$id.')?(\.'.$id.')?(\[(\w+)="(.+)"\])?$/i', $value, $r ) ){ throw new InvalidArgumentException('Bad filter, '.$value ); } if( $r[1] ){ $this->tag = $r[1]; } if( ! empty($r[2]) ){ $this->attr['id'] = substr($r[2],1); } if( ! empty($r[3]) ){ $this->attr['class'] = substr($r[3],1); } if( ! empty($r[4]) ){ $this->attr[ $r[5] ] = $r[6]; } }
9
- public function filter( DOMElement $el ){ if( '' !== $this->tag ){ $list = $el->getElementsByTagName($this->tag); $recursive = false; } else { $list = $el->childNodes; $recursive = true; } if( $this->attr ){ $list = $this->reduce( $list, new ArrayIterator, $recursive )->getArrayCopy(); } return $list; }
10
  public function reduce( DOMNodeList $list, ArrayIterator $reduced, $recursive ) { foreach( $list as $node ){ if( $node instanceof DOMElement ){ $matched = false; foreach( $this->attr as $name => $value ){ if( ! $node->hasAttribute($name) ){ $matched = false; break; } $values = array_flip( explode(' ', $node->getAttribute($name) ) ); if( ! isset($values[$value]) ){ $matched = false; break; } $matched = true; } if( $matched ){ $reduced[] = $node; } if( $recursive && $node->hasChildNodes() ){ $this->reduce( $node->childNodes, $reduced, true ); } } } return $reduced; } }
11
  class LocoDomQuery extends ArrayIterator {
12
  public static function parse( $source ) { $dom = new DOMDocument('1.0', 'UTF-8' ); $dom->preserveWhitespace = true; $dom->formatOutput = false; $source = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>'.$source.'</body></html>'; $used_errors = libxml_use_internal_errors(true); $opts = LIBXML_HTML_NODEFDTD; $parsed = $dom->loadHTML( $source, $opts ); $errors = libxml_get_errors(); $used_errors || libxml_use_internal_errors(false); libxml_clear_errors(); if( $errors || ! $parsed ){ $e = new Loco_error_ParseException('Unknown parse error'); foreach( $errors as $error ){ $e = new Loco_error_ParseException( trim($error->message) ); $e->setContext( $error->line, $error->column, $source ); if( LIBXML_ERR_FATAL === $error->level ){ throw $e; } } if( ! $parsed ){ throw $e; } } return $dom; }
13
- public function __construct( $value ){ if( $value instanceof DOMDocument ){ $value = array( $value->documentElement ); } else if( $value instanceof DOMNode ){ $value = array( $value ); } if( is_iterable($value) ){ $nodes = array(); foreach( $value as $node ){ $nodes[] = $node; } } else if( is_string($value) || method_exists($value,'__toString') ){ $value = self::parse( $value ); $nodes = array( $value->documentElement ); } else { $type = is_object($value) ? get_class($value) : gettype($value); throw new InvalidArgumentException('Cannot construct DOM from '.$type ); } parent::__construct( $nodes ); }
14
- public function eq( $index ) { $q = new LocoDomQuery(array()); if( $el = $this[$index] ){ $q[] = $el; } return $q; }
15
- public function find( $value ) { $q = new LocoDomQuery( array() ); $f = new LocoDomQueryFilter($value); foreach( $this as $el ){ foreach( $f->filter($el) as $match ){ $q[] = $match; } } return $q; }
16
- public function children() { $q = new LocoDomQuery(array()); foreach( $this as $el ){ if( $el instanceof DOMNode ){ foreach( $el->childNodes as $child ) { $q[] = $child; } } } return $q; }
17
  public function text(){ $s = ''; foreach( $this as $el ){ $s .= $el->textContent; } return $s; }
18
  public function html() { $s = ''; foreach( $this as $outer ){ foreach( $outer->childNodes as $inner ){ $s .= $inner->ownerDocument->saveXML($inner); } break; } return $s; }
19
  public function attr( $name ) { foreach( $this as $el ){ return $el->getAttribute($name); } return null; }
20
  public function getFormData() { parse_str( $this->serializeForm(), $data ); return $data; }
21
- public function serializeForm() { $pairs = array(); foreach( array('input','select','textarea','button') as $type ){ foreach( $this->find($type) as $field ){ $name = $field->getAttribute('name'); if( ! $name ){ continue; } if( $field->hasAttribute('type') ){ $type = $field->getAttribute('type'); } if( 'select' === $type ){ $value = null; $f = new LocoDomQueryFilter('option'); foreach( $f->filter($field) as $option ){ if( $option->hasAttribute('value') ){ $_value = $option->getAttribute('value'); } else { $_value = $option->nodeValue; } if( $option->hasAttribute('selected') ){ $value = $_value; break; } else if( is_null($value) ){ $value = $_value; } } if( is_null($value) ){ $value = ''; } } else if( 'checkbox' === $type || 'radio' === $type ){ if( $field->hasAttribute('checked') ){ $value = $field->getAttribute('value'); } else { continue; } } else if( 'file' === $type ){ $value = ''; } else if( $field->hasAttribute('value') ){ $value = $field->getAttribute('value'); } else { $value = $field->textContent; } $pairs[] = sprintf('%s=%s', rawurlencode($name), rawurlencode($value) ); } } return implode('&',$pairs); } }
1
  <?php
2
  /**
3
+ * Downgraded for PHP 5.6 compatibility. Do not edit.
4
+ * @noinspection ALL
5
  */
6
  class LocoDomQueryFilter {
7
  private $tag = '';
8
+ private $attr = [];
9
+ public function __construct( $value ){ $id = '[-_a-z][-_a-z0-9]*'; if( ! preg_match('/^([a-z1-6]*)(#'.$id.')?(\\.'.$id.')?(\\[(\\w+)="(.+)"])?$/i', $value, $r ) ){ throw new InvalidArgumentException('Bad filter, '.$value ); } if( $r[1] ){ $this->tag = $r[1]; } if( ! empty($r[2]) ){ $this->attr['id'] = substr($r[2],1); } if( ! empty($r[3]) ){ $this->attr['class'] = substr($r[3],1); } if( ! empty($r[4]) ){ $this->attr[ $r[5] ] = $r[6]; } }
10
+ public function filter( DOMElement $el ) { if( '' !== $this->tag ){ $list = $el->getElementsByTagName($this->tag); $recursive = false; } else { $list = $el->childNodes; $recursive = true; } if( $this->attr ){ $list = $this->reduce( $list, new ArrayIterator, $recursive )->getArrayCopy(); } return $list; }
11
  public function reduce( DOMNodeList $list, ArrayIterator $reduced, $recursive ) { foreach( $list as $node ){ if( $node instanceof DOMElement ){ $matched = false; foreach( $this->attr as $name => $value ){ if( ! $node->hasAttribute($name) ){ $matched = false; break; } $values = array_flip( explode(' ', $node->getAttribute($name) ) ); if( ! isset($values[$value]) ){ $matched = false; break; } $matched = true; } if( $matched ){ $reduced[] = $node; } if( $recursive && $node->hasChildNodes() ){ $this->reduce( $node->childNodes, $reduced, true ); } } } return $reduced; } }
12
  class LocoDomQuery extends ArrayIterator {
13
  public static function parse( $source ) { $dom = new DOMDocument('1.0', 'UTF-8' ); $dom->preserveWhitespace = true; $dom->formatOutput = false; $source = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body>'.$source.'</body></html>'; $used_errors = libxml_use_internal_errors(true); $opts = LIBXML_HTML_NODEFDTD; $parsed = $dom->loadHTML( $source, $opts ); $errors = libxml_get_errors(); $used_errors || libxml_use_internal_errors(false); libxml_clear_errors(); if( $errors || ! $parsed ){ $e = new Loco_error_ParseException('Unknown parse error'); foreach( $errors as $error ){ $e = new Loco_error_ParseException( trim($error->message) ); $e->setContext( $error->line, $error->column, $source ); if( LIBXML_ERR_FATAL === $error->level ){ throw $e; } } if( ! $parsed ){ throw $e; } } return $dom; }
14
+ public function __construct( $value ){ if( $value instanceof DOMDocument ){ $value = [ $value->documentElement ]; } else if( $value instanceof DOMNode ){ $value = [ $value ]; } if( is_iterable($value) ){ $nodes = []; foreach( $value as $node ){ $nodes[] = $node; } } else if( is_string($value) || method_exists($value,'__toString') ){ $value = self::parse( $value ); $nodes = [ $value->documentElement ]; } else { $type = is_object($value) ? get_class($value) : gettype($value); throw new InvalidArgumentException('Cannot construct DOM from '.$type ); } parent::__construct( $nodes ); }
15
+ public function eq( $index ) { $q = new LocoDomQuery([]); if( $el = $this[$index] ){ $q[] = $el; } return $q; }
16
+ public function find( $value ) { $q = new LocoDomQuery( [] ); $f = new LocoDomQueryFilter($value); foreach( $this as $el ){ foreach( $f->filter($el) as $match ){ $q[] = $match; } } return $q; }
17
+ public function children() { $q = new LocoDomQuery([]); foreach( $this as $el ){ if( $el instanceof DOMNode ){ foreach( $el->childNodes as $child ) { $q[] = $child; } } } return $q; }
18
  public function text(){ $s = ''; foreach( $this as $el ){ $s .= $el->textContent; } return $s; }
19
  public function html() { $s = ''; foreach( $this as $outer ){ foreach( $outer->childNodes as $inner ){ $s .= $inner->ownerDocument->saveXML($inner); } break; } return $s; }
20
  public function attr( $name ) { foreach( $this as $el ){ return $el->getAttribute($name); } return null; }
21
  public function getFormData() { parse_str( $this->serializeForm(), $data ); return $data; }
22
+ public function serializeForm() { $pairs = []; foreach( ['input','select','textarea','button'] as $type ){ foreach( $this->find($type) as $field ){ $name = $field->getAttribute('name'); if( ! $name ){ continue; } if( $field->hasAttribute('type') ){ $type = $field->getAttribute('type'); } if( 'select' === $type ){ $value = null; $f = new LocoDomQueryFilter('option'); foreach( $f->filter($field) as $option ){ if( $option->hasAttribute('value') ){ $_value = $option->getAttribute('value'); } else { $_value = $option->nodeValue; } if( $option->hasAttribute('selected') ){ $value = $_value; break; } else if( is_null($value) ){ $value = $_value; } } if( is_null($value) ){ $value = ''; } } else if( 'checkbox' === $type || 'radio' === $type ){ if( $field->hasAttribute('checked') ){ $value = $field->getAttribute('value'); } else { continue; } } else if( 'file' === $type ){ $value = ''; } else if( $field->hasAttribute('value') ){ $value = $field->getAttribute('value'); } else { $value = $field->textContent; } $pairs[] = sprintf('%s=%s', rawurlencode($name), rawurlencode($value) ); } } return implode('&',$pairs); } }
lib/data/gp.php CHANGED
@@ -2,4 +2,4 @@
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
- return array('version'=>'3.0.0-alpha.2','aliases'=>array('arg'=>'an','bg-bg'=>'bg','bn-bd'=>'bn','bre'=>'br','bs-ba'=>'bs','cs-cz'=>'cs','da-dk'=>'da','de-de'=>'de','ewe'=>'ee','en-us'=>'en','es-es'=>'es','fa-ir'=>'fa','fr-fr'=>'fr','gl-es'=>'gl','haw-us'=>'haw','he-il'=>'he','hi-in'=>'hi','hu-hu'=>'hu','id-id'=>'id','is-is'=>'is','it-it'=>'it','jv-id'=>'jv','ka-ge'=>'ka','ko-kr'=>'ko','lb-lu'=>'lb','lt-lt'=>'lt','me-me'=>'me','mg-mg'=>'mg','mk-mk'=>'mk','ml-in'=>'ml','ms-my'=>'ms','my-mm'=>'mya','ne-np'=>'ne','nb-no'=>'nb','nl-nl'=>'nl','nn-no'=>'nn','pa-in'=>'pa','art-xpirate'=>'pirate','pl-pl'=>'pl','pt-pt'=>'pt','pt-pt-ao90'=>'pt-ao90','ro-ro'=>'ro','ru-ru'=>'ru','si-lk'=>'si','sk-sk'=>'sk','sl-si'=>'sl','so-so'=>'so','sr-rs'=>'sr','su-id'=>'su','sv-se'=>'sv','ta-in'=>'ta','tr-tr'=>'tr','tt-ru'=>'tt','ug-cn'=>'ug','uz-uz'=>'uz'));
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
+ return ['version'=>'3.0.0-alpha.2','aliases'=>['arg'=>'an','bg-bg'=>'bg','bn-bd'=>'bn','bre'=>'br','bs-ba'=>'bs','cs-cz'=>'cs','da-dk'=>'da','de-de'=>'de','ewe'=>'ee','en-us'=>'en','es-es'=>'es','fa-ir'=>'fa','fr-fr'=>'fr','gl-es'=>'gl','haw-us'=>'haw','he-il'=>'he','hi-in'=>'hi','hu-hu'=>'hu','id-id'=>'id','is-is'=>'is','it-it'=>'it','jv-id'=>'jv','ka-ge'=>'ka','ko-kr'=>'ko','lb-lu'=>'lb','lt-lt'=>'lt','me-me'=>'me','mg-mg'=>'mg','mk-mk'=>'mk','ml-in'=>'ml','ms-my'=>'ms','my-mm'=>'mya','ne-np'=>'ne','nb-no'=>'nb','nl-nl'=>'nl','nn-no'=>'nn','pa-in'=>'pa','art-xpirate'=>'pirate','pl-pl'=>'pl','pt-pt'=>'pt','pt-pt-ao90'=>'pt-ao90','ro-ro'=>'ro','ru-ru'=>'ru','si-lk'=>'si','sk-sk'=>'sk','sl-si'=>'sl','so-so'=>'so','sr-rs'=>'sr','su-id'=>'su','sv-se'=>'sv','ta-in'=>'ta','tr-tr'=>'tr','tt-ru'=>'tt','ug-cn'=>'ug','uz-uz'=>'uz']];
lib/data/languages.php CHANGED
@@ -2,4 +2,4 @@
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
- return array('aa'=>'Afar','ab'=>'Abkhazian','ae'=>'Avestan','af'=>'Afrikaans','ak'=>'Akan','am'=>'Amharic','an'=>'Aragonese','ar'=>'Arabic','arq'=>'Algerian Arabic','ary'=>'Moroccan Arabic','as'=>'Assamese','ast'=>'Asturian','av'=>'Avaric','ay'=>'Aymara','az'=>'Azerbaijani','azb'=>'South Azerbaijani','ba'=>'Bashkir','bal'=>'Baluchi','bcc'=>'Southern Balochi','be'=>'Belarusian','bg'=>'Bulgarian','bho'=>'Bhojpuri','bi'=>'Bislama','bm'=>'Bambara','bn'=>'Bengali','bo'=>'Tibetan','br'=>'Breton','brx'=>'Bodo (India)','bs'=>'Bosnian','ca'=>'Catalan','ce'=>'Chechen','ceb'=>'Cebuano','ch'=>'Chamorro','ckb'=>'Central Kurdish','co'=>'Corsican','cr'=>'Cree','cs'=>'Czech','cu'=>'Church Slavic','cv'=>'Chuvash','cy'=>'Welsh','da'=>'Danish','de'=>'German','dsb'=>'Lower Sorbian','dv'=>'Dhivehi','dz'=>'Dzongkha','ee'=>'Ewe','el'=>'Greek','en'=>'English','eo'=>'Esperanto','es'=>'Spanish','et'=>'Estonian','eu'=>'Basque','fa'=>'Persian','ff'=>'Fulah','fi'=>'Finnish','fj'=>'Fijian','fo'=>'Faroese','fon'=>'Fon','fr'=>'French','frp'=>'Arpitan','fuc'=>'Pulaar','fur'=>'Friulian','fy'=>'Western Frisian','ga'=>'Irish','gax'=>'Borana-Arsi-Guji Oromo','gd'=>'Scottish Gaelic','gl'=>'Galician','gn'=>'Guarani','gu'=>'Gujarati','gv'=>'Manx','ha'=>'Hausa','haw'=>'Hawaiian','haz'=>'Hazaragi','he'=>'Hebrew','hi'=>'Hindi','ho'=>'Hiri Motu','hr'=>'Croatian','hsb'=>'Upper Sorbian','ht'=>'Haitian','hu'=>'Hungarian','hy'=>'Armenian','hz'=>'Herero','ia'=>'Interlingua','id'=>'Indonesian','ie'=>'Interlingue','ig'=>'Igbo','ii'=>'Sichuan Yi','ik'=>'Inupiaq','io'=>'Ido','is'=>'Icelandic','it'=>'Italian','iu'=>'Inuktitut','ja'=>'Japanese','jv'=>'Javanese','ka'=>'Georgian','kaa'=>'Kara-Kalpak','kab'=>'Kabyle','kg'=>'Kongo','ki'=>'Kikuyu','kj'=>'Kuanyama','kk'=>'Kazakh','kl'=>'Kalaallisut','km'=>'Central Khmer','kmr'=>'Northern Kurdish','kn'=>'Kannada','ko'=>'Korean','kr'=>'Kanuri','ks'=>'Kashmiri','ku'=>'Kurdish','kv'=>'Komi','kw'=>'Cornish','ky'=>'Kirghiz','la'=>'Latin','lb'=>'Luxembourgish','lg'=>'Ganda','li'=>'Limburgan','lij'=>'Ligurian','lmo'=>'Lombard','ln'=>'Lingala','lo'=>'Lao','lt'=>'Lithuanian','lu'=>'Luba-Katanga','lv'=>'Latvian','mai'=>'Maithili','mfe'=>'Morisyen','mg'=>'Malagasy','mh'=>'Marshallese','mi'=>'Maori','mk'=>'Macedonian','ml'=>'Malayalam','mn'=>'Mongolian','mr'=>'Marathi','ms'=>'Malay','mt'=>'Maltese','my'=>'Burmese','na'=>'Nauru','nb'=>'Norwegian Bokmål','nd'=>'North Ndebele','ne'=>'Nepali','ng'=>'Ndonga','nl'=>'Dutch','nn'=>'Norwegian Nynorsk','no'=>'Norwegian','nqo'=>'N\'Ko','nr'=>'South Ndebele','nv'=>'Navajo','ny'=>'Nyanja','oc'=>'Occitan (post 1500)','oj'=>'Ojibwa','om'=>'Oromo','or'=>'Oriya','ory'=>'Oriya (individual language)','os'=>'Ossetian','pa'=>'Panjabi','pap'=>'Papiamento','pcd'=>'Picard','pcm'=>'Nigerian Pidgin','pi'=>'Pali','pl'=>'Polish','ps'=>'Pushto','pt'=>'Portuguese','qu'=>'Quechua','rhg'=>'Rohingya','rm'=>'Romansh','rn'=>'Rundi','ro'=>'Romanian','ru'=>'Russian','rw'=>'Kinyarwanda','sa'=>'Sanskrit','sah'=>'Yakut','sc'=>'Sardinian','scn'=>'Sicilian','sd'=>'Sindhi','se'=>'Northern Sami','sg'=>'Sango','sh'=>'Serbo-Croatian','si'=>'Sinhala','sk'=>'Slovak','skr'=>'Saraiki','sl'=>'Slovenian','sm'=>'Samoan','sn'=>'Shona','so'=>'Somali','sq'=>'Albanian','sr'=>'Serbian','ss'=>'Swati','st'=>'Southern Sotho','su'=>'Sundanese','sv'=>'Swedish','sw'=>'Swahili','syr'=>'Syriac','szl'=>'Silesian','ta'=>'Tamil','te'=>'Telugu','tg'=>'Tajik','th'=>'Thai','ti'=>'Tigrinya','tk'=>'Turkmen','tl'=>'Tagalog','tn'=>'Tswana','to'=>'Tonga (Tonga Islands)','tr'=>'Turkish','ts'=>'Tsonga','tt'=>'Tatar','tw'=>'Twi','twd'=>'Twents','ty'=>'Tahitian','tzm'=>'Central Atlas Tamazight','ug'=>'Uighur','uk'=>'Ukrainian','ur'=>'Urdu','uz'=>'Uzbek','ve'=>'Venda','vec'=>'Venetian','vi'=>'Vietnamese','vo'=>'Volapük','wa'=>'Walloon','wo'=>'Wolof','xh'=>'Xhosa','yi'=>'Yiddish','yo'=>'Yoruba','za'=>'Zhuang','zgh'=>'Standard Moroccan Tamazight','zh'=>'Chinese','zu'=>'Zulu','tlh'=>'Klingon');
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
+ return ['aa'=>'Afar','ab'=>'Abkhazian','ae'=>'Avestan','af'=>'Afrikaans','ak'=>'Akan','am'=>'Amharic','an'=>'Aragonese','ar'=>'Arabic','arq'=>'Algerian Arabic','ary'=>'Moroccan Arabic','as'=>'Assamese','ast'=>'Asturian','av'=>'Avaric','ay'=>'Aymara','az'=>'Azerbaijani','azb'=>'South Azerbaijani','ba'=>'Bashkir','bal'=>'Baluchi','bcc'=>'Southern Balochi','be'=>'Belarusian','bg'=>'Bulgarian','bho'=>'Bhojpuri','bi'=>'Bislama','bm'=>'Bambara','bn'=>'Bengali','bo'=>'Tibetan','br'=>'Breton','brx'=>'Bodo (India)','bs'=>'Bosnian','ca'=>'Catalan','ce'=>'Chechen','ceb'=>'Cebuano','ch'=>'Chamorro','ckb'=>'Central Kurdish','co'=>'Corsican','cr'=>'Cree','cs'=>'Czech','cu'=>'Church Slavic','cv'=>'Chuvash','cy'=>'Welsh','da'=>'Danish','de'=>'German','dsb'=>'Lower Sorbian','dv'=>'Dhivehi','dz'=>'Dzongkha','ee'=>'Ewe','el'=>'Greek','en'=>'English','eo'=>'Esperanto','es'=>'Spanish','et'=>'Estonian','eu'=>'Basque','fa'=>'Persian','ff'=>'Fulah','fi'=>'Finnish','fj'=>'Fijian','fo'=>'Faroese','fon'=>'Fon','fr'=>'French','frp'=>'Arpitan','fuc'=>'Pulaar','fur'=>'Friulian','fy'=>'Western Frisian','ga'=>'Irish','gax'=>'Borana-Arsi-Guji Oromo','gd'=>'Scottish Gaelic','gl'=>'Galician','gn'=>'Guarani','gu'=>'Gujarati','gv'=>'Manx','ha'=>'Hausa','haw'=>'Hawaiian','haz'=>'Hazaragi','he'=>'Hebrew','hi'=>'Hindi','ho'=>'Hiri Motu','hr'=>'Croatian','hsb'=>'Upper Sorbian','ht'=>'Haitian','hu'=>'Hungarian','hy'=>'Armenian','hz'=>'Herero','ia'=>'Interlingua','id'=>'Indonesian','ie'=>'Interlingue','ig'=>'Igbo','ii'=>'Sichuan Yi','ik'=>'Inupiaq','io'=>'Ido','is'=>'Icelandic','it'=>'Italian','iu'=>'Inuktitut','ja'=>'Japanese','jv'=>'Javanese','ka'=>'Georgian','kaa'=>'Kara-Kalpak','kab'=>'Kabyle','kg'=>'Kongo','ki'=>'Kikuyu','kj'=>'Kuanyama','kk'=>'Kazakh','kl'=>'Kalaallisut','km'=>'Central Khmer','kmr'=>'Northern Kurdish','kn'=>'Kannada','ko'=>'Korean','kr'=>'Kanuri','ks'=>'Kashmiri','ku'=>'Kurdish','kv'=>'Komi','kw'=>'Cornish','ky'=>'Kirghiz','la'=>'Latin','lb'=>'Luxembourgish','lg'=>'Ganda','li'=>'Limburgan','lij'=>'Ligurian','lmo'=>'Lombard','ln'=>'Lingala','lo'=>'Lao','lt'=>'Lithuanian','lu'=>'Luba-Katanga','lv'=>'Latvian','mai'=>'Maithili','mfe'=>'Morisyen','mg'=>'Malagasy','mh'=>'Marshallese','mi'=>'Maori','mk'=>'Macedonian','ml'=>'Malayalam','mn'=>'Mongolian','mr'=>'Marathi','ms'=>'Malay','mt'=>'Maltese','my'=>'Burmese','na'=>'Nauru','nb'=>'Norwegian Bokmål','nd'=>'North Ndebele','ne'=>'Nepali','ng'=>'Ndonga','nl'=>'Dutch','nn'=>'Norwegian Nynorsk','no'=>'Norwegian','nqo'=>'N\'Ko','nr'=>'South Ndebele','nv'=>'Navajo','ny'=>'Nyanja','oc'=>'Occitan (post 1500)','oj'=>'Ojibwa','om'=>'Oromo','or'=>'Oriya','ory'=>'Oriya (individual language)','os'=>'Ossetian','pa'=>'Panjabi','pap'=>'Papiamento','pcd'=>'Picard','pcm'=>'Nigerian Pidgin','pi'=>'Pali','pl'=>'Polish','ps'=>'Pushto','pt'=>'Portuguese','qu'=>'Quechua','rhg'=>'Rohingya','rm'=>'Romansh','rn'=>'Rundi','ro'=>'Romanian','ru'=>'Russian','rw'=>'Kinyarwanda','sa'=>'Sanskrit','sah'=>'Yakut','sc'=>'Sardinian','scn'=>'Sicilian','sd'=>'Sindhi','se'=>'Northern Sami','sg'=>'Sango','sh'=>'Serbo-Croatian','si'=>'Sinhala','sk'=>'Slovak','skr'=>'Saraiki','sl'=>'Slovenian','sm'=>'Samoan','sn'=>'Shona','so'=>'Somali','sq'=>'Albanian','sr'=>'Serbian','ss'=>'Swati','st'=>'Southern Sotho','su'=>'Sundanese','sv'=>'Swedish','sw'=>'Swahili','syr'=>'Syriac','szl'=>'Silesian','ta'=>'Tamil','te'=>'Telugu','tg'=>'Tajik','th'=>'Thai','ti'=>'Tigrinya','tk'=>'Turkmen','tl'=>'Tagalog','tn'=>'Tswana','to'=>'Tonga (Tonga Islands)','tr'=>'Turkish','ts'=>'Tsonga','tt'=>'Tatar','tw'=>'Twi','twd'=>'Twents','ty'=>'Tahitian','tzm'=>'Central Atlas Tamazight','ug'=>'Uighur','uk'=>'Ukrainian','ur'=>'Urdu','uz'=>'Uzbek','ve'=>'Venda','vec'=>'Venetian','vi'=>'Vietnamese','vo'=>'Volapük','wa'=>'Walloon','wo'=>'Wolof','xh'=>'Xhosa','yi'=>'Yiddish','yo'=>'Yoruba','za'=>'Zhuang','zgh'=>'Standard Moroccan Tamazight','zh'=>'Chinese','zu'=>'Zulu','tlh'=>'Klingon'];
lib/data/locales.php CHANGED
@@ -2,4 +2,4 @@
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
- return array('af'=>array(0=>'Afrikaans',1=>'Afrikaans'),'am'=>array(0=>'Amharic',1=>'አማርኛ'),'ar'=>array(0=>'Arabic',1=>'العربية'),'ary'=>array(0=>'Moroccan Arabic',1=>'العربية المغربية'),'as'=>array(0=>'Assamese',1=>'অসমীয়া'),'az'=>array(0=>'Azerbaijani',1=>'Azərbaycan dili'),'azb'=>array(0=>'South Azerbaijani',1=>'گؤنئی آذربایجان'),'bel'=>array(0=>'Belarusian',1=>'Беларуская мова'),'bg_BG'=>array(0=>'Bulgarian',1=>'Български'),'bn_BD'=>array(0=>'Bengali (Bangladesh)',1=>'বাংলা'),'bo'=>array(0=>'Tibetan',1=>'བོད་ཡིག'),'bs_BA'=>array(0=>'Bosnian',1=>'Bosanski'),'ca'=>array(0=>'Catalan',1=>'Català'),'ceb'=>array(0=>'Cebuano',1=>'Cebuano'),'cs_CZ'=>array(0=>'Czech',1=>'Čeština'),'cy'=>array(0=>'Welsh',1=>'Cymraeg'),'da_DK'=>array(0=>'Danish',1=>'Dansk'),'de_CH_informal'=>array(0=>'German (Switzerland, Informal)',1=>'Deutsch (Schweiz, Du)'),'de_CH'=>array(0=>'German (Switzerland)',1=>'Deutsch (Schweiz)'),'de_DE'=>array(0=>'German',1=>'Deutsch'),'de_DE_formal'=>array(0=>'German (Formal)',1=>'Deutsch (Sie)'),'de_AT'=>array(0=>'German (Austria)',1=>'Deutsch (Österreich)'),'dsb'=>array(0=>'Lower Sorbian',1=>'Dolnoserbšćina'),'dzo'=>array(0=>'Dzongkha',1=>'རྫོང་ཁ'),'el'=>array(0=>'Greek',1=>'Ελληνικά'),'en_GB'=>array(0=>'English (UK)',1=>'English (UK)'),'en_AU'=>array(0=>'English (Australia)',1=>'English (Australia)'),'en_ZA'=>array(0=>'English (South Africa)',1=>'English (South Africa)'),'en_NZ'=>array(0=>'English (New Zealand)',1=>'English (New Zealand)'),'en_CA'=>array(0=>'English (Canada)',1=>'English (Canada)'),'eo'=>array(0=>'Esperanto',1=>'Esperanto'),'es_ES'=>array(0=>'Spanish (Spain)',1=>'Español'),'es_EC'=>array(0=>'Spanish (Ecuador)',1=>'Español de Ecuador'),'es_CO'=>array(0=>'Spanish (Colombia)',1=>'Español de Colombia'),'es_AR'=>array(0=>'Spanish (Argentina)',1=>'Español de Argentina'),'es_VE'=>array(0=>'Spanish (Venezuela)',1=>'Español de Venezuela'),'es_DO'=>array(0=>'Spanish (Dominican Republic)',1=>'Español de República Dominicana'),'es_CR'=>array(0=>'Spanish (Costa Rica)',1=>'Español de Costa Rica'),'es_PE'=>array(0=>'Spanish (Peru)',1=>'Español de Perú'),'es_CL'=>array(0=>'Spanish (Chile)',1=>'Español de Chile'),'es_UY'=>array(0=>'Spanish (Uruguay)',1=>'Español de Uruguay'),'es_PR'=>array(0=>'Spanish (Puerto Rico)',1=>'Español de Puerto Rico'),'es_GT'=>array(0=>'Spanish (Guatemala)',1=>'Español de Guatemala'),'es_MX'=>array(0=>'Spanish (Mexico)',1=>'Español de México'),'et'=>array(0=>'Estonian',1=>'Eesti'),'eu'=>array(0=>'Basque',1=>'Euskara'),'fa_IR'=>array(0=>'Persian',1=>'فارسی'),'fa_AF'=>array(0=>'Persian (Afghanistan)',1=>'(فارسی (افغانستان'),'fi'=>array(0=>'Finnish',1=>'Suomi'),'fr_CA'=>array(0=>'French (Canada)',1=>'Français du Canada'),'fr_BE'=>array(0=>'French (Belgium)',1=>'Français de Belgique'),'fr_FR'=>array(0=>'French (France)',1=>'Français'),'fur'=>array(0=>'Friulian',1=>'Friulian'),'gd'=>array(0=>'Scottish Gaelic',1=>'Gàidhlig'),'gl_ES'=>array(0=>'Galician',1=>'Galego'),'gu'=>array(0=>'Gujarati',1=>'ગુજરાતી'),'haz'=>array(0=>'Hazaragi',1=>'هزاره گی'),'he_IL'=>array(0=>'Hebrew',1=>'עִבְרִית'),'hi_IN'=>array(0=>'Hindi',1=>'हिन्दी'),'hr'=>array(0=>'Croatian',1=>'Hrvatski'),'hsb'=>array(0=>'Upper Sorbian',1=>'Hornjoserbšćina'),'hu_HU'=>array(0=>'Hungarian',1=>'Magyar'),'hy'=>array(0=>'Armenian',1=>'Հայերեն'),'id_ID'=>array(0=>'Indonesian',1=>'Bahasa Indonesia'),'is_IS'=>array(0=>'Icelandic',1=>'Íslenska'),'it_IT'=>array(0=>'Italian',1=>'Italiano'),'ja'=>array(0=>'Japanese',1=>'日本語'),'jv_ID'=>array(0=>'Javanese',1=>'Basa Jawa'),'ka_GE'=>array(0=>'Georgian',1=>'ქართული'),'kab'=>array(0=>'Kabyle',1=>'Taqbaylit'),'kk'=>array(0=>'Kazakh',1=>'Қазақ тілі'),'km'=>array(0=>'Khmer',1=>'ភាសាខ្មែរ'),'kn'=>array(0=>'Kannada',1=>'ಕನ್ನಡ'),'ko_KR'=>array(0=>'Korean',1=>'한국어'),'ckb'=>array(0=>'Kurdish (Sorani)',1=>'كوردی‎'),'lo'=>array(0=>'Lao',1=>'ພາສາລາວ'),'lt_LT'=>array(0=>'Lithuanian',1=>'Lietuvių kalba'),'lv'=>array(0=>'Latvian',1=>'Latviešu valoda'),'mk_MK'=>array(0=>'Macedonian',1=>'Македонски јазик'),'ml_IN'=>array(0=>'Malayalam',1=>'മലയാളം'),'mn'=>array(0=>'Mongolian',1=>'Монгол'),'mr'=>array(0=>'Marathi',1=>'मराठी'),'ms_MY'=>array(0=>'Malay',1=>'Bahasa Melayu'),'my_MM'=>array(0=>'Myanmar (Burmese)',1=>'ဗမာစာ'),'nb_NO'=>array(0=>'Norwegian (Bokmål)',1=>'Norsk bokmål'),'ne_NP'=>array(0=>'Nepali',1=>'नेपाली'),'nl_BE'=>array(0=>'Dutch (Belgium)',1=>'Nederlands (België)'),'nl_NL'=>array(0=>'Dutch',1=>'Nederlands'),'nl_NL_formal'=>array(0=>'Dutch (Formal)',1=>'Nederlands (Formeel)'),'nn_NO'=>array(0=>'Norwegian (Nynorsk)',1=>'Norsk nynorsk'),'oci'=>array(0=>'Occitan',1=>'Occitan'),'pa_IN'=>array(0=>'Punjabi',1=>'ਪੰਜਾਬੀ'),'pl_PL'=>array(0=>'Polish',1=>'Polski'),'ps'=>array(0=>'Pashto',1=>'پښتو'),'pt_BR'=>array(0=>'Portuguese (Brazil)',1=>'Português do Brasil'),'pt_PT'=>array(0=>'Portuguese (Portugal)',1=>'Português'),'pt_AO'=>array(0=>'Portuguese (Angola)',1=>'Português de Angola'),'pt_PT_ao90'=>array(0=>'Portuguese (Portugal, AO90)',1=>'Português (AO90)'),'rhg'=>array(0=>'Rohingya',1=>'Ruáinga'),'ro_RO'=>array(0=>'Romanian',1=>'Română'),'ru_RU'=>array(0=>'Russian',1=>'Русский'),'sah'=>array(0=>'Sakha',1=>'Сахалыы'),'snd'=>array(0=>'Sindhi',1=>'سنڌي'),'si_LK'=>array(0=>'Sinhala',1=>'සිංහල'),'sk_SK'=>array(0=>'Slovak',1=>'Slovenčina'),'skr'=>array(0=>'Saraiki',1=>'سرائیکی'),'sl_SI'=>array(0=>'Slovenian',1=>'Slovenščina'),'sq'=>array(0=>'Albanian',1=>'Shqip'),'sr_RS'=>array(0=>'Serbian',1=>'Српски језик'),'sv_SE'=>array(0=>'Swedish',1=>'Svenska'),'sw'=>array(0=>'Swahili',1=>'Kiswahili'),'szl'=>array(0=>'Silesian',1=>'Ślōnskŏ gŏdka'),'ta_IN'=>array(0=>'Tamil',1=>'தமிழ்'),'ta_LK'=>array(0=>'Tamil (Sri Lanka)',1=>'தமிழ்'),'te'=>array(0=>'Telugu',1=>'తెలుగు'),'th'=>array(0=>'Thai',1=>'ไทย'),'tl'=>array(0=>'Tagalog',1=>'Tagalog'),'tr_TR'=>array(0=>'Turkish',1=>'Türkçe'),'tt_RU'=>array(0=>'Tatar',1=>'Татар теле'),'tah'=>array(0=>'Tahitian',1=>'Reo Tahiti'),'ug_CN'=>array(0=>'Uighur',1=>'ئۇيغۇرچە'),'uk'=>array(0=>'Ukrainian',1=>'Українська'),'ur'=>array(0=>'Urdu',1=>'اردو'),'uz_UZ'=>array(0=>'Uzbek',1=>'O‘zbekcha'),'vi'=>array(0=>'Vietnamese',1=>'Tiếng Việt'),'zh_TW'=>array(0=>'Chinese (Taiwan)',1=>'繁體中文'),'zh_HK'=>array(0=>'Chinese (Hong Kong)',1=>'香港中文版 '),'zh_CN'=>array(0=>'Chinese (China)',1=>'简体中文'));
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
+ return ['af'=>[0=>'Afrikaans',1=>'Afrikaans'],'am'=>[0=>'Amharic',1=>'አማርኛ'],'ar'=>[0=>'Arabic',1=>'العربية'],'ary'=>[0=>'Moroccan Arabic',1=>'العربية المغربية'],'as'=>[0=>'Assamese',1=>'অসমীয়া'],'azb'=>[0=>'South Azerbaijani',1=>'گؤنئی آذربایجان'],'az'=>[0=>'Azerbaijani',1=>'Azərbaycan dili'],'bel'=>[0=>'Belarusian',1=>'Беларуская мова'],'bg_BG'=>[0=>'Bulgarian',1=>'Български'],'bn_BD'=>[0=>'Bengali (Bangladesh)',1=>'বাংলা'],'bo'=>[0=>'Tibetan',1=>'བོད་ཡིག'],'bs_BA'=>[0=>'Bosnian',1=>'Bosanski'],'ca'=>[0=>'Catalan',1=>'Català'],'ceb'=>[0=>'Cebuano',1=>'Cebuano'],'cs_CZ'=>[0=>'Czech',1=>'Čeština'],'cy'=>[0=>'Welsh',1=>'Cymraeg'],'da_DK'=>[0=>'Danish',1=>'Dansk'],'de_DE'=>[0=>'German',1=>'Deutsch'],'de_CH'=>[0=>'German (Switzerland)',1=>'Deutsch (Schweiz)'],'de_CH_informal'=>[0=>'German (Switzerland, Informal)',1=>'Deutsch (Schweiz, Du)'],'de_AT'=>[0=>'German (Austria)',1=>'Deutsch (Österreich)'],'de_DE_formal'=>[0=>'German (Formal)',1=>'Deutsch (Sie)'],'dsb'=>[0=>'Lower Sorbian',1=>'Dolnoserbšćina'],'dzo'=>[0=>'Dzongkha',1=>'རྫོང་ཁ'],'el'=>[0=>'Greek',1=>'Ελληνικά'],'en_CA'=>[0=>'English (Canada)',1=>'English (Canada)'],'en_NZ'=>[0=>'English (New Zealand)',1=>'English (New Zealand)'],'en_ZA'=>[0=>'English (South Africa)',1=>'English (South Africa)'],'en_GB'=>[0=>'English (UK)',1=>'English (UK)'],'en_AU'=>[0=>'English (Australia)',1=>'English (Australia)'],'eo'=>[0=>'Esperanto',1=>'Esperanto'],'es_MX'=>[0=>'Spanish (Mexico)',1=>'Español de México'],'es_CO'=>[0=>'Spanish (Colombia)',1=>'Español de Colombia'],'es_ES'=>[0=>'Spanish (Spain)',1=>'Español'],'es_VE'=>[0=>'Spanish (Venezuela)',1=>'Español de Venezuela'],'es_PE'=>[0=>'Spanish (Peru)',1=>'Español de Perú'],'es_DO'=>[0=>'Spanish (Dominican Republic)',1=>'Español de República Dominicana'],'es_CR'=>[0=>'Spanish (Costa Rica)',1=>'Español de Costa Rica'],'es_UY'=>[0=>'Spanish (Uruguay)',1=>'Español de Uruguay'],'es_CL'=>[0=>'Spanish (Chile)',1=>'Español de Chile'],'es_PR'=>[0=>'Spanish (Puerto Rico)',1=>'Español de Puerto Rico'],'es_GT'=>[0=>'Spanish (Guatemala)',1=>'Español de Guatemala'],'es_AR'=>[0=>'Spanish (Argentina)',1=>'Español de Argentina'],'es_EC'=>[0=>'Spanish (Ecuador)',1=>'Español de Ecuador'],'et'=>[0=>'Estonian',1=>'Eesti'],'eu'=>[0=>'Basque',1=>'Euskara'],'fa_IR'=>[0=>'Persian',1=>'فارسی'],'fa_AF'=>[0=>'Persian (Afghanistan)',1=>'(فارسی (افغانستان'],'fi'=>[0=>'Finnish',1=>'Suomi'],'fr_CA'=>[0=>'French (Canada)',1=>'Français du Canada'],'fr_BE'=>[0=>'French (Belgium)',1=>'Français de Belgique'],'fr_FR'=>[0=>'French (France)',1=>'Français'],'fur'=>[0=>'Friulian',1=>'Friulian'],'gd'=>[0=>'Scottish Gaelic',1=>'Gàidhlig'],'gl_ES'=>[0=>'Galician',1=>'Galego'],'gu'=>[0=>'Gujarati',1=>'ગુજરાતી'],'haz'=>[0=>'Hazaragi',1=>'هزاره گی'],'he_IL'=>[0=>'Hebrew',1=>'עִבְרִית'],'hi_IN'=>[0=>'Hindi',1=>'हिन्दी'],'hr'=>[0=>'Croatian',1=>'Hrvatski'],'hsb'=>[0=>'Upper Sorbian',1=>'Hornjoserbšćina'],'hu_HU'=>[0=>'Hungarian',1=>'Magyar'],'hy'=>[0=>'Armenian',1=>'Հայերեն'],'id_ID'=>[0=>'Indonesian',1=>'Bahasa Indonesia'],'is_IS'=>[0=>'Icelandic',1=>'Íslenska'],'it_IT'=>[0=>'Italian',1=>'Italiano'],'ja'=>[0=>'Japanese',1=>'日本語'],'jv_ID'=>[0=>'Javanese',1=>'Basa Jawa'],'ka_GE'=>[0=>'Georgian',1=>'ქართული'],'kab'=>[0=>'Kabyle',1=>'Taqbaylit'],'kk'=>[0=>'Kazakh',1=>'Қазақ тілі'],'km'=>[0=>'Khmer',1=>'ភាសាខ្មែរ'],'kn'=>[0=>'Kannada',1=>'ಕನ್ನಡ'],'ko_KR'=>[0=>'Korean',1=>'한국어'],'ckb'=>[0=>'Kurdish (Sorani)',1=>'كوردی‎'],'lo'=>[0=>'Lao',1=>'ພາສາລາວ'],'lt_LT'=>[0=>'Lithuanian',1=>'Lietuvių kalba'],'lv'=>[0=>'Latvian',1=>'Latviešu valoda'],'mk_MK'=>[0=>'Macedonian',1=>'Македонски јазик'],'ml_IN'=>[0=>'Malayalam',1=>'മലയാളം'],'mn'=>[0=>'Mongolian',1=>'Монгол'],'mr'=>[0=>'Marathi',1=>'मराठी'],'ms_MY'=>[0=>'Malay',1=>'Bahasa Melayu'],'my_MM'=>[0=>'Myanmar (Burmese)',1=>'ဗမာစာ'],'nb_NO'=>[0=>'Norwegian (Bokmål)',1=>'Norsk bokmål'],'ne_NP'=>[0=>'Nepali',1=>'नेपाली'],'nl_NL_formal'=>[0=>'Dutch (Formal)',1=>'Nederlands (Formeel)'],'nl_NL'=>[0=>'Dutch',1=>'Nederlands'],'nl_BE'=>[0=>'Dutch (Belgium)',1=>'Nederlands (België)'],'nn_NO'=>[0=>'Norwegian (Nynorsk)',1=>'Norsk nynorsk'],'oci'=>[0=>'Occitan',1=>'Occitan'],'pa_IN'=>[0=>'Punjabi',1=>'ਪੰਜਾਬੀ'],'pl_PL'=>[0=>'Polish',1=>'Polski'],'ps'=>[0=>'Pashto',1=>'پښتو'],'pt_PT'=>[0=>'Portuguese (Portugal)',1=>'Português'],'pt_AO'=>[0=>'Portuguese (Angola)',1=>'Português de Angola'],'pt_PT_ao90'=>[0=>'Portuguese (Portugal, AO90)',1=>'Português (AO90)'],'pt_BR'=>[0=>'Portuguese (Brazil)',1=>'Português do Brasil'],'rhg'=>[0=>'Rohingya',1=>'Ruáinga'],'ro_RO'=>[0=>'Romanian',1=>'Română'],'ru_RU'=>[0=>'Russian',1=>'Русский'],'sah'=>[0=>'Sakha',1=>'Сахалыы'],'snd'=>[0=>'Sindhi',1=>'سنڌي'],'si_LK'=>[0=>'Sinhala',1=>'සිංහල'],'sk_SK'=>[0=>'Slovak',1=>'Slovenčina'],'skr'=>[0=>'Saraiki',1=>'سرائیکی'],'sl_SI'=>[0=>'Slovenian',1=>'Slovenščina'],'sq'=>[0=>'Albanian',1=>'Shqip'],'sr_RS'=>[0=>'Serbian',1=>'Српски језик'],'sv_SE'=>[0=>'Swedish',1=>'Svenska'],'sw'=>[0=>'Swahili',1=>'Kiswahili'],'szl'=>[0=>'Silesian',1=>'Ślōnskŏ gŏdka'],'ta_IN'=>[0=>'Tamil',1=>'தமிழ்'],'ta_LK'=>[0=>'Tamil (Sri Lanka)',1=>'தமிழ்'],'te'=>[0=>'Telugu',1=>'తెలుగు'],'th'=>[0=>'Thai',1=>'ไทย'],'tl'=>[0=>'Tagalog',1=>'Tagalog'],'tr_TR'=>[0=>'Turkish',1=>'Türkçe'],'tt_RU'=>[0=>'Tatar',1=>'Татар теле'],'tah'=>[0=>'Tahitian',1=>'Reo Tahiti'],'ug_CN'=>[0=>'Uighur',1=>'ئۇيغۇرچە'],'uk'=>[0=>'Ukrainian',1=>'Українська'],'ur'=>[0=>'Urdu',1=>'اردو'],'uz_UZ'=>[0=>'Uzbek',1=>'O‘zbekcha'],'vi'=>[0=>'Vietnamese',1=>'Tiếng Việt'],'zh_HK'=>[0=>'Chinese (Hong Kong)',1=>'香港中文版 '],'zh_CN'=>[0=>'Chinese (China)',1=>'简体中文'],'zh_TW'=>[0=>'Chinese (Taiwan)',1=>'繁體中文']];
lib/data/plurals.php CHANGED
@@ -2,4 +2,4 @@
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
- return array('ak'=>1,'am'=>1,'ar'=>2,'ary'=>2,'be'=>3,'bm'=>4,'bo'=>4,'br'=>1,'bs'=>3,'cs'=>5,'cy'=>6,'dz'=>4,'ff'=>1,'fr'=>1,'ga'=>7,'gd'=>8,'gv'=>9,'hr'=>10,'id'=>4,'ii'=>4,'iu'=>11,'ja'=>4,'ka'=>4,'kk'=>4,'km'=>4,'kn'=>4,'ko'=>4,'kw'=>11,'ky'=>4,'ln'=>1,'lo'=>4,'lt'=>12,'lv'=>13,'mg'=>1,'mi'=>1,'mk'=>14,'ms'=>4,'mt'=>15,'my'=>4,'nr'=>4,'oc'=>1,'pl'=>16,'ro'=>17,'ru'=>3,'sa'=>11,'sg'=>4,'sk'=>5,'sl'=>18,'sm'=>4,'sr'=>3,'su'=>4,'th'=>4,'ti'=>1,'tl'=>1,'to'=>4,'tt'=>4,'ug'=>4,'uk'=>3,'vi'=>4,'wa'=>1,'wo'=>4,'yo'=>4,'zh'=>4,''=>array(0=>array(0=>'n != 1',1=>array(0=>'one',1=>'other')),1=>array(0=>'n > 1',1=>array(0=>'one',1=>'other')),2=>array(0=>'n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100 >= 3 && n%100<=10 ? 3 : n%100 >= 11 && n%100<=99 ? 4 : 5',1=>array(0=>'zero',1=>'one',2=>'two',3=>'few',4=>'many',5=>'other')),3=>array(0=>'(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>array(0=>'one',1=>'few',2=>'other')),4=>array(0=>'0',1=>array(0=>'other')),5=>array(0=>'( n == 1 ) ? 0 : ( n >= 2 && n <= 4 ) ? 1 : 2',1=>array(0=>'one',1=>'few',2=>'other')),6=>array(0=>'n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 5',1=>array(0=>'zero',1=>'one',2=>'two',3=>'few',4=>'many',5=>'other')),7=>array(0=>'n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4',1=>array(0=>'one',1=>'two',2=>'few',3=>'many',4=>'other')),8=>array(0=>'n==1||n==11 ? 0 : n==2||n==12 ? 1 :(n >= 3 && n<=10)||(n >= 13 && n<=19)? 2 : 3',1=>array(0=>'one',1=>'two',2=>'few',3=>'other')),9=>array(0=>'n%10==1 ? 0 : n%10==2 ? 1 : n%20==0 ? 2 : 3',1=>array(0=>'one',1=>'two',2=>'few',3=>'other')),10=>array(0=>'n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2',1=>array(0=>'one',1=>'few',2=>'other')),11=>array(0=>'n == 1 ? 0 : n == 2 ? 1 : 2',1=>array(0=>'one',1=>'two',2=>'other')),12=>array(0=>'(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>array(0=>'one',1=>'few',2=>'other')),13=>array(0=>'n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2',1=>array(0=>'one',1=>'other',2=>'zero')),14=>array(0=>'( n % 10 == 1 && n % 100 != 11 ) ? 0 : 1',1=>array(0=>'one',1=>'other')),15=>array(0=>'(n==1 ? 0 : n==0||( n%100>1 && n%100<11)? 1 :(n%100>10 && n%100<20)? 2 : 3)',1=>array(0=>'one',1=>'few',2=>'many',3=>'other')),16=>array(0=>'(n==1 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>array(0=>'one',1=>'few',2=>'other')),17=>array(0=>'(n==1 ? 0 :(((n%100>19)||(( n%100==0)&&(n!=0)))? 2 : 1))',1=>array(0=>'one',1=>'few',2=>'other')),18=>array(0=>'n%100==1 ? 0 : n%100==2 ? 1 : n%100==3||n%100==4 ? 2 : 3',1=>array(0=>'one',1=>'two',2=>'few',3=>'other'))));
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
+ return ['ak'=>1,'am'=>1,'ar'=>2,'ary'=>2,'be'=>3,'bm'=>4,'bo'=>4,'br'=>1,'bs'=>3,'cs'=>5,'cy'=>6,'dz'=>4,'ff'=>1,'fr'=>1,'ga'=>7,'gd'=>8,'gv'=>9,'hr'=>10,'id'=>4,'ii'=>4,'iu'=>11,'ja'=>4,'ka'=>4,'kk'=>4,'km'=>4,'kn'=>4,'ko'=>4,'kw'=>11,'ky'=>4,'ln'=>1,'lo'=>4,'lt'=>12,'lv'=>13,'mg'=>1,'mi'=>1,'mk'=>14,'ms'=>4,'mt'=>15,'my'=>4,'nr'=>4,'oc'=>1,'pl'=>16,'ro'=>17,'ru'=>3,'sa'=>11,'sg'=>4,'sk'=>5,'sl'=>18,'sm'=>4,'sr'=>3,'su'=>4,'th'=>4,'ti'=>1,'tl'=>1,'to'=>4,'tt'=>4,'ug'=>4,'uk'=>3,'vi'=>4,'wa'=>1,'wo'=>4,'yo'=>4,'zh'=>4,''=>[0=>[0=>'n != 1',1=>[0=>'one',1=>'other']],1=>[0=>'n > 1',1=>[0=>'one',1=>'other']],2=>[0=>'n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100 >= 3 && n%100<=10 ? 3 : n%100 >= 11 && n%100<=99 ? 4 : 5',1=>[0=>'zero',1=>'one',2=>'two',3=>'few',4=>'many',5=>'other']],3=>[0=>'(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>[0=>'one',1=>'few',2=>'other']],4=>[0=>'0',1=>[0=>'other']],5=>[0=>'( n == 1 ) ? 0 : ( n >= 2 && n <= 4 ) ? 1 : 2',1=>[0=>'one',1=>'few',2=>'other']],6=>[0=>'n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 5',1=>[0=>'zero',1=>'one',2=>'two',3=>'few',4=>'many',5=>'other']],7=>[0=>'n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4',1=>[0=>'one',1=>'two',2=>'few',3=>'many',4=>'other']],8=>[0=>'n==1||n==11 ? 0 : n==2||n==12 ? 1 :(n >= 3 && n<=10)||(n >= 13 && n<=19)? 2 : 3',1=>[0=>'one',1=>'two',2=>'few',3=>'other']],9=>[0=>'n%10==1 ? 0 : n%10==2 ? 1 : n%20==0 ? 2 : 3',1=>[0=>'one',1=>'two',2=>'few',3=>'other']],10=>[0=>'n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2',1=>[0=>'one',1=>'few',2=>'other']],11=>[0=>'n == 1 ? 0 : n == 2 ? 1 : 2',1=>[0=>'one',1=>'two',2=>'other']],12=>[0=>'(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>[0=>'one',1=>'few',2=>'other']],13=>[0=>'n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2',1=>[0=>'one',1=>'other',2=>'zero']],14=>[0=>'( n % 10 == 1 && n % 100 != 11 ) ? 0 : 1',1=>[0=>'one',1=>'other']],15=>[0=>'(n==1 ? 0 : n==0||( n%100>1 && n%100<11)? 1 :(n%100>10 && n%100<20)? 2 : 3)',1=>[0=>'one',1=>'few',2=>'many',3=>'other']],16=>[0=>'(n==1 ? 0 : n%10 >= 2 && n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)',1=>[0=>'one',1=>'few',2=>'other']],17=>[0=>'(n==1 ? 0 :(((n%100>19)||(( n%100==0)&&(n!=0)))? 2 : 1))',1=>[0=>'one',1=>'few',2=>'other']],18=>[0=>'n%100==1 ? 0 : n%100==2 ? 1 : n%100==3||n%100==4 ? 2 : 3',1=>[0=>'one',1=>'two',2=>'few',3=>'other']]]];
lib/data/regions.php CHANGED
@@ -2,4 +2,4 @@
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
- return array('AD'=>'Andorra','AE'=>'United Arab Emirates','AF'=>'Afghanistan','AG'=>'Antigua and Barbuda','AI'=>'Anguilla','AL'=>'Albania','AM'=>'Armenia','AO'=>'Angola','AQ'=>'Antarctica','AR'=>'Argentina','AS'=>'American Samoa','AT'=>'Austria','AU'=>'Australia','AW'=>'Aruba','AX'=>'Åland Islands','AZ'=>'Azerbaijan','BA'=>'Bosnia and Herzegovina','BB'=>'Barbados','BD'=>'Bangladesh','BE'=>'Belgium','BF'=>'Burkina Faso','BG'=>'Bulgaria','BH'=>'Bahrain','BI'=>'Burundi','BJ'=>'Benin','BL'=>'Saint Barthélemy','BM'=>'Bermuda','BN'=>'Brunei Darussalam','BO'=>'Bolivia','BQ'=>'Bonaire, Sint Eustatius and Saba','BR'=>'Brazil','BS'=>'Bahamas','BT'=>'Bhutan','BV'=>'Bouvet Island','BW'=>'Botswana','BY'=>'Belarus','BZ'=>'Belize','CA'=>'Canada','CC'=>'Cocos (Keeling) Islands','CD'=>'The Democratic Republic of the Congo','CF'=>'Central African Republic','CG'=>'Congo','CH'=>'Switzerland','CI'=>'Côte d\'Ivoire','CK'=>'Cook Islands','CL'=>'Chile','CM'=>'Cameroon','CN'=>'China','CO'=>'Colombia','CR'=>'Costa Rica','CU'=>'Cuba','CV'=>'Cabo Verde; Cape Verde','CW'=>'Curaçao','CX'=>'Christmas Island','CY'=>'Cyprus','CZ'=>'Czech Republic','DE'=>'Germany','DJ'=>'Djibouti','DK'=>'Denmark','DM'=>'Dominica','DO'=>'Dominican Republic','DZ'=>'Algeria','EC'=>'Ecuador','EE'=>'Estonia','EG'=>'Egypt','EH'=>'Western Sahara','ER'=>'Eritrea','ES'=>'Spain','ET'=>'Ethiopia','FI'=>'Finland','FJ'=>'Fiji','FK'=>'Falkland Islands (Malvinas)','FM'=>'Federated States of Micronesia','FO'=>'Faroe Islands','FR'=>'France','GA'=>'Gabon','GB'=>'United Kingdom','GD'=>'Grenada','GE'=>'Georgia','GF'=>'French Guiana','GG'=>'Guernsey','GH'=>'Ghana','GI'=>'Gibraltar','GL'=>'Greenland','GM'=>'Gambia','GN'=>'Guinea','GP'=>'Guadeloupe','GQ'=>'Equatorial Guinea','GR'=>'Greece','GS'=>'South Georgia and the South Sandwich Islands','GT'=>'Guatemala','GU'=>'Guam','GW'=>'Guinea-Bissau','GY'=>'Guyana','HK'=>'Hong Kong','HM'=>'Heard Island and McDonald Islands','HN'=>'Honduras','HR'=>'Croatia','HT'=>'Haiti','HU'=>'Hungary','ID'=>'Indonesia','IE'=>'Ireland','IL'=>'Israel','IM'=>'Isle of Man','IN'=>'India','IO'=>'British Indian Ocean Territory','IQ'=>'Iraq','IR'=>'Islamic Republic of Iran','IS'=>'Iceland','IT'=>'Italy','JE'=>'Jersey','JM'=>'Jamaica','JO'=>'Jordan','JP'=>'Japan','KE'=>'Kenya','KG'=>'Kyrgyzstan','KH'=>'Cambodia','KI'=>'Kiribati','KM'=>'Comoros','KN'=>'Saint Kitts and Nevis','KP'=>'Democratic People\'s Republic of Korea','KR'=>'Republic of Korea','KW'=>'Kuwait','KY'=>'Cayman Islands','KZ'=>'Kazakhstan','LA'=>'Lao People\'s Democratic Republic','LB'=>'Lebanon','LC'=>'Saint Lucia','LI'=>'Liechtenstein','LK'=>'Sri Lanka','LR'=>'Liberia','LS'=>'Lesotho','LT'=>'Lithuania','LU'=>'Luxembourg','LV'=>'Latvia','LY'=>'Libya','MA'=>'Morocco','MC'=>'Monaco','MD'=>'Moldova','ME'=>'Montenegro','MF'=>'Saint Martin (French part)','MG'=>'Madagascar','MH'=>'Marshall Islands','MK'=>'The Former Yugoslav Republic of Macedonia','ML'=>'Mali','MM'=>'Myanmar','MN'=>'Mongolia','MO'=>'Macao','MP'=>'Northern Mariana Islands','MQ'=>'Martinique','MR'=>'Mauritania','MS'=>'Montserrat','MT'=>'Malta','MU'=>'Mauritius','MV'=>'Maldives','MW'=>'Malawi','MX'=>'Mexico','MY'=>'Malaysia','MZ'=>'Mozambique','NA'=>'Namibia','NC'=>'New Caledonia','NE'=>'Niger','NF'=>'Norfolk Island','NG'=>'Nigeria','NI'=>'Nicaragua','NL'=>'Netherlands','NO'=>'Norway','NP'=>'Nepal','NR'=>'Nauru','NU'=>'Niue','NZ'=>'New Zealand','OM'=>'Oman','PA'=>'Panama','PE'=>'Peru','PF'=>'French Polynesia','PG'=>'Papua New Guinea','PH'=>'Philippines','PK'=>'Pakistan','PL'=>'Poland','PM'=>'Saint Pierre and Miquelon','PN'=>'Pitcairn','PR'=>'Puerto Rico','PS'=>'State of Palestine','PT'=>'Portugal','PW'=>'Palau','PY'=>'Paraguay','QA'=>'Qatar','RE'=>'Réunion','RO'=>'Romania','RS'=>'Serbia','RU'=>'Russian Federation','RW'=>'Rwanda','SA'=>'Saudi Arabia','SB'=>'Solomon Islands','SC'=>'Seychelles','SD'=>'Sudan','SE'=>'Sweden','SG'=>'Singapore','SH'=>'Saint Helena, Ascension and Tristan da Cunha','SI'=>'Slovenia','SJ'=>'Svalbard and Jan Mayen','SK'=>'Slovakia','SL'=>'Sierra Leone','SM'=>'San Marino','SN'=>'Senegal','SO'=>'Somalia','SR'=>'Suriname','SS'=>'South Sudan','ST'=>'Sao Tome and Principe','SV'=>'El Salvador','SX'=>'Sint Maarten (Dutch part)','SY'=>'Syrian Arab Republic','SZ'=>'Swaziland','TC'=>'Turks and Caicos Islands','TD'=>'Chad','TF'=>'French Southern Territories','TG'=>'Togo','TH'=>'Thailand','TJ'=>'Tajikistan','TK'=>'Tokelau','TL'=>'Timor-Leste','TM'=>'Turkmenistan','TN'=>'Tunisia','TO'=>'Tonga','TR'=>'Turkey','TT'=>'Trinidad and Tobago','TV'=>'Tuvalu','TW'=>'Taiwan','TZ'=>'United Republic of Tanzania','UA'=>'Ukraine','UG'=>'Uganda','UM'=>'United States Minor Outlying Islands','US'=>'United States','UY'=>'Uruguay','UZ'=>'Uzbekistan','VA'=>'Holy See (Vatican City State)','VC'=>'Saint Vincent and the Grenadines','VE'=>'Venezuela','VG'=>'British Virgin Islands','VI'=>'U.S. Virgin Islands','VN'=>'Viet Nam','VU'=>'Vanuatu','WF'=>'Wallis and Futuna','WS'=>'Samoa','YE'=>'Yemen','YT'=>'Mayotte','ZA'=>'South Africa','ZM'=>'Zambia','ZW'=>'Zimbabwe','ZZ'=>'Private use');
2
  /**
3
  * Compiled data. Do not edit.
4
  */
5
+ return ['AD'=>'Andorra','AE'=>'United Arab Emirates','AF'=>'Afghanistan','AG'=>'Antigua and Barbuda','AI'=>'Anguilla','AL'=>'Albania','AM'=>'Armenia','AO'=>'Angola','AQ'=>'Antarctica','AR'=>'Argentina','AS'=>'American Samoa','AT'=>'Austria','AU'=>'Australia','AW'=>'Aruba','AX'=>'Åland Islands','AZ'=>'Azerbaijan','BA'=>'Bosnia and Herzegovina','BB'=>'Barbados','BD'=>'Bangladesh','BE'=>'Belgium','BF'=>'Burkina Faso','BG'=>'Bulgaria','BH'=>'Bahrain','BI'=>'Burundi','BJ'=>'Benin','BL'=>'Saint Barthélemy','BM'=>'Bermuda','BN'=>'Brunei Darussalam','BO'=>'Bolivia','BQ'=>'Bonaire, Sint Eustatius and Saba','BR'=>'Brazil','BS'=>'Bahamas','BT'=>'Bhutan','BV'=>'Bouvet Island','BW'=>'Botswana','BY'=>'Belarus','BZ'=>'Belize','CA'=>'Canada','CC'=>'Cocos (Keeling) Islands','CD'=>'The Democratic Republic of the Congo','CF'=>'Central African Republic','CG'=>'Congo','CH'=>'Switzerland','CI'=>'Côte d\'Ivoire','CK'=>'Cook Islands','CL'=>'Chile','CM'=>'Cameroon','CN'=>'China','CO'=>'Colombia','CR'=>'Costa Rica','CU'=>'Cuba','CV'=>'Cabo Verde; Cape Verde','CW'=>'Curaçao','CX'=>'Christmas Island','CY'=>'Cyprus','CZ'=>'Czech Republic','DE'=>'Germany','DJ'=>'Djibouti','DK'=>'Denmark','DM'=>'Dominica','DO'=>'Dominican Republic','DZ'=>'Algeria','EC'=>'Ecuador','EE'=>'Estonia','EG'=>'Egypt','EH'=>'Western Sahara','ER'=>'Eritrea','ES'=>'Spain','ET'=>'Ethiopia','FI'=>'Finland','FJ'=>'Fiji','FK'=>'Falkland Islands (Malvinas)','FM'=>'Federated States of Micronesia','FO'=>'Faroe Islands','FR'=>'France','GA'=>'Gabon','GB'=>'United Kingdom','GD'=>'Grenada','GE'=>'Georgia','GF'=>'French Guiana','GG'=>'Guernsey','GH'=>'Ghana','GI'=>'Gibraltar','GL'=>'Greenland','GM'=>'Gambia','GN'=>'Guinea','GP'=>'Guadeloupe','GQ'=>'Equatorial Guinea','GR'=>'Greece','GS'=>'South Georgia and the South Sandwich Islands','GT'=>'Guatemala','GU'=>'Guam','GW'=>'Guinea-Bissau','GY'=>'Guyana','HK'=>'Hong Kong','HM'=>'Heard Island and McDonald Islands','HN'=>'Honduras','HR'=>'Croatia','HT'=>'Haiti','HU'=>'Hungary','ID'=>'Indonesia','IE'=>'Ireland','IL'=>'Israel','IM'=>'Isle of Man','IN'=>'India','IO'=>'British Indian Ocean Territory','IQ'=>'Iraq','IR'=>'Islamic Republic of Iran','IS'=>'Iceland','IT'=>'Italy','JE'=>'Jersey','JM'=>'Jamaica','JO'=>'Jordan','JP'=>'Japan','KE'=>'Kenya','KG'=>'Kyrgyzstan','KH'=>'Cambodia','KI'=>'Kiribati','KM'=>'Comoros','KN'=>'Saint Kitts and Nevis','KP'=>'Democratic People\'s Republic of Korea','KR'=>'Republic of Korea','KW'=>'Kuwait','KY'=>'Cayman Islands','KZ'=>'Kazakhstan','LA'=>'Lao People\'s Democratic Republic','LB'=>'Lebanon','LC'=>'Saint Lucia','LI'=>'Liechtenstein','LK'=>'Sri Lanka','LR'=>'Liberia','LS'=>'Lesotho','LT'=>'Lithuania','LU'=>'Luxembourg','LV'=>'Latvia','LY'=>'Libya','MA'=>'Morocco','MC'=>'Monaco','MD'=>'Moldova','ME'=>'Montenegro','MF'=>'Saint Martin (French part)','MG'=>'Madagascar','MH'=>'Marshall Islands','MK'=>'The Former Yugoslav Republic of Macedonia','ML'=>'Mali','MM'=>'Myanmar','MN'=>'Mongolia','MO'=>'Macao','MP'=>'Northern Mariana Islands','MQ'=>'Martinique','MR'=>'Mauritania','MS'=>'Montserrat','MT'=>'Malta','MU'=>'Mauritius','MV'=>'Maldives','MW'=>'Malawi','MX'=>'Mexico','MY'=>'Malaysia','MZ'=>'Mozambique','NA'=>'Namibia','NC'=>'New Caledonia','NE'=>'Niger','NF'=>'Norfolk Island','NG'=>'Nigeria','NI'=>'Nicaragua','NL'=>'Netherlands','NO'=>'Norway','NP'=>'Nepal','NR'=>'Nauru','NU'=>'Niue','NZ'=>'New Zealand','OM'=>'Oman','PA'=>'Panama','PE'=>'Peru','PF'=>'French Polynesia','PG'=>'Papua New Guinea','PH'=>'Philippines','PK'=>'Pakistan','PL'=>'Poland','PM'=>'Saint Pierre and Miquelon','PN'=>'Pitcairn','PR'=>'Puerto Rico','PS'=>'State of Palestine','PT'=>'Portugal','PW'=>'Palau','PY'=>'Paraguay','QA'=>'Qatar','RE'=>'Réunion','RO'=>'Romania','RS'=>'Serbia','RU'=>'Russian Federation','RW'=>'Rwanda','SA'=>'Saudi Arabia','SB'=>'Solomon Islands','SC'=>'Seychelles','SD'=>'Sudan','SE'=>'Sweden','SG'=>'Singapore','SH'=>'Saint Helena, Ascension and Tristan da Cunha','SI'=>'Slovenia','SJ'=>'Svalbard and Jan Mayen','SK'=>'Slovakia','SL'=>'Sierra Leone','SM'=>'San Marino','SN'=>'Senegal','SO'=>'Somalia','SR'=>'Suriname','SS'=>'South Sudan','ST'=>'Sao Tome and Principe','SV'=>'El Salvador','SX'=>'Sint Maarten (Dutch part)','SY'=>'Syrian Arab Republic','SZ'=>'Swaziland','TC'=>'Turks and Caicos Islands','TD'=>'Chad','TF'=>'French Southern Territories','TG'=>'Togo','TH'=>'Thailand','TJ'=>'Tajikistan','TK'=>'Tokelau','TL'=>'Timor-Leste','TM'=>'Turkmenistan','TN'=>'Tunisia','TO'=>'Tonga','TR'=>'Turkey','TT'=>'Trinidad and Tobago','TV'=>'Tuvalu','TW'=>'Taiwan','TZ'=>'United Republic of Tanzania','UA'=>'Ukraine','UG'=>'Uganda','UM'=>'United States Minor Outlying Islands','US'=>'United States','UY'=>'Uruguay','UZ'=>'Uzbekistan','VA'=>'Holy See (Vatican City State)','VC'=>'Saint Vincent and the Grenadines','VE'=>'Venezuela','VG'=>'British Virgin Islands','VI'=>'U.S. Virgin Islands','VN'=>'Viet Nam','VU'=>'Vanuatu','WF'=>'Wallis and Futuna','WS'=>'Samoa','YE'=>'Yemen','YT'=>'Mayotte','ZA'=>'South Africa','ZM'=>'Zambia','ZW'=>'Zimbabwe','ZZ'=>'Private use'];
loco.php CHANGED
@@ -4,10 +4,10 @@ Plugin Name: Loco Translate
4
  Plugin URI: https://wordpress.org/plugins/loco-translate/
5
  Description: Translate themes and plugins directly in WordPress
6
  Author: Tim Whitlock
7
- Version: 2.5.8
8
- Requires at least: 4.1
9
- Tested up to: 5.9
10
- Requires PHP: 5.2.4
11
  Author URI: https://localise.biz/wordpress/plugin
12
  Text Domain: loco-translate
13
  Domain Path: /languages/
@@ -33,7 +33,7 @@ function loco_plugin_file(){
33
  * @return string
34
  */
35
  function loco_plugin_version(){
36
- return '2.5.8';
37
  }
38
 
39
 
@@ -53,9 +53,7 @@ function loco_plugin_self(){
53
  * @return string __DIR__
54
  */
55
  function loco_plugin_root(){
56
- static $root;
57
- isset($root) or $root = dirname(__FILE__);
58
- return $root;
59
  }
60
 
61
 
4
  Plugin URI: https://wordpress.org/plugins/loco-translate/
5
  Description: Translate themes and plugins directly in WordPress
6
  Author: Tim Whitlock
7
+ Version: 2.6.0
8
+ Requires at least: 5.2
9
+ Requires PHP: 5.6.20
10
+ Tested up to: 5.9.1
11
  Author URI: https://localise.biz/wordpress/plugin
12
  Text Domain: loco-translate
13
  Domain Path: /languages/
33
  * @return string
34
  */
35
  function loco_plugin_version(){
36
+ return '2.6.0';
37
  }
38
 
39
 
53
  * @return string __DIR__
54
  */
55
  function loco_plugin_root(){
56
+ return __DIR__;
 
 
57
  }
58
 
59
 
pub/css/admin.css CHANGED
@@ -1 +1 @@
1
- ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.5.8) 0 0 no-repeat;min-height:75px}._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.5.8);background-size:16px}._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.5.8);background-size:16px}}._green_glow_inner{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}.loco-font,#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after,#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@font-face{font-family:"loco";src:url("../font/loco.eot?v=2.5.8");src:url("../font/loco.eot?v=2.5.8?#iefix") format("embedded-opentype"),url("../font/loco.woff?v=2.5.8") format("woff"),url("../font/loco.ttf?v=2.5.8") format("truetype"),url("../font/loco.svg?v=2.5.8#loco") format("svg");font-weight:normal;font-style:normal}.tipsy{font-size:11px;position:absolute;padding:5px;z-index:500001;opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.tipsy.in{opacity:1}.tipsy-inner{background-color:#000;color:#fff;white-space:nowrap;padding:6px 8px;line-height:1.3em;text-align:center;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}.tipsy-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.tipsy-n .tipsy-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-nw .tipsy-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-ne .tipsy-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-s .tipsy-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-sw .tipsy-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-se .tipsy-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-e .tipsy-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.tipsy-w .tipsy-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}#loco-admin.wrap .selector li,#loco-admin.wrap .selector .handle,#loco-admin.wrap .selectoradd a,#loco-admin.wrap .selectorsep:before,#loco-admin.wrap .selectorsep span{padding:.3em .75em}#loco-admin.wrap .selector{text-align:left;display:inline-block;white-space:nowrap}#loco-admin.wrap .selectoradd a,#loco-admin.wrap .selector .handle{cursor:default;display:block;position:relative;border-top:solid 1px #fff;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd;border-left:solid 1px #fff;color:#666;height:1.3em;overflow:hidden;white-space:normal}#loco-admin.wrap .selectorsep{display:inline-block;border:solid 1px transparent}#loco-admin.wrap .selectorsep:before{display:block;position:relative;color:#999;height:1.3em;overflow:hidden}#loco-admin.wrap .selectorsep>*{display:block;line-height:1em;color:#666;height:1.3em;overflow:hidden}#loco-admin.wrap .selector .handle{outline:none;white-space:nowrap;padding-right:2.3em;max-width:250px;text-overflow:ellipsis}#loco-admin.wrap .selector .handle .prefix{padding-right:.6ex}#loco-admin.wrap .selector .handle:after{font-family:loco;font-size:1.3em;color:#ccc;display:block;position:absolute;top:.25em;right:.6em;content:"▼"}#loco-admin.wrap .selector .handle:focus:after,#loco-admin.wrap .selector .handle:hover:after{color:#666}#loco-admin.wrap .selector.no-caret .handle{padding-right:.75em}#loco-admin.wrap .selector.no-caret .handle:after{display:none}#loco-admin.wrap .selector.no-title .handle{padding-left:.5em;padding-right:.5em}#loco-admin.wrap .selector.no-title .handle .label{display:none}#loco-admin.wrap .selector.no-title .handle .icon{margin-right:0px}#loco-admin.wrap .selector.dummy .handle{border-color:transparent}#loco-admin.wrap .selector.dummy .handle:after{display:none}#loco-admin.wrap .selectoradd{position:relative}#loco-admin.wrap .selectoradd>*{display:block;float:left;clear:none}#loco-admin.wrap .selectoradd>a.has-icon{width:1.3em}#loco-admin.wrap .selectoradd>a.has-icon:before{color:#999;display:inline;padding-left:0;padding-right:0;line-height:1.4em}#loco-admin.wrap .selectoradd>a.has-icon:hover:after{color:#2e892e}#loco-admin.wrap .selectorsep{display:inline-block}#loco-admin.wrap .selectorsep span{color:#666;height:1.3em}#loco-admin.wrap .selector ul{padding:0}#loco-admin.wrap .selector ul,#loco-admin.wrap .selector li{display:block;position:relative;cursor:default;margin:0}#loco-admin.wrap .selector ul{z-index:5;position:absolute;left:0;top:0;background:#f5f5f5;box-shadow:0 10px 5px rgba(0,0,0,.2);border:solid 1px #ccc;overflow:auto}#loco-admin.wrap .selector.up ul{margin-top:0}#loco-admin.wrap .selector.multi li input{display:none}#loco-admin.wrap .selector.multi li.checked{background:#e5e5e5}#loco-admin.wrap .selector li.active{background:#e5e5e5 !important}#loco-admin.wrap .selector li.over{background:#ccc !important;color:#fff;text-shadow:1px 1px #aaa}#loco-admin.wrap .selector li.over .label{color:#fff}#loco-admin.wrap .selector .label{font:inherit;color:inherit}#loco-admin.wrap .selector .icon{display:inline-block;min-width:1.2em;text-align:center;font-size:14px}#loco-admin.wrap .selector .icon.no-icon{display:none}#loco-admin.wrap .selector .icon:before{color:#666}#loco-admin.wrap .selector .avtr{width:18px;height:18px;background-size:18px;background-repeat:no-repeat}#loco-admin.wrap .selector .label{line-height:1}#loco-admin.wrap .selector .icon,#loco-admin.wrap .selector .icon-16{vertical-align:bottom}#loco-admin.wrap .selector .icon,#loco-admin.wrap .selector .lang,#loco-admin.wrap .selector .icon-16{margin-right:5px}#loco-admin.wrap .selector .region,#loco-admin.wrap .selector .variant-wales,#loco-admin.wrap .selector .region-gb.lang-cy,#loco-admin.wrap .selector .variant-scotland,#loco-admin.wrap .selector .region-gb.lang-gd,#loco-admin.wrap .selector .variant-valencia,#loco-admin.wrap .selector .region-es.variant-valencia,#loco-admin.wrap .selector .lang-ca,#loco-admin.wrap .selector .region-es.lang-ca,#loco-admin.wrap .selector .lang-eo,#loco-admin.wrap .selector .lang-eu{margin-left:2px;margin-right:7px}#loco-admin.wrap .selector.ticked .icon.no-icon{font-size:12px;display:inline-block}#loco-admin.wrap .selector.ticked .active .icon.no-icon:before{content:"✓"}#loco-admin.wrap .selectoradd a:hover,#loco-admin.wrap .selector a.handle:focus,#loco-admin.wrap .selector a.handle:hover{color:#000;border-color:#999}#loco-admin.wrap .selector.active .handle{border-color:#999;background-color:#eee;color:#999}#loco-admin.wrap .selector.active .handle:after{color:#999;content:"▲"}#loco-admin.wrap .selector.disabled{cursor:default;cursor:no-drop;cursor:not-allowed}#loco-admin.wrap .selector.disabled .handle{pointer-events:none;border-top:solid 1px #fff;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd;border-left:solid 1px #fff;color:#999;padding-right:1em}#loco-admin.wrap .selector.disabled .handle:after{display:none}#loco-admin.wrap .selector.disabled .handle span.icon{color:#999 !important}#loco-admin.wrap .selector li.disabled,#loco-admin.wrap .selector li.disabled.over{color:#aaa;text-shadow:1px 1px #fff;pointer-events:none}#loco-admin.wrap .selector li.disabled *{cursor:text}#loco-admin.wrap .selector li.disabled .icon:before{color:#aaa}#loco-admin.wrap .selector li.disabled .flag,#loco-admin.wrap .selector li.disabled .icon-16{opacity:.4}#loco-admin.wrap .selector.lefty ul{left:auto;right:0}#loco-admin.wrap .selector.lefty ul .icon,#loco-admin.wrap .selector.lefty ul .icon-32{display:block;float:right;clear:none}#loco-admin.wrap .selector.lefty ul .label{padding-right:32px;padding-left:0}#loco-admin.wrap .selector ul>form{margin:0;display:block}#loco-admin.wrap .selector ul>form input{margin:0;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0}#loco-admin.wrap .selector ul>form input:focus{-webkit-box-shadow:inset 0 0 5px 0 #3db63d;-moz-box-shadow:inset 0 0 5px 0 #3db63d;box-shadow:inset 0 0 5px 0 #3db63d}#loco-admin.wrap .selector ul>form input.error{border-color:#c00;-webkit-box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5);-moz-box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5);box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5)}#loco-admin.wrap .selector ul>form a.clear{margin:0;border:none}#loco-admin.wrap .selector ul>form ::placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap .selector ul>form ::-webkit-input-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap .selector ul>form :-moz-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block;opacity:1}#loco-admin.wrap .selector ul>form ::-moz-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block;opacity:1}#loco-admin.wrap .selector ul>form :-ms-input-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap .selector ul>form .ielt10 .placeheld{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap div.auto-comp-wrap{width:100%}#loco-admin.wrap div.auto-comp-wrap input{display:inline-block}#loco-admin.wrap div.auto-comp-wrap.loading input{background:transparent url(../img/ajax-loader.gif?v=2.5.8) right 2px no-repeat}#loco-admin.wrap div.auto-comp-drop{color:#333;background:#fff;border-top:none;position:absolute;width:auto;top:0;left:0;z-index:99;-webkit-box-shadow:0 5px 5px rgba(0,0,0,.4);-moz-box-shadow:0 5px 5px rgba(0,0,0,.4);box-shadow:0 5px 5px rgba(0,0,0,.4)}#loco-admin.wrap div.auto-comp-result{padding:5px 10px;cursor:pointer;background:#f0f0f0;border-top:solid 1px #fff;border-bottom:solid 1px #ddd;white-space:nowrap}#loco-admin.wrap div.auto-comp-result:first-child{border-top:solid 1px #ddd}#loco-admin.wrap div.auto-comp-result>*{display:inline-block;vertical-align:middle;line-height:normal}#loco-admin.wrap div.auto-comp-result .icon:before{padding-right:5px}#loco-admin.wrap div.auto-comp-result:hover{background:#a8a8a8;color:#fff;border-top-color:#a8a8a8;border-bottom-color:#999}#loco-admin.wrap div.auto-comp-result.selected{background:#666 !important;color:#fff;border-top-color:#666;border-bottom-color:#666}#loco-admin.wrap div.auto-comp-result .lang,#loco-admin.wrap div.auto-comp-result .region,#loco-admin.wrap div.auto-comp-result .variant-wales,#loco-admin.wrap div.auto-comp-result .region-gb.lang-cy,#loco-admin.wrap div.auto-comp-result .variant-scotland,#loco-admin.wrap div.auto-comp-result .region-gb.lang-gd,#loco-admin.wrap div.auto-comp-result .variant-valencia,#loco-admin.wrap div.auto-comp-result .region-es.variant-valencia,#loco-admin.wrap div.auto-comp-result .lang-ca,#loco-admin.wrap div.auto-comp-result .region-es.lang-ca,#loco-admin.wrap div.auto-comp-result .lang-eo,#loco-admin.wrap div.auto-comp-result .lang-eu,#loco-admin.wrap div.auto-comp-result .avtr{margin-right:5px}#loco-admin.wrap div.auto-comp-wrap.error a.icon.clear:before{color:#c00;opacity:1}#loco-admin.wrap div.auto-comp-wrap.error input[type=text]{border-color:#c00;color:#c00}#loco-admin.wrap div.auto-comp-wrap.error input[type=text]:focus{-webkit-box-shadow:0 0 .5em 0 rgba(153,0,0,.5);-moz-box-shadow:0 0 .5em 0 rgba(153,0,0,.5);box-shadow:0 0 .5em 0 rgba(153,0,0,.5)}#loco-admin.wrap ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}#loco-admin.wrap ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.5.8) 0 0 no-repeat;min-height:75px}#loco-admin.wrap ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-admin.wrap ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.5.8);background-size:16px}#loco-admin.wrap ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.5.8);background-size:16px}}#loco-admin.wrap ._green_glow_inner{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-admin.wrap ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-admin.wrap .loco-font,#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after,#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-admin.wrap .has-icon:before{display:inline-block;padding-right:.3em}#loco-admin.wrap a.icon-help{cursor:help}#loco-admin.wrap a.icon-help span{display:none}#loco-admin.wrap .icon-notag:before{content:""}#loco-admin.wrap .icon-magnify:before{content:"🔍"}#loco-admin.wrap .icon-python:before{content:"🐍"}#loco-admin.wrap .icon-unicode:before{content:"u"}#loco-admin.wrap .icon-json:before{content:"{"}#loco-admin.wrap .icon-bullist:before{content:""}#loco-admin.wrap .icon-numlist:before{content:""}#loco-admin.wrap .icon-indent:before{content:""}#loco-admin.wrap .icon-outdent:before{content:""}#loco-admin.wrap .icon-link:before{content:""}#loco-admin.wrap .icon-unlink:before{content:""}#loco-admin.wrap .icon-bold:before{content:"B"}#loco-admin.wrap .icon-italic:before{content:"I"}#loco-admin.wrap .icon-translate:before{content:""}#loco-admin.wrap .icon-proj:before{content:""}#loco-admin.wrap .icon-plural:before{content:"᛬"}#loco-admin.wrap .icon-max:before,#loco-admin.wrap .icon-full-screen:before{content:""}#loco-admin.wrap .icon-min:before{content:""}#loco-admin.wrap .icon-sort:before{content:""}#loco-admin.wrap .icon-ok:before,#loco-admin.wrap .notice-success>.has-icon:before,#loco-admin.wrap .notice-success p>strong.has-icon:before{content:"✓"}#loco-admin.wrap .icon-ok-empty:before{content:"🗌"}#loco-admin.wrap .icon-checkbox-checked:before,#loco-admin.wrap .selector.multi li.checked .icon-checkbox:before{content:"☑"}#loco-admin.wrap .icon-checkbox-unchecked:before{content:"☐"}#loco-admin.wrap .icon-checkbox-partial:before{content:"☉"}#loco-admin.wrap .icon-radio-checked:before{content:"⚫"}#loco-admin.wrap .icon-radio-unchecked:before{content:"⚪"}#loco-admin.wrap .icon-ext:before{content:"⬈"}#loco-admin.wrap .icon-share:before{content:""}#loco-admin.wrap .icon-star:before{content:""}#loco-admin.wrap .icon-user:before{content:""}#loco-admin.wrap .icon-remove:before,#loco-admin.wrap a.icon.close:before{content:"×"}#loco-admin.wrap .icon-cog:before{content:""}#loco-admin.wrap .icon-trash:before{content:""}#loco-admin.wrap .icon-time:before,#loco-admin.wrap .icon-history:before{content:""}#loco-admin.wrap .icon-download:before{content:""}#loco-admin.wrap .icon-revert:before{content:""}#loco-admin.wrap .icon-sync:before{content:""}#loco-admin.wrap .icon-lock:before,#loco-admin.wrap .notice-locked>.has-icon:before,#loco-admin.wrap .notice-locked p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-flag:before{content:""}#loco-admin.wrap .icon-tag:before{content:""}#loco-admin.wrap .icon-tags:before{content:""}#loco-admin.wrap .icon-print:before{content:""}#loco-admin.wrap .icon-camera:before{content:""}#loco-admin.wrap .icon-pencil:before{content:""}#loco-admin.wrap .icon-add:before{content:""}#loco-admin.wrap .icon-del:before{content:""}#loco-admin.wrap .icon-clear:before,#loco-admin.wrap a.icon.clear:before{content:""}#loco-admin.wrap .icon-ok-sign:before{content:"✔"}#loco-admin.wrap .icon-help:before{content:"?"}#loco-admin.wrap .icon-info:before,#loco-admin.wrap .notice-info>.has-icon:before,#loco-admin.wrap .notice-info p>strong.has-icon:before{content:"ℹ"}#loco-admin.wrap .icon-cancel:before{content:""}#loco-admin.wrap .icon-warn:before,#loco-admin.wrap .notice-error>.has-icon:before,#loco-admin.wrap .notice-error p>strong.has-icon:before,#loco-admin.wrap .notice-warning>.has-icon:before,#loco-admin.wrap .notice-warning p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-comment:before{content:""}#loco-admin.wrap .icon-bar-chart:before{content:""}#loco-admin.wrap .icon-key:before{content:""}#loco-admin.wrap .icon-cogs:before{content:""}#loco-admin.wrap .icon-comments:before{content:""}#loco-admin.wrap .icon-signout:before{content:""}#loco-admin.wrap .icon-signin:before{content:""}#loco-admin.wrap .icon-upload:before{content:""}#loco-admin.wrap .icon-twitter:before{content:"🐦"}#loco-admin.wrap .icon-facebook:before{content:""}#loco-admin.wrap .icon-github:before{content:""}#loco-admin.wrap .icon-feed:before{content:""}#loco-admin.wrap .icon-globe:before{content:""}#loco-admin.wrap .icon-wrench:before,#loco-admin.wrap .notice-debug>.has-icon:before,#loco-admin.wrap .notice-debug p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-group:before{content:""}#loco-admin.wrap .icon-cloud:before{content:""}#loco-admin.wrap .icon-copy:before{content:""}#loco-admin.wrap .icon-save:before{content:""}#loco-admin.wrap .icon-menu:before{content:""}#loco-admin.wrap .icon-table:before{content:""}#loco-admin.wrap .icon-caret-down:before{content:"▼"}#loco-admin.wrap .icon-caret-up:before{content:"▲"}#loco-admin.wrap .icon-caret-right:before{content:"▶"}#loco-admin.wrap .icon-mail:before{content:""}#loco-admin.wrap .icon-cloud-upload:before{content:""}#loco-admin.wrap .icon-file:before{content:""}#loco-admin.wrap .icon-circle-white:before{content:"⚬"}#loco-admin.wrap .icon-circle-black:before{content:"●"}#loco-admin.wrap .icon-eraser:before{content:""}#loco-admin.wrap .icon-unlock:before{content:""}#loco-admin.wrap .icon-apple:before{content:""}#loco-admin.wrap .icon-android:before{content:""}#loco-admin.wrap .icon-robot:before{content:"🤖"}#loco-admin.wrap .icon-back:before{content:"⬅"}#loco-admin.wrap .icon-next:before{content:"➔"}#loco-admin.wrap .icon-arrow-up:before{content:""}#loco-admin.wrap .icon-calendar:before{content:""}#loco-admin.wrap .icon-ccard:before{content:""}#loco-admin.wrap .icon-caret-left:before{content:"◀"}#loco-admin.wrap .icon-pro:before{content:"⚡"}#loco-admin.wrap .icon-bell:before{content:""}#loco-admin.wrap .icon-code:before{content:""}#loco-admin.wrap .icon-privacy:before{content:"🛡"}#loco-admin.wrap .icon-hellip:before{content:"…"}#loco-admin.wrap .icon-vellip:before{content:"⁞"}#loco-admin.wrap .icon-collapse:before{content:""}#loco-admin.wrap .icon-expand:before{content:""}#loco-admin.wrap .icon-wordpress:before{content:""}#loco-admin.wrap .icon-database:before{content:""}#loco-admin.wrap .icon-restore:before{content:""}#loco-admin.wrap .icon-pilcrow:before{content:"¶"}#loco-admin.wrap .icon-status.is-translated:before,#loco-admin.wrap .is-translated>header>.icon-status:before{color:#2e892e;content:"✓";text-align:center}#loco-admin.wrap .icon-status.is-untranslated:before,#loco-admin.wrap .is-untranslated>header>.icon-status:before{color:#aaa;content:"×";text-align:center;font-size:1.1em}#loco-admin.wrap .icon-status.is-flagged:before,#loco-admin.wrap .is-flagged>header>.icon-status:before{color:#bd2c00;content:"";text-align:center}#loco-admin.wrap .icon-status.is-translated.is-blank:before,#loco-admin.wrap .icon-status.is-translated.is-inherit:before,#loco-admin.wrap .is-translated.is-blank>header>.icon-status:before,#loco-admin.wrap .is-translated.is-inherit>header>.icon-status:before{content:"🗌"}#loco-admin.wrap .icon-status.is-fuzzy:before,#loco-admin.wrap .is-fuzzy>header>.icon-status:before{color:#666;content:""}#loco-admin.wrap .lang,#loco-admin.wrap .region,#loco-admin.wrap .variant-wales,#loco-admin.wrap .region-gb.lang-cy,#loco-admin.wrap .variant-scotland,#loco-admin.wrap .region-gb.lang-gd,#loco-admin.wrap .variant-valencia,#loco-admin.wrap .region-es.variant-valencia,#loco-admin.wrap .lang-ca,#loco-admin.wrap .region-es.lang-ca,#loco-admin.wrap .lang-eo,#loco-admin.wrap .lang-eu{color:#fff;background:#2e892e;display:inline-block;text-transform:uppercase;overflow:hidden;font-family:Verdana,Arial,sans-serif;font-size:9px;font-weight:normal;font-style:normal;line-height:12px;text-align:center;white-space:normal;text-shadow:none}#loco-admin.wrap .lang{width:20px;height:12px;line-height:12px;vertical-align:middle}#loco-admin.wrap .lang:before{content:attr(lang);vertical-align:baseline}#loco-admin.wrap .no-lang{width:18px;height:10px;border:solid 1px #2e892e;background:transparent}#loco-admin.wrap .lang-el{background-color:#1d48a3}#loco-admin.wrap .lang-el:before{content:"Ελ"}#loco-admin.wrap .region,#loco-admin.wrap .variant-wales,#loco-admin.wrap .region-gb.lang-cy,#loco-admin.wrap .variant-scotland,#loco-admin.wrap .region-gb.lang-gd,#loco-admin.wrap .variant-valencia,#loco-admin.wrap .region-es.variant-valencia,#loco-admin.wrap .lang-ca,#loco-admin.wrap .region-es.lang-ca,#loco-admin.wrap .lang-eo,#loco-admin.wrap .lang-eu{width:16px;height:12px;margin:0 2px;background-image:url(../img/flags.png?v=2.5.8);background-repeat:no-repeat;background-color:transparent}#loco-admin.wrap .region:before,#loco-admin.wrap .variant-wales:before,#loco-admin.wrap .region-gb.lang-cy:before,#loco-admin.wrap .variant-scotland:before,#loco-admin.wrap .region-gb.lang-gd:before,#loco-admin.wrap .variant-valencia:before,#loco-admin.wrap .region-es.variant-valencia:before,#loco-admin.wrap .lang-ca:before,#loco-admin.wrap .region-es.lang-ca:before,#loco-admin.wrap .lang-eo:before,#loco-admin.wrap .lang-eu:before{visibility:hidden}#loco-admin.wrap .lang-zh{background-color:#b90000}#loco-admin.wrap .lang-zh.script-hans:before{content:"中国"}#loco-admin.wrap .lang-zh.script-hant:before{content:"中國"}#loco-admin.wrap .__{background-position:0 0}#loco-admin.wrap .lang-eo{background-position:0 -12px}#loco-admin.wrap .lang-eu{background-position:0 -24px}#loco-admin.wrap .lang-ca,#loco-admin.wrap .region-es.lang-ca{background-position:0 -36px}#loco-admin.wrap .region-tg{background-position:0 -48px}#loco-admin.wrap .region-me{background-position:0 -60px}#loco-admin.wrap .region-la{background-position:0 -73px}#loco-admin.wrap .region-mr{background-position:0 -85px}#loco-admin.wrap .region-ni{background-position:0 -97px}#loco-admin.wrap .region-lv{background-position:0 -109px}#loco-admin.wrap .region-om{background-position:0 -121px}#loco-admin.wrap .region-af{background-position:0 -133px}#loco-admin.wrap .region-cy{background-position:0 -145px}#loco-admin.wrap .region-bj{background-position:0 -157px}#loco-admin.wrap .region-aq{background-position:0 -169px}#loco-admin.wrap .region-cn{background-position:0 -186px}#loco-admin.wrap .region-co{background-position:0 -198px}#loco-admin.wrap .region-cx{background-position:0 -210px}#loco-admin.wrap .region-ag{background-position:0 -222px}#loco-admin.wrap .region-ms{background-position:0 -234px}#loco-admin.wrap .region-md{background-position:0 -246px}#loco-admin.wrap .region-zm{background-position:0 -258px}#loco-admin.wrap .region-vn{background-position:0 -270px}#loco-admin.wrap .region-tf{background-position:0 -282px}#loco-admin.wrap .region-td{background-position:0 -294px}#loco-admin.wrap .region-yt{background-position:0 -306px}#loco-admin.wrap .region-lb{background-position:0 -318px}#loco-admin.wrap .region-mf{background-position:0 -330px}#loco-admin.wrap .region-lu{background-position:0 -347px}#loco-admin.wrap .region-mq{background-position:0 -359px}#loco-admin.wrap .region-cz{background-position:0 -371px}#loco-admin.wrap .region-ae{background-position:0 -383px}#loco-admin.wrap .region-cm{background-position:0 -395px}#loco-admin.wrap .region-bi{background-position:0 -407px}#loco-admin.wrap .region-ar{background-position:0 -419px}#loco-admin.wrap .region-as{background-position:0 -431px}#loco-admin.wrap .region-bh{background-position:0 -443px}#loco-admin.wrap .region-cl{background-position:0 -455px}#loco-admin.wrap .region-ad{background-position:0 -467px}#loco-admin.wrap .region-mp{background-position:0 -479px}#loco-admin.wrap .region-lt{background-position:0 -491px}#loco-admin.wrap .region-mg{background-position:0 -503px}#loco-admin.wrap .region-lc{background-position:0 -515px}#loco-admin.wrap .region-tr{background-position:0 -527px}#loco-admin.wrap .region-ua{background-position:0 -539px}#loco-admin.wrap .region-tv{background-position:0 -551px}#loco-admin.wrap .region-vi{background-position:0 -563px}#loco-admin.wrap .region-mt{background-position:0 -575px}#loco-admin.wrap .region-no{background-position:0 -587px}#loco-admin.wrap .region-mc{background-position:0 -599px}#loco-admin.wrap .region-ch{background-position:0 -611px}#loco-admin.wrap .region-bl{background-position:0 -623px}#loco-admin.wrap .region-aw{background-position:0 -640px}#loco-admin.wrap .region-bz{background-position:0 -652px}#loco-admin.wrap .region-bm{background-position:0 -664px}#loco-admin.wrap .region-ci{background-position:0 -676px}#loco-admin.wrap .region-mu{background-position:0 -688px}#loco-admin.wrap .region-us{background-position:0 -700px}#loco-admin.wrap .region-tw{background-position:0 -712px}#loco-admin.wrap .region-ye{background-position:0 -724px}#loco-admin.wrap .region-mw{background-position:0 -736px}#loco-admin.wrap .region-nl{background-position:0 -748px}#loco-admin.wrap .region-ls{background-position:0 -760px}#loco-admin.wrap .region-bo{background-position:0 -772px}#loco-admin.wrap .region-at{background-position:0 -784px}#loco-admin.wrap .region-ck{background-position:0 -796px}#loco-admin.wrap .region-by{background-position:0 -808px}#loco-admin.wrap .region-au{background-position:0 -820px}#loco-admin.wrap .region-bn{background-position:0 -832px}#loco-admin.wrap .region-ma{background-position:0 -844px}#loco-admin.wrap .region-nz{background-position:0 -856px}#loco-admin.wrap .region-lr{background-position:0 -868px}#loco-admin.wrap .region-mv{background-position:0 -880px}#loco-admin.wrap .region-tc{background-position:0 -892px}#loco-admin.wrap .region-ug{background-position:0 -904px}#loco-admin.wrap .region-tt{background-position:0 -916px}#loco-admin.wrap .region-pl{background-position:0 -928px}#loco-admin.wrap .region-rs{background-position:0 -940px}#loco-admin.wrap .region-in{background-position:0 -952px}#loco-admin.wrap .region-ge{background-position:0 -964px}#loco-admin.wrap .region-gr{background-position:0 -976px}#loco-admin.wrap .region-gs{background-position:0 -988px}#loco-admin.wrap .region-gd{background-position:0 -1000px}#loco-admin.wrap .region-io{background-position:0 -1012px}#loco-admin.wrap .region-hk{background-position:0 -1024px}#loco-admin.wrap .region-kp{background-position:0 -1036px}#loco-admin.wrap .region-kg{background-position:0 -1048px}#loco-admin.wrap .region-pm{background-position:0 -1060px}#loco-admin.wrap .region-sv{background-position:0 -1072px}#loco-admin.wrap .region-re{background-position:0 -1084px}#loco-admin.wrap .region-sa{background-position:0 -1096px}#loco-admin.wrap .region-sc{background-position:0 -1108px}#loco-admin.wrap .region-st{background-position:0 -1120px}#loco-admin.wrap .region-ke{background-position:0 -1132px}#loco-admin.wrap .region-im{background-position:0 -1144px}#loco-admin.wrap .region-kr{background-position:0 -1161px}#loco-admin.wrap .region-gf{background-position:0 -1173px}#loco-admin.wrap .region-dj{background-position:0 -1185px}#loco-admin.wrap .region-gq{background-position:0 -1197px}#loco-admin.wrap .region-gp{background-position:0 -1209px}#loco-admin.wrap .region-dk{background-position:0 -1221px}#loco-admin.wrap .region-gg{background-position:0 -1233px}#loco-admin.wrap .region-il{background-position:0 -1250px}#loco-admin.wrap .region-pn{background-position:0 -1262px}#loco-admin.wrap .region-sb{background-position:0 -1274px}#loco-admin.wrap .region-py{background-position:0 -1286px}#loco-admin.wrap .region-ru{background-position:0 -1298px}#loco-admin.wrap .region-kw{background-position:0 -1310px}#loco-admin.wrap .region-do{background-position:0 -1322px}#loco-admin.wrap .region-gt{background-position:0 -1334px}#loco-admin.wrap .region-gb{background-position:0 -1346px}#loco-admin.wrap .region-gu{background-position:0 -1358px}#loco-admin.wrap .region-je{background-position:0 -1370px}#loco-admin.wrap .region-hm{background-position:0 -1387px}#loco-admin.wrap .region-sg{background-position:0 -1399px}#loco-admin.wrap .region-pk{background-position:0 -1411px}#loco-admin.wrap .region-sr{background-position:0 -1423px}#loco-admin.wrap .region-se{background-position:0 -1435px}#loco-admin.wrap .region-jp{background-position:0 -1447px}#loco-admin.wrap .region-gw{background-position:0 -1459px}#loco-admin.wrap .region-eh{background-position:0 -1471px}#loco-admin.wrap .region-dz{background-position:0 -1483px}#loco-admin.wrap .region-ga{background-position:0 -1495px}#loco-admin.wrap .region-fr{background-position:0 -1507px}#loco-admin.wrap .region-dm{background-position:0 -1519px}#loco-admin.wrap .region-hn{background-position:0 -1531px}#loco-admin.wrap .region-sd{background-position:0 -1543px}#loco-admin.wrap .region-rw{background-position:0 -1555px}#loco-admin.wrap .region-ph{background-position:0 -1567px}#loco-admin.wrap .region-ss{background-position:0 -1579px}#loco-admin.wrap .region-qa{background-position:0 -1596px}#loco-admin.wrap .region-pe{background-position:0 -1608px}#loco-admin.wrap .region-pr{background-position:0 -1620px}#loco-admin.wrap .region-si{background-position:0 -1632px}#loco-admin.wrap .region-ht{background-position:0 -1644px}#loco-admin.wrap .region-es{background-position:0 -1656px}#loco-admin.wrap .region-gl{background-position:0 -1668px}#loco-admin.wrap .region-gm{background-position:0 -1680px}#loco-admin.wrap .region-er{background-position:0 -1692px}#loco-admin.wrap .region-fi{background-position:0 -1704px}#loco-admin.wrap .region-ee{background-position:0 -1716px}#loco-admin.wrap .region-kn{background-position:0 -1728px}#loco-admin.wrap .region-hu{background-position:0 -1740px}#loco-admin.wrap .region-iq{background-position:0 -1752px}#loco-admin.wrap .region-ky{background-position:0 -1764px}#loco-admin.wrap .region-sh{background-position:0 -1776px}#loco-admin.wrap .region-ps{background-position:0 -1788px}#loco-admin.wrap .region-pf{background-position:0 -1800px}#loco-admin.wrap .region-sj{background-position:0 -1812px}#loco-admin.wrap .region-id{background-position:0 -1824px}#loco-admin.wrap .region-is{background-position:0 -1836px}#loco-admin.wrap .region-eg{background-position:0 -1848px}#loco-admin.wrap .region-fk{background-position:0 -1860px}#loco-admin.wrap .region-fj{background-position:0 -1872px}#loco-admin.wrap .region-gn{background-position:0 -1884px}#loco-admin.wrap .region-gy{background-position:0 -1896px}#loco-admin.wrap .region-ir{background-position:0 -1908px}#loco-admin.wrap .region-km{background-position:0 -1920px}#loco-admin.wrap .region-ie{background-position:0 -1932px}#loco-admin.wrap .region-kz{background-position:0 -1944px}#loco-admin.wrap .region-ro{background-position:0 -1956px}#loco-admin.wrap .region-sk{background-position:0 -1968px}#loco-admin.wrap .region-pg{background-position:0 -1980px}#loco-admin.wrap .region-pt{background-position:0 -1992px}#loco-admin.wrap .region-so{background-position:0 -2004px}#loco-admin.wrap .region-sx{background-position:0 -2016px}#loco-admin.wrap .region-hr{background-position:0 -2033px}#loco-admin.wrap .region-ki{background-position:0 -2045px}#loco-admin.wrap .region-jm{background-position:0 -2057px}#loco-admin.wrap .region-ec{background-position:0 -2069px}#loco-admin.wrap .region-et{background-position:0 -2081px}#loco-admin.wrap .region-fo{background-position:0 -2093px}#loco-admin.wrap .region-kh{background-position:0 -2105px}#loco-admin.wrap .region-sy{background-position:0 -2117px}#loco-admin.wrap .region-sn{background-position:0 -2129px}#loco-admin.wrap .region-pw{background-position:0 -2141px}#loco-admin.wrap .region-sl{background-position:0 -2153px}#loco-admin.wrap .region-fm{background-position:0 -2165px}#loco-admin.wrap .region-gi{background-position:0 -2177px}#loco-admin.wrap .region-de{background-position:0 -2189px}#loco-admin.wrap .region-gh{background-position:0 -2201px}#loco-admin.wrap .region-jo{background-position:0 -2213px}#loco-admin.wrap .region-it{background-position:0 -2225px}#loco-admin.wrap .region-pa{background-position:0 -2237px}#loco-admin.wrap .region-sz{background-position:0 -2249px}#loco-admin.wrap .region-sm{background-position:0 -2261px}#loco-admin.wrap .region-tn{background-position:0 -2273px}#loco-admin.wrap .region-ml{background-position:0 -2285px}#loco-admin.wrap .region-cg{background-position:0 -2297px}#loco-admin.wrap .region-ax{background-position:0 -2309px}#loco-admin.wrap .region-ao{background-position:0 -2321px}#loco-admin.wrap .region-bt{background-position:0 -2333px}#loco-admin.wrap .region-an{background-position:0 -2345px}#loco-admin.wrap .region-bb{background-position:0 -2357px}#loco-admin.wrap .region-cf{background-position:0 -2369px}#loco-admin.wrap .region-mm{background-position:0 -2381px}#loco-admin.wrap .region-li{background-position:0 -2393px}#loco-admin.wrap .region-na{background-position:0 -2405px}#loco-admin.wrap .region-mz{background-position:0 -2417px}#loco-admin.wrap .region-to{background-position:0 -2429px}#loco-admin.wrap .region-vg{background-position:0 -2441px}#loco-admin.wrap .region-ve{background-position:0 -2453px}#loco-admin.wrap .region-tz{background-position:0 -2465px}#loco-admin.wrap .region-tm{background-position:0 -2477px}#loco-admin.wrap .region-mx{background-position:0 -2489px}#loco-admin.wrap .region-nc{background-position:0 -2501px}#loco-admin.wrap .region-mo{background-position:0 -2513px}#loco-admin.wrap .region-lk{background-position:0 -2525px}#loco-admin.wrap .region-cd{background-position:0 -2537px}#loco-admin.wrap .region-al{background-position:0 -2549px}#loco-admin.wrap .region-bw{background-position:0 -2561px}#loco-admin.wrap .region-cs{background-position:0 -2573px}#loco-admin.wrap .region-cr{background-position:0 -2585px}#loco-admin.wrap .region-bv{background-position:0 -2597px}#loco-admin.wrap .region-am{background-position:0 -2609px}#loco-admin.wrap .region-az{background-position:0 -2621px}#loco-admin.wrap .region-ba{background-position:0 -2633px}#loco-admin.wrap .region-mn{background-position:0 -2645px}#loco-admin.wrap .region-nu{background-position:0 -2657px}#loco-admin.wrap .region-my{background-position:0 -2669px}#loco-admin.wrap .region-tl{background-position:0 -2681px}#loco-admin.wrap .region-ws{background-position:0 -2693px}#loco-admin.wrap .region-th{background-position:0 -2705px}#loco-admin.wrap .region-nf{background-position:0 -2717px}#loco-admin.wrap .region-ly{background-position:0 -2729px}#loco-admin.wrap .region-ai{background-position:0 -2741px}#loco-admin.wrap .region-br{background-position:0 -2753px}#loco-admin.wrap .region-cv{background-position:0 -2765px}#loco-admin.wrap .region-be{background-position:0 -2777px}#loco-admin.wrap .region-ca{background-position:0 -2789px}#loco-admin.wrap .region-bd{background-position:0 -2801px}#loco-admin.wrap .region-cw{background-position:0 -2813px}#loco-admin.wrap .region-bs{background-position:0 -2830px}#loco-admin.wrap .region-ng{background-position:0 -2842px}#loco-admin.wrap .region-mk{background-position:0 -2854px}#loco-admin.wrap .region-np{background-position:0 -2866px}#loco-admin.wrap .region-va{background-position:0 -2878px}#loco-admin.wrap .region-uz{background-position:0 -2890px}#loco-admin.wrap .region-um{background-position:0 -2902px}#loco-admin.wrap .region-tk{background-position:0 -2914px}#loco-admin.wrap .region-vc{background-position:0 -2926px}#loco-admin.wrap .region-zw{background-position:0 -2938px}#loco-admin.wrap .region-nr{background-position:0 -2950px}#loco-admin.wrap .region-ne{background-position:0 -2962px}#loco-admin.wrap .region-cu{background-position:0 -2974px}#loco-admin.wrap .region-bq{background-position:0 -2986px}#loco-admin.wrap .region-bf{background-position:0 -2998px}#loco-admin.wrap .region-bg{background-position:0 -3010px}#loco-admin.wrap .region-cc{background-position:0 -3022px}#loco-admin.wrap .region-mh{background-position:0 -3034px}#loco-admin.wrap .region-za{background-position:0 -3046px}#loco-admin.wrap .region-uy{background-position:0 -3058px}#loco-admin.wrap .region-wf{background-position:0 -3070px}#loco-admin.wrap .region-vu{background-position:0 -3082px}#loco-admin.wrap .region-tj{background-position:0 -3094px}#loco-admin.wrap .variant-scotland,#loco-admin.wrap .region-gb.lang-gd{background-position:0 -3106px}#loco-admin.wrap .variant-valencia,#loco-admin.wrap .region-es.variant-valencia{background-position:0 -3118px}#loco-admin.wrap .variant-wales,#loco-admin.wrap .region-gb.lang-cy{background-position:0 -3130px}#loco-admin.wrap .x-eu{background-position:0 -3142px}#loco-admin.wrap span.lang code{display:none}#loco-admin.wrap .icon-notag:before{content:""}#loco-admin.wrap .icon-magnify:before{content:"🔍"}#loco-admin.wrap .icon-python:before{content:"🐍"}#loco-admin.wrap .icon-unicode:before{content:"u"}#loco-admin.wrap .icon-json:before{content:"{"}#loco-admin.wrap .icon-bullist:before{content:""}#loco-admin.wrap .icon-numlist:before{content:""}#loco-admin.wrap .icon-indent:before{content:""}#loco-admin.wrap .icon-outdent:before{content:""}#loco-admin.wrap .icon-link:before{content:""}#loco-admin.wrap .icon-unlink:before{content:""}#loco-admin.wrap .icon-bold:before{content:"B"}#loco-admin.wrap .icon-italic:before{content:"I"}#loco-admin.wrap .icon-translate:before{content:""}#loco-admin.wrap .icon-proj:before{content:""}#loco-admin.wrap .icon-plural:before{content:"᛬"}#loco-admin.wrap .icon-max:before,#loco-admin.wrap .icon-full-screen:before{content:""}#loco-admin.wrap .icon-min:before{content:""}#loco-admin.wrap .icon-sort:before{content:""}#loco-admin.wrap .icon-ok:before,#loco-admin.wrap .notice-success>.has-icon:before,#loco-admin.wrap .notice-success p>strong.has-icon:before{content:"✓"}#loco-admin.wrap .icon-ok-empty:before{content:"🗌"}#loco-admin.wrap .icon-checkbox-checked:before,#loco-admin.wrap .selector.multi li.checked .icon-checkbox:before{content:"☑"}#loco-admin.wrap .icon-checkbox-unchecked:before{content:"☐"}#loco-admin.wrap .icon-checkbox-partial:before{content:"☉"}#loco-admin.wrap .icon-radio-checked:before{content:"⚫"}#loco-admin.wrap .icon-radio-unchecked:before{content:"⚪"}#loco-admin.wrap .icon-ext:before{content:"⬈"}#loco-admin.wrap .icon-share:before{content:""}#loco-admin.wrap .icon-star:before{content:""}#loco-admin.wrap .icon-user:before{content:""}#loco-admin.wrap .icon-remove:before,#loco-admin.wrap a.icon.close:before{content:"×"}#loco-admin.wrap .icon-cog:before{content:""}#loco-admin.wrap .icon-trash:before{content:""}#loco-admin.wrap .icon-time:before,#loco-admin.wrap .icon-history:before{content:""}#loco-admin.wrap .icon-download:before{content:""}#loco-admin.wrap .icon-revert:before{content:""}#loco-admin.wrap .icon-sync:before{content:""}#loco-admin.wrap .icon-lock:before,#loco-admin.wrap .notice-locked>.has-icon:before,#loco-admin.wrap .notice-locked p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-flag:before{content:""}#loco-admin.wrap .icon-tag:before{content:""}#loco-admin.wrap .icon-tags:before{content:""}#loco-admin.wrap .icon-print:before{content:""}#loco-admin.wrap .icon-camera:before{content:""}#loco-admin.wrap .icon-pencil:before{content:""}#loco-admin.wrap .icon-add:before{content:""}#loco-admin.wrap .icon-del:before{content:""}#loco-admin.wrap .icon-clear:before,#loco-admin.wrap a.icon.clear:before{content:""}#loco-admin.wrap .icon-ok-sign:before{content:"✔"}#loco-admin.wrap .icon-help:before{content:"?"}#loco-admin.wrap .icon-info:before,#loco-admin.wrap .notice-info>.has-icon:before,#loco-admin.wrap .notice-info p>strong.has-icon:before{content:"ℹ"}#loco-admin.wrap .icon-cancel:before{content:""}#loco-admin.wrap .icon-warn:before,#loco-admin.wrap .notice-error>.has-icon:before,#loco-admin.wrap .notice-error p>strong.has-icon:before,#loco-admin.wrap .notice-warning>.has-icon:before,#loco-admin.wrap .notice-warning p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-comment:before{content:""}#loco-admin.wrap .icon-bar-chart:before{content:""}#loco-admin.wrap .icon-key:before{content:""}#loco-admin.wrap .icon-cogs:before{content:""}#loco-admin.wrap .icon-comments:before{content:""}#loco-admin.wrap .icon-signout:before{content:""}#loco-admin.wrap .icon-signin:before{content:""}#loco-admin.wrap .icon-upload:before{content:""}#loco-admin.wrap .icon-twitter:before{content:"🐦"}#loco-admin.wrap .icon-facebook:before{content:""}#loco-admin.wrap .icon-github:before{content:""}#loco-admin.wrap .icon-feed:before{content:""}#loco-admin.wrap .icon-globe:before{content:""}#loco-admin.wrap .icon-wrench:before,#loco-admin.wrap .notice-debug>.has-icon:before,#loco-admin.wrap .notice-debug p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-group:before{content:""}#loco-admin.wrap .icon-cloud:before{content:""}#loco-admin.wrap .icon-copy:before{content:""}#loco-admin.wrap .icon-save:before{content:""}#loco-admin.wrap .icon-menu:before{content:""}#loco-admin.wrap .icon-table:before{content:""}#loco-admin.wrap .icon-caret-down:before{content:"▼"}#loco-admin.wrap .icon-caret-up:before{content:"▲"}#loco-admin.wrap .icon-caret-right:before{content:"▶"}#loco-admin.wrap .icon-mail:before{content:""}#loco-admin.wrap .icon-cloud-upload:before{content:""}#loco-admin.wrap .icon-file:before{content:""}#loco-admin.wrap .icon-circle-white:before{content:"⚬"}#loco-admin.wrap .icon-circle-black:before{content:"●"}#loco-admin.wrap .icon-eraser:before{content:""}#loco-admin.wrap .icon-unlock:before{content:""}#loco-admin.wrap .icon-apple:before{content:""}#loco-admin.wrap .icon-android:before{content:""}#loco-admin.wrap .icon-robot:before{content:"🤖"}#loco-admin.wrap .icon-back:before{content:"⬅"}#loco-admin.wrap .icon-next:before{content:"➔"}#loco-admin.wrap .icon-arrow-up:before{content:""}#loco-admin.wrap .icon-calendar:before{content:""}#loco-admin.wrap .icon-ccard:before{content:""}#loco-admin.wrap .icon-caret-left:before{content:"◀"}#loco-admin.wrap .icon-pro:before{content:"⚡"}#loco-admin.wrap .icon-bell:before{content:""}#loco-admin.wrap .icon-code:before{content:""}#loco-admin.wrap .icon-privacy:before{content:"🛡"}#loco-admin.wrap .icon-hellip:before{content:"…"}#loco-admin.wrap .icon-vellip:before{content:"⁞"}#loco-admin.wrap .icon-collapse:before{content:""}#loco-admin.wrap .icon-expand:before{content:""}#loco-admin.wrap .icon-wordpress:before{content:""}#loco-admin.wrap .icon-database:before{content:""}#loco-admin.wrap .icon-restore:before{content:""}#loco-admin.wrap .icon-pilcrow:before{content:"¶"}#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before,#loco-admin.wrap .has-dashicon:before{speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before{font-family:"loco"}#loco-admin.wrap .has-dashicon:before{font-family:"dashicons";font-size:1.4em}#loco-admin.wrap .has-icon:before,#loco-admin.wrap .has-dashicon:before,#loco-admin.wrap .has-icon>span{display:inline-block;vertical-align:middle}#loco-admin.wrap .only-icon{text-align:center}#loco-admin.wrap .only-icon:before{text-align:center;padding:0}#loco-admin.wrap .only-icon span{display:none}#loco-admin.wrap a,#loco-admin.wrap .wp-core-ui .button-link{text-decoration:none}#loco-admin.wrap h3:hover>a.loco-anchor{color:#ccc}#loco-admin.wrap h3:hover>a.loco-anchor:before{content:"¶"}#loco-admin.wrap .has-lang>span{display:inline-block;vertical-align:middle}#loco-admin.wrap a.has-lang:hover>span:last-child{text-decoration:underline}#loco-admin.wrap h1 ul,#loco-admin.wrap h1 li{margin:0;padding:0}#loco-admin.wrap h1 li{display:inline-block}#loco-admin.wrap h1 li:after{content:"/";color:#999;text-shadow:none;display:inline-block}#loco-admin.wrap h1 li:last-child:after{content:""}#loco-admin.wrap h1 li:last-child a{color:inherit;pointer-events:none;cursor:auto}#loco-admin.wrap h2 span{color:#999;font-weight:normal}#loco-admin.wrap h2 .loco-meta,#loco-admin.wrap h3 .loco-meta{color:inherit;font-size:14px;font-weight:normal;vertical-align:middle}#loco-admin.wrap .wp-list-table td:first-child .icon{width:16px;display:inline-block;text-align:center}#loco-admin.wrap .wp-list-table td{white-space:nowrap}#loco-admin.wrap .wp-list-table td>a,#loco-admin.wrap .wp-list-table td>time{display:inline-block;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#loco-admin.wrap .wp-list-table th.loco-sort{cursor:pointer}#loco-admin.wrap .wp-list-table th.loco-sort:hover{color:#000}#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after{padding:0 0 0 4px;color:#999}#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after{content:"▼"}#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after{content:"▲"}#loco-admin.wrap .wp-list-table td.has-row-actions{overflow:visible}#loco-admin.wrap form.loco-filter{display:block;margin-bottom:5px}#loco-admin.wrap form.loco-filter .icon-filter{color:#999}#loco-admin.wrap nav.above-list-table{margin-bottom:1em}#loco-admin.wrap nav.above-list-table a{display:inline-block;margin-right:1em}#loco-admin.wrap .wp-core-ui button.inverted,#loco-admin.wrap .wp-core-ui button.inverted:hover,#loco-admin.wrap .po-fuzzy button.icon-cloud{background:-moz-linear-gradient(top, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);background:-webkit-linear-gradient(top, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);background:linear-gradient(to bottom, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);-webkit-box-shadow:0 1px 0 #fff;-moz-box-shadow:0 1px 0 #fff;box-shadow:0 1px 0 #fff;border-color:gray}#loco-admin.wrap .wp-core-ui button:active,#loco-admin.wrap .wp-core-ui button.inverted:active{border-color:#5b9dd9}#loco-admin.wrap .loco-clearable{display:inline-block;vertical-align:middle;position:relative}#loco-admin.wrap .loco-clearable a.clear,#loco-admin.wrap .auto-comp-wrap a.clear{top:0;right:0;outline:none;margin:0;border:solid 1px transparent;padding:5px 5px;position:absolute;font-size:1em;line-height:normal}#loco-admin.wrap .loco-clearable a.clear:before,#loco-admin.wrap .auto-comp-wrap a.clear:before{vertical-align:middle;padding:0;color:#999}#loco-admin.wrap .loco-clearable a.clear:hover:before,#loco-admin.wrap .auto-comp-wrap a.clear:hover:before{color:#333}#loco-admin.wrap .loco-clearable a.clear span,#loco-admin.wrap .auto-comp-wrap a.clear span{display:none}#loco-admin.wrap .loco-clearable ::-ms-clear,#loco-admin.wrap .auto-comp-wrap ::-ms-clear{display:none}#loco-admin.wrap div.progress{color:#000;background:transparent !important}#loco-admin.wrap div.progress *{height:100%;overflow:hidden;white-space:nowrap}#loco-admin.wrap div.progress .t{background-color:#ddd;border:1px solid #ccc}#loco-admin.wrap div.progress .t .bar{float:left;clear:none;background-color:#3db63d}#loco-admin.wrap div.progress .t .bar.f{background-color:#bd2c00}#loco-admin.wrap div.progress .l{display:block}#loco-admin.wrap td div.progress .t{border:none}#loco-admin.wrap td div.progress .l{display:none}#loco-admin.wrap code.path{color:#333;margin:0;padding:0;display:inline;background:transparent}#loco-admin.wrap .loco-danger{color:#d54e21}#loco-admin.wrap .notice,#loco-admin.wrap .panel{background:#fff;position:relative;margin:1em 0;padding:1px 12px}#loco-admin.wrap .notice-generic{border-color:#ddd}#loco-admin.wrap .notice-success>.has-icon,#loco-admin.wrap .notice-success p>strong.has-icon{color:#000}#loco-admin.wrap .notice-warning{border-color:orange}#loco-admin.wrap .notice-error{border-color:#dc3232}#loco-admin.wrap .notice-debug{border-color:#00a0d2}#loco-admin.wrap .notice-danger{border-color:#dc3232}#loco-admin.wrap .notice-locked{border-color:orange}#loco-admin.wrap .notice>.has-icon:before,#loco-admin.wrap .notice p>strong.has-icon:before{padding-right:6px}#loco-admin.wrap .notice>p>a.button.has-icon:before{width:1.2em}#loco-admin.wrap .notice>p>em{color:#d54e21;font-style:normal}#loco-admin.wrap .notice>p>em a{color:inherit}#loco-admin.wrap .notice>p a:hover,#loco-admin.wrap .notice>nav a:hover{text-decoration:underline}#loco-admin.wrap .notice>p a.button,#loco-admin.wrap .notice>nav a.button{text-decoration:inherit}#loco-admin.wrap .notice.has-nav{display:flex;flex-direction:row}#loco-admin.wrap .notice.has-nav p,#loco-admin.wrap .notice.has-nav nav{line-height:22px;flex-grow:1}#loco-admin.wrap .notice.has-nav nav{text-align:right;padding:2px;margin:.5em 0}#loco-admin.wrap .notice.has-nav.is-dismissible{padding-right:38px}#loco-admin.wrap .notice.has-nav a{white-space:nowrap}#loco-admin.wrap .notice.has-nav nav>span{color:#666}#loco-admin.wrap .notice>h3>span{display:inline-block;vertical-align:middle}#loco-admin.wrap ul.problems li{font-style:italic}#loco-admin.wrap label{position:relative}#loco-admin.wrap label.for-disabled,#loco-admin.wrap label.for-disabled>input{cursor:default !important}#loco-admin.wrap input.regular-text,#loco-admin.wrap textarea.regular-text{width:25em}#loco-admin.wrap .button-link{padding:0 10px 1px}#loco-admin.wrap .button-danger{background:#ba0000;border-color:#900 #600 #600;-webkit-box-shadow:0 1px 0 #600;-moz-box-shadow:0 1px 0 #600;box-shadow:0 1px 0 #600;color:#fff;text-shadow:0 -1px 1px #600,1px 0 1px #600,0 1px 1px #600,-1px 0 1px #600}#loco-admin.wrap .button-success{background:#00b500;border-color:#090 #2e892e #2e892e;-webkit-box-shadow:0 1px 0 #2e892e;-moz-box-shadow:0 1px 0 #2e892e;box-shadow:0 1px 0 #2e892e;color:#fff;text-shadow:0 -1px 1px #2e892e,1px 0 1px #2e892e,0 1px 1px #2e892e,-1px 0 1px #2e892e}#loco-admin.wrap .button-success:hover{background:#3db63d}#loco-admin.wrap .button-danger[disabled],#loco-admin.wrap .button-success[disabled]{text-shadow:none !important}#loco-admin.wrap form button.loco-loading.button-large{padding-left:0}#loco-admin.wrap form button.loco-loading.button-large:before{width:16px;height:16px;margin:0 4px;content:" ";font-size:16px;line-height:1;display:inline-block;vertical-align:sub}#loco-admin.wrap ::placeholder{color:#ccc}#loco-admin.wrap ::-webkit-input-placeholder{color:#ccc}#loco-admin.wrap :-moz-placeholder{color:#ccc;opacity:1}#loco-admin.wrap ::-moz-placeholder{color:#ccc;opacity:1}#loco-admin.wrap :-ms-input-placeholder{color:#ccc}#loco-admin.wrap .ielt10 .placeheld{color:#ccc}#loco-admin.wrap a.has-raquo:after{content:" »"}#loco-admin.wrap a.has-laquo:before{content:"« "}#loco-admin.wrap span.inline-spinner{display:inline-block;min-width:16px;min-height:16px;background:transparent url(../img/spin-modal.gif?v=2.5.8) 0 0 no-repeat}.js #wpbody-content>.notice{display:none}.js #wpbody-content>.notice.inline{display:block}.js #loco-admin.wrap .jshide,.no-js #loco-admin.wrap .jsonly{display:none !important}#loco-admin.wrap .invis{visibility:hidden}.form-table tr td{vertical-align:top}.form-table tr.compact td{padding-top:0}.form-table tr th a.icon-help{display:none}.loco-modal{min-width:50%;min-height:100px}.loco-modal-wide{min-width:90% !important}.loco-modal-no-close .ui-dialog-titlebar-close{display:none}.loco-modal .ui-dialog-titlebar-close{overflow:hidden}.loco-modal.request-filesystem-credentials-dialog{top:15% !important;max-height:85% !important}.loco-modal.request-filesystem-credentials-dialog>.ui-dialog-content{background:inherit}.loco-modal.request-filesystem-credentials-dialog .ftp-password>label>em:last-child{display:none}.ui-dialog-content>div.loco-loading{height:100%;background:transparent url(../img/spin-modal.gif?v=2.5.8) center 20px no-repeat}#loco-po-ref ol li{color:#aaa;margin:0;white-space:pre;padding:0 0 0 1em;font:normal 12px/17px Consolas,Monaco,monospace;background:transparent;border-left:1px solid #eee}#loco-po-ref ol li code{margin:0;padding:0;display:inline;background:inherit}#loco-po-ref ol li.highlighted{color:#666;background-color:#f8eec7}#loco-po-ref ol li.highlighted code.T_CONSTANT_ENCAPSED_STRING{color:#c931c7}#loco-credit>*{vertical-align:middle}#loco-credit>a{display:inline-block;position:relative;overflow:hidden;background:transparent url(../img/logo-foot.gif?v=2.5.8) 0 0 no-repeat;height:30px;width:100px;text-indent:200px;-webkit-transition-duration:0s;transition-duration:0s}#loco-credit>a:hover{background-position:0 -35px}#loco-content{position:relative}#footer-upgrade span:before{color:#ccc;content:" | ";display:inline;padding-left:.5em;padding-right:.5em}#footer-upgrade span:first-child:before{content:"";display:none}.loco-clearfix:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}dl.debug dt{font-weight:bold}dl.debug dt,dl.debug dd{white-space:pre}.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(0,115,170,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#0073aa;foo:#0073aa}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#66c6e4 !important;background:#008ec2 !important;border-color:#008ec2 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../img/skins/fresh/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.6.0) 0 0 no-repeat;min-height:75px}._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.6.0);background-size:16px}._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.6.0);background-size:16px}}._green_glow_inner{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}.loco-font,#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after,#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@font-face{font-family:"loco";src:url("../font/loco.eot?v=2.6.0");src:url("../font/loco.eot?v=2.6.0?#iefix") format("embedded-opentype"),url("../font/loco.woff?v=2.6.0") format("woff"),url("../font/loco.ttf?v=2.6.0") format("truetype"),url("../font/loco.svg?v=2.6.0#loco") format("svg");font-weight:normal;font-style:normal}.tipsy{font-size:11px;position:absolute;padding:5px;z-index:500001;opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.tipsy.in{opacity:1}.tipsy-inner{background-color:#000;color:#fff;white-space:nowrap;padding:6px 8px;line-height:1.3em;text-align:center;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-font-smoothing:subpixel-antialiased}.tipsy-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.tipsy-n .tipsy-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-nw .tipsy-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-ne .tipsy-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.tipsy-s .tipsy-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-sw .tipsy-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-se .tipsy-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.tipsy-e .tipsy-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.tipsy-w .tipsy-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}#loco-admin.wrap .selector li,#loco-admin.wrap .selector .handle,#loco-admin.wrap .selectoradd a,#loco-admin.wrap .selectorsep:before,#loco-admin.wrap .selectorsep span{padding:.3em .75em}#loco-admin.wrap .selector{text-align:left;display:inline-block;white-space:nowrap}#loco-admin.wrap .selectoradd a,#loco-admin.wrap .selector .handle{cursor:default;display:block;position:relative;border-top:solid 1px #fff;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd;border-left:solid 1px #fff;color:#666;height:1.3em;overflow:hidden;white-space:normal}#loco-admin.wrap .selectorsep{display:inline-block;border:solid 1px transparent}#loco-admin.wrap .selectorsep:before{display:block;position:relative;color:#999;height:1.3em;overflow:hidden}#loco-admin.wrap .selectorsep>*{display:block;line-height:1em;color:#666;height:1.3em;overflow:hidden}#loco-admin.wrap .selector .handle{outline:none;white-space:nowrap;padding-right:2.3em;max-width:250px;text-overflow:ellipsis}#loco-admin.wrap .selector .handle .prefix{padding-right:.6ex}#loco-admin.wrap .selector .handle:after{font-family:loco;font-size:1.3em;color:#ccc;display:block;position:absolute;top:.25em;right:.6em;content:"▼"}#loco-admin.wrap .selector .handle:focus:after,#loco-admin.wrap .selector .handle:hover:after{color:#666}#loco-admin.wrap .selector.no-caret .handle{padding-right:.75em}#loco-admin.wrap .selector.no-caret .handle:after{display:none}#loco-admin.wrap .selector.no-title .handle{padding-left:.5em;padding-right:.5em}#loco-admin.wrap .selector.no-title .handle .label{display:none}#loco-admin.wrap .selector.no-title .handle .icon{margin-right:0px}#loco-admin.wrap .selector.dummy .handle{border-color:transparent}#loco-admin.wrap .selector.dummy .handle:after{display:none}#loco-admin.wrap .selectoradd{position:relative}#loco-admin.wrap .selectoradd>*{display:block;float:left;clear:none}#loco-admin.wrap .selectoradd>a.has-icon{width:1.3em}#loco-admin.wrap .selectoradd>a.has-icon:before{color:#999;display:inline;padding-left:0;padding-right:0;line-height:1.4em}#loco-admin.wrap .selectoradd>a.has-icon:hover:after{color:#2e892e}#loco-admin.wrap .selectorsep{display:inline-block}#loco-admin.wrap .selectorsep span{color:#666;height:1.3em}#loco-admin.wrap .selector ul{padding:0}#loco-admin.wrap .selector ul,#loco-admin.wrap .selector li{display:block;position:relative;cursor:default;margin:0}#loco-admin.wrap .selector ul{z-index:5;position:absolute;left:0;top:0;background:#f5f5f5;box-shadow:0 10px 5px rgba(0,0,0,.2);border:solid 1px #ccc;overflow:auto}#loco-admin.wrap .selector.up ul{margin-top:0}#loco-admin.wrap .selector.multi li input{display:none}#loco-admin.wrap .selector.multi li.checked{background:#e5e5e5}#loco-admin.wrap .selector li.active{background:#e5e5e5 !important}#loco-admin.wrap .selector li.over{background:#ccc !important;color:#fff;text-shadow:1px 1px #aaa}#loco-admin.wrap .selector li.over .label{color:#fff}#loco-admin.wrap .selector .label{font:inherit;color:inherit}#loco-admin.wrap .selector .icon{display:inline-block;min-width:1.2em;text-align:center;font-size:14px}#loco-admin.wrap .selector .icon.no-icon{display:none}#loco-admin.wrap .selector .icon:before{color:#666}#loco-admin.wrap .selector .avtr{width:18px;height:18px;background-size:18px;background-repeat:no-repeat}#loco-admin.wrap .selector .label{line-height:1}#loco-admin.wrap .selector .icon,#loco-admin.wrap .selector .icon-16{vertical-align:bottom}#loco-admin.wrap .selector .icon,#loco-admin.wrap .selector .lang,#loco-admin.wrap .selector .icon-16{margin-right:5px}#loco-admin.wrap .selector .region,#loco-admin.wrap .selector .variant-wales,#loco-admin.wrap .selector .region-gb.lang-cy,#loco-admin.wrap .selector .variant-scotland,#loco-admin.wrap .selector .region-gb.lang-gd,#loco-admin.wrap .selector .variant-valencia,#loco-admin.wrap .selector .region-es.variant-valencia,#loco-admin.wrap .selector .lang-ca,#loco-admin.wrap .selector .region-es.lang-ca,#loco-admin.wrap .selector .lang-eo,#loco-admin.wrap .selector .lang-eu{margin-left:2px;margin-right:7px}#loco-admin.wrap .selector.ticked .icon.no-icon{font-size:12px;display:inline-block}#loco-admin.wrap .selector.ticked .active .icon.no-icon:before{content:"✓"}#loco-admin.wrap .selectoradd a:hover,#loco-admin.wrap .selector a.handle:focus,#loco-admin.wrap .selector a.handle:hover{color:#000;border-color:#999}#loco-admin.wrap .selector.active .handle{border-color:#999;background-color:#eee;color:#999}#loco-admin.wrap .selector.active .handle:after{color:#999;content:"▲"}#loco-admin.wrap .selector.disabled{cursor:default;cursor:no-drop;cursor:not-allowed}#loco-admin.wrap .selector.disabled .handle{pointer-events:none;border-top:solid 1px #fff;border-right:solid 1px #ddd;border-bottom:solid 1px #ddd;border-left:solid 1px #fff;color:#999;padding-right:1em}#loco-admin.wrap .selector.disabled .handle:after{display:none}#loco-admin.wrap .selector.disabled .handle span.icon{color:#999 !important}#loco-admin.wrap .selector li.disabled,#loco-admin.wrap .selector li.disabled.over{color:#aaa;text-shadow:1px 1px #fff;pointer-events:none}#loco-admin.wrap .selector li.disabled *{cursor:text}#loco-admin.wrap .selector li.disabled .icon:before{color:#aaa}#loco-admin.wrap .selector li.disabled .flag,#loco-admin.wrap .selector li.disabled .icon-16{opacity:.4}#loco-admin.wrap .selector.lefty ul{left:auto;right:0}#loco-admin.wrap .selector.lefty ul .icon,#loco-admin.wrap .selector.lefty ul .icon-32{display:block;float:right;clear:none}#loco-admin.wrap .selector.lefty ul .label{padding-right:32px;padding-left:0}#loco-admin.wrap .selector ul>form{margin:0;display:block}#loco-admin.wrap .selector ul>form input{margin:0;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0}#loco-admin.wrap .selector ul>form input:focus{-webkit-box-shadow:inset 0 0 5px 0 #3db63d;-moz-box-shadow:inset 0 0 5px 0 #3db63d;box-shadow:inset 0 0 5px 0 #3db63d}#loco-admin.wrap .selector ul>form input.error{border-color:#c00;-webkit-box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5);-moz-box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5);box-shadow:inset 0 0 5px 0 rgba(153,0,0,.5)}#loco-admin.wrap .selector ul>form a.clear{margin:0;border:none}#loco-admin.wrap .selector ul>form ::placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap .selector ul>form ::-webkit-input-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap .selector ul>form :-moz-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block;opacity:1}#loco-admin.wrap .selector ul>form ::-moz-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block;opacity:1}#loco-admin.wrap .selector ul>form :-ms-input-placeholder{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap .selector ul>form .ielt10 .placeheld{color:gray;font-size:16px;font-family:"loco";text-align:right;display:block}#loco-admin.wrap div.auto-comp-wrap{width:100%}#loco-admin.wrap div.auto-comp-wrap input{display:inline-block}#loco-admin.wrap div.auto-comp-wrap.loading input{background:transparent url(../img/ajax-loader.gif?v=2.6.0) right 2px no-repeat}#loco-admin.wrap div.auto-comp-drop{color:#333;background:#fff;border-top:none;position:absolute;width:auto;top:0;left:0;z-index:99;-webkit-box-shadow:0 5px 5px rgba(0,0,0,.4);-moz-box-shadow:0 5px 5px rgba(0,0,0,.4);box-shadow:0 5px 5px rgba(0,0,0,.4)}#loco-admin.wrap div.auto-comp-result{padding:5px 10px;cursor:pointer;background:#f0f0f0;border-top:solid 1px #fff;border-bottom:solid 1px #ddd;white-space:nowrap}#loco-admin.wrap div.auto-comp-result:first-child{border-top:solid 1px #ddd}#loco-admin.wrap div.auto-comp-result>*{display:inline-block;vertical-align:middle;line-height:normal}#loco-admin.wrap div.auto-comp-result .icon:before{padding-right:5px}#loco-admin.wrap div.auto-comp-result:hover{background:#a8a8a8;color:#fff;border-top-color:#a8a8a8;border-bottom-color:#999}#loco-admin.wrap div.auto-comp-result.selected{background:#666 !important;color:#fff;border-top-color:#666;border-bottom-color:#666}#loco-admin.wrap div.auto-comp-result .lang,#loco-admin.wrap div.auto-comp-result .region,#loco-admin.wrap div.auto-comp-result .variant-wales,#loco-admin.wrap div.auto-comp-result .region-gb.lang-cy,#loco-admin.wrap div.auto-comp-result .variant-scotland,#loco-admin.wrap div.auto-comp-result .region-gb.lang-gd,#loco-admin.wrap div.auto-comp-result .variant-valencia,#loco-admin.wrap div.auto-comp-result .region-es.variant-valencia,#loco-admin.wrap div.auto-comp-result .lang-ca,#loco-admin.wrap div.auto-comp-result .region-es.lang-ca,#loco-admin.wrap div.auto-comp-result .lang-eo,#loco-admin.wrap div.auto-comp-result .lang-eu,#loco-admin.wrap div.auto-comp-result .avtr{margin-right:5px}#loco-admin.wrap div.auto-comp-wrap.error a.icon.clear:before{color:#c00;opacity:1}#loco-admin.wrap div.auto-comp-wrap.error input[type=text]{border-color:#c00;color:#c00}#loco-admin.wrap div.auto-comp-wrap.error input[type=text]:focus{-webkit-box-shadow:0 0 .5em 0 rgba(153,0,0,.5);-moz-box-shadow:0 0 .5em 0 rgba(153,0,0,.5);box-shadow:0 0 .5em 0 rgba(153,0,0,.5)}#loco-admin.wrap ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}#loco-admin.wrap ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.6.0) 0 0 no-repeat;min-height:75px}#loco-admin.wrap ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-admin.wrap ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.6.0);background-size:16px}#loco-admin.wrap ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.6.0);background-size:16px}}#loco-admin.wrap ._green_glow_inner{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-admin.wrap ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-admin.wrap .loco-font,#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after,#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-admin.wrap .has-icon:before{display:inline-block;padding-right:.3em}#loco-admin.wrap a.icon-help{cursor:help}#loco-admin.wrap a.icon-help span{display:none}#loco-admin.wrap .icon-share:before{content:"↑"}#loco-admin.wrap .icon-notag:before{content:""}#loco-admin.wrap .icon-magnify:before{content:"🔍"}#loco-admin.wrap .icon-python:before{content:"🐍"}#loco-admin.wrap .icon-unicode:before{content:"u"}#loco-admin.wrap .icon-json:before{content:"{"}#loco-admin.wrap .icon-bullist:before{content:""}#loco-admin.wrap .icon-numlist:before{content:""}#loco-admin.wrap .icon-indent:before{content:""}#loco-admin.wrap .icon-outdent:before{content:""}#loco-admin.wrap .icon-link:before{content:""}#loco-admin.wrap .icon-unlink:before{content:""}#loco-admin.wrap .icon-bold:before{content:"B"}#loco-admin.wrap .icon-italic:before{content:"I"}#loco-admin.wrap .icon-translate:before{content:""}#loco-admin.wrap .icon-proj:before{content:""}#loco-admin.wrap .icon-plural:before{content:"᛬"}#loco-admin.wrap .icon-max:before,#loco-admin.wrap .icon-full-screen:before{content:""}#loco-admin.wrap .icon-min:before{content:""}#loco-admin.wrap .icon-sort:before{content:""}#loco-admin.wrap .icon-ok:before,#loco-admin.wrap .notice-success>.has-icon:before,#loco-admin.wrap .notice-success p>strong.has-icon:before{content:"✓"}#loco-admin.wrap .icon-ok-empty:before{content:"🗌"}#loco-admin.wrap .icon-checkbox-checked:before,#loco-admin.wrap .selector.multi li.checked .icon-checkbox:before{content:"☑"}#loco-admin.wrap .icon-checkbox-unchecked:before{content:"☐"}#loco-admin.wrap .icon-checkbox-partial:before{content:"☉"}#loco-admin.wrap .icon-radio-checked:before{content:"⚫"}#loco-admin.wrap .icon-radio-unchecked:before{content:"⚪"}#loco-admin.wrap .icon-ext:before{content:"⬈"}#loco-admin.wrap .icon-star:before{content:""}#loco-admin.wrap .icon-user:before{content:""}#loco-admin.wrap .icon-remove:before,#loco-admin.wrap a.icon.close:before{content:"×"}#loco-admin.wrap .icon-cog:before{content:""}#loco-admin.wrap .icon-trash:before{content:""}#loco-admin.wrap .icon-time:before,#loco-admin.wrap .icon-history:before{content:""}#loco-admin.wrap .icon-download:before{content:""}#loco-admin.wrap .icon-revert:before{content:""}#loco-admin.wrap .icon-sync:before{content:""}#loco-admin.wrap .icon-lock:before,#loco-admin.wrap .notice-locked>.has-icon:before,#loco-admin.wrap .notice-locked p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-flag:before{content:""}#loco-admin.wrap .icon-tag:before{content:""}#loco-admin.wrap .icon-tags:before{content:""}#loco-admin.wrap .icon-print:before{content:""}#loco-admin.wrap .icon-camera:before{content:""}#loco-admin.wrap .icon-pencil:before{content:""}#loco-admin.wrap .icon-add:before{content:""}#loco-admin.wrap .icon-del:before{content:""}#loco-admin.wrap .icon-clear:before,#loco-admin.wrap a.icon.clear:before{content:""}#loco-admin.wrap .icon-ok-sign:before{content:"✔"}#loco-admin.wrap .icon-help:before{content:"?"}#loco-admin.wrap .icon-info:before,#loco-admin.wrap .notice-info>.has-icon:before,#loco-admin.wrap .notice-info p>strong.has-icon:before{content:"ℹ"}#loco-admin.wrap .icon-cancel:before{content:""}#loco-admin.wrap .icon-warn:before,#loco-admin.wrap .notice-error>.has-icon:before,#loco-admin.wrap .notice-error p>strong.has-icon:before,#loco-admin.wrap .notice-warning>.has-icon:before,#loco-admin.wrap .notice-warning p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-comment:before{content:""}#loco-admin.wrap .icon-bar-chart:before{content:""}#loco-admin.wrap .icon-key:before{content:""}#loco-admin.wrap .icon-cogs:before{content:""}#loco-admin.wrap .icon-comments:before{content:""}#loco-admin.wrap .icon-signout:before{content:""}#loco-admin.wrap .icon-signin:before{content:""}#loco-admin.wrap .icon-upload:before{content:""}#loco-admin.wrap .icon-twitter:before{content:"🐦"}#loco-admin.wrap .icon-facebook:before{content:""}#loco-admin.wrap .icon-github:before{content:""}#loco-admin.wrap .icon-feed:before{content:""}#loco-admin.wrap .icon-globe:before{content:""}#loco-admin.wrap .icon-wrench:before,#loco-admin.wrap .notice-debug>.has-icon:before,#loco-admin.wrap .notice-debug p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-group:before{content:""}#loco-admin.wrap .icon-cloud:before{content:""}#loco-admin.wrap .icon-copy:before{content:""}#loco-admin.wrap .icon-save:before{content:""}#loco-admin.wrap .icon-menu:before{content:""}#loco-admin.wrap .icon-table:before{content:""}#loco-admin.wrap .icon-caret-down:before{content:"▼"}#loco-admin.wrap .icon-caret-up:before{content:"▲"}#loco-admin.wrap .icon-caret-right:before{content:"▶"}#loco-admin.wrap .icon-mail:before{content:""}#loco-admin.wrap .icon-cloud-upload:before{content:""}#loco-admin.wrap .icon-file:before{content:""}#loco-admin.wrap .icon-circle-white:before{content:"⚬"}#loco-admin.wrap .icon-circle-black:before{content:"●"}#loco-admin.wrap .icon-eraser:before{content:""}#loco-admin.wrap .icon-unlock:before{content:""}#loco-admin.wrap .icon-apple:before{content:""}#loco-admin.wrap .icon-android:before{content:""}#loco-admin.wrap .icon-robot:before{content:"🤖"}#loco-admin.wrap .icon-back:before{content:"⬅"}#loco-admin.wrap .icon-next:before{content:"➔"}#loco-admin.wrap .icon-arrow-up:before{content:""}#loco-admin.wrap .icon-calendar:before{content:""}#loco-admin.wrap .icon-ccard:before{content:""}#loco-admin.wrap .icon-caret-left:before{content:"◀"}#loco-admin.wrap .icon-pro:before{content:"⚡"}#loco-admin.wrap .icon-bell:before{content:""}#loco-admin.wrap .icon-code:before{content:""}#loco-admin.wrap .icon-privacy:before{content:"🛡"}#loco-admin.wrap .icon-hellip:before{content:"…"}#loco-admin.wrap .icon-vellip:before{content:"⁞"}#loco-admin.wrap .icon-collapse:before{content:""}#loco-admin.wrap .icon-expand:before{content:""}#loco-admin.wrap .icon-wordpress:before{content:""}#loco-admin.wrap .icon-database:before{content:""}#loco-admin.wrap .icon-restore:before{content:""}#loco-admin.wrap .icon-pilcrow:before{content:"¶"}#loco-admin.wrap .icon-status.is-translated:before,#loco-admin.wrap .is-translated>header>.icon-status:before{color:#2e892e;content:"✓";text-align:center}#loco-admin.wrap .icon-status.is-untranslated:before,#loco-admin.wrap .is-untranslated>header>.icon-status:before{color:#aaa;content:"×";text-align:center;font-size:1.1em}#loco-admin.wrap .icon-status.is-flagged:before,#loco-admin.wrap .is-flagged>header>.icon-status:before{color:#bd2c00;content:"";text-align:center}#loco-admin.wrap .icon-status.is-translated.is-blank:before,#loco-admin.wrap .icon-status.is-translated.is-inherit:before,#loco-admin.wrap .is-translated.is-blank>header>.icon-status:before,#loco-admin.wrap .is-translated.is-inherit>header>.icon-status:before{content:"🗌"}#loco-admin.wrap .icon-status.is-fuzzy:before,#loco-admin.wrap .is-fuzzy>header>.icon-status:before{color:#666;content:""}#loco-admin.wrap .lang,#loco-admin.wrap .region,#loco-admin.wrap .variant-wales,#loco-admin.wrap .region-gb.lang-cy,#loco-admin.wrap .variant-scotland,#loco-admin.wrap .region-gb.lang-gd,#loco-admin.wrap .variant-valencia,#loco-admin.wrap .region-es.variant-valencia,#loco-admin.wrap .lang-ca,#loco-admin.wrap .region-es.lang-ca,#loco-admin.wrap .lang-eo,#loco-admin.wrap .lang-eu{color:#fff;background:#2e892e;display:inline-block;text-transform:uppercase;overflow:hidden;font-family:Verdana,Arial,sans-serif;font-size:9px;font-weight:normal;font-style:normal;line-height:12px;text-align:center;white-space:normal;text-shadow:none}#loco-admin.wrap .lang{width:20px;height:12px;line-height:12px;vertical-align:middle}#loco-admin.wrap .lang:before{content:attr(lang);vertical-align:baseline}#loco-admin.wrap .no-lang{width:18px;height:10px;border:solid 1px #2e892e;background:transparent}#loco-admin.wrap .lang-el{background-color:#1d48a3}#loco-admin.wrap .lang-el:before{content:"Ελ"}#loco-admin.wrap .region,#loco-admin.wrap .variant-wales,#loco-admin.wrap .region-gb.lang-cy,#loco-admin.wrap .variant-scotland,#loco-admin.wrap .region-gb.lang-gd,#loco-admin.wrap .variant-valencia,#loco-admin.wrap .region-es.variant-valencia,#loco-admin.wrap .lang-ca,#loco-admin.wrap .region-es.lang-ca,#loco-admin.wrap .lang-eo,#loco-admin.wrap .lang-eu{width:16px;height:12px;margin:0 2px;background-image:url(../img/flags.png?v=2.6.0);background-repeat:no-repeat;background-color:transparent}#loco-admin.wrap .region:before,#loco-admin.wrap .variant-wales:before,#loco-admin.wrap .region-gb.lang-cy:before,#loco-admin.wrap .variant-scotland:before,#loco-admin.wrap .region-gb.lang-gd:before,#loco-admin.wrap .variant-valencia:before,#loco-admin.wrap .region-es.variant-valencia:before,#loco-admin.wrap .lang-ca:before,#loco-admin.wrap .region-es.lang-ca:before,#loco-admin.wrap .lang-eo:before,#loco-admin.wrap .lang-eu:before{visibility:hidden}#loco-admin.wrap .lang-zh{background-color:#b90000}#loco-admin.wrap .lang-zh.script-hans:before{content:"中国"}#loco-admin.wrap .lang-zh.script-hant:before{content:"中國"}#loco-admin.wrap .__{background-position:0 0}#loco-admin.wrap .lang-eo{background-position:0 -12px}#loco-admin.wrap .lang-eu{background-position:0 -24px}#loco-admin.wrap .lang-ca,#loco-admin.wrap .region-es.lang-ca{background-position:0 -36px}#loco-admin.wrap .region-tg{background-position:0 -48px}#loco-admin.wrap .region-me{background-position:0 -60px}#loco-admin.wrap .region-la{background-position:0 -73px}#loco-admin.wrap .region-mr{background-position:0 -85px}#loco-admin.wrap .region-ni{background-position:0 -97px}#loco-admin.wrap .region-lv{background-position:0 -109px}#loco-admin.wrap .region-om{background-position:0 -121px}#loco-admin.wrap .region-af{background-position:0 -133px}#loco-admin.wrap .region-cy{background-position:0 -145px}#loco-admin.wrap .region-bj{background-position:0 -157px}#loco-admin.wrap .region-aq{background-position:0 -169px}#loco-admin.wrap .region-cn{background-position:0 -186px}#loco-admin.wrap .region-co{background-position:0 -198px}#loco-admin.wrap .region-cx{background-position:0 -210px}#loco-admin.wrap .region-ag{background-position:0 -222px}#loco-admin.wrap .region-ms{background-position:0 -234px}#loco-admin.wrap .region-md{background-position:0 -246px}#loco-admin.wrap .region-zm{background-position:0 -258px}#loco-admin.wrap .region-vn{background-position:0 -270px}#loco-admin.wrap .region-tf{background-position:0 -282px}#loco-admin.wrap .region-td{background-position:0 -294px}#loco-admin.wrap .region-yt{background-position:0 -306px}#loco-admin.wrap .region-lb{background-position:0 -318px}#loco-admin.wrap .region-mf{background-position:0 -330px}#loco-admin.wrap .region-lu{background-position:0 -347px}#loco-admin.wrap .region-mq{background-position:0 -359px}#loco-admin.wrap .region-cz{background-position:0 -371px}#loco-admin.wrap .region-ae{background-position:0 -383px}#loco-admin.wrap .region-cm{background-position:0 -395px}#loco-admin.wrap .region-bi{background-position:0 -407px}#loco-admin.wrap .region-ar{background-position:0 -419px}#loco-admin.wrap .region-as{background-position:0 -431px}#loco-admin.wrap .region-bh{background-position:0 -443px}#loco-admin.wrap .region-cl{background-position:0 -455px}#loco-admin.wrap .region-ad{background-position:0 -467px}#loco-admin.wrap .region-mp{background-position:0 -479px}#loco-admin.wrap .region-lt{background-position:0 -491px}#loco-admin.wrap .region-mg{background-position:0 -503px}#loco-admin.wrap .region-lc{background-position:0 -515px}#loco-admin.wrap .region-tr{background-position:0 -527px}#loco-admin.wrap .region-ua{background-position:0 -539px}#loco-admin.wrap .region-tv{background-position:0 -551px}#loco-admin.wrap .region-vi{background-position:0 -563px}#loco-admin.wrap .region-mt{background-position:0 -575px}#loco-admin.wrap .region-no{background-position:0 -587px}#loco-admin.wrap .region-mc{background-position:0 -599px}#loco-admin.wrap .region-ch{background-position:0 -611px}#loco-admin.wrap .region-bl{background-position:0 -623px}#loco-admin.wrap .region-aw{background-position:0 -640px}#loco-admin.wrap .region-bz{background-position:0 -652px}#loco-admin.wrap .region-bm{background-position:0 -664px}#loco-admin.wrap .region-ci{background-position:0 -676px}#loco-admin.wrap .region-mu{background-position:0 -688px}#loco-admin.wrap .region-us{background-position:0 -700px}#loco-admin.wrap .region-tw{background-position:0 -712px}#loco-admin.wrap .region-ye{background-position:0 -724px}#loco-admin.wrap .region-mw{background-position:0 -736px}#loco-admin.wrap .region-nl{background-position:0 -748px}#loco-admin.wrap .region-ls{background-position:0 -760px}#loco-admin.wrap .region-bo{background-position:0 -772px}#loco-admin.wrap .region-at{background-position:0 -784px}#loco-admin.wrap .region-ck{background-position:0 -796px}#loco-admin.wrap .region-by{background-position:0 -808px}#loco-admin.wrap .region-au{background-position:0 -820px}#loco-admin.wrap .region-bn{background-position:0 -832px}#loco-admin.wrap .region-ma{background-position:0 -844px}#loco-admin.wrap .region-nz{background-position:0 -856px}#loco-admin.wrap .region-lr{background-position:0 -868px}#loco-admin.wrap .region-mv{background-position:0 -880px}#loco-admin.wrap .region-tc{background-position:0 -892px}#loco-admin.wrap .region-ug{background-position:0 -904px}#loco-admin.wrap .region-tt{background-position:0 -916px}#loco-admin.wrap .region-pl{background-position:0 -928px}#loco-admin.wrap .region-rs{background-position:0 -940px}#loco-admin.wrap .region-in{background-position:0 -952px}#loco-admin.wrap .region-ge{background-position:0 -964px}#loco-admin.wrap .region-gr{background-position:0 -976px}#loco-admin.wrap .region-gs{background-position:0 -988px}#loco-admin.wrap .region-gd{background-position:0 -1000px}#loco-admin.wrap .region-io{background-position:0 -1012px}#loco-admin.wrap .region-hk{background-position:0 -1024px}#loco-admin.wrap .region-kp{background-position:0 -1036px}#loco-admin.wrap .region-kg{background-position:0 -1048px}#loco-admin.wrap .region-pm{background-position:0 -1060px}#loco-admin.wrap .region-sv{background-position:0 -1072px}#loco-admin.wrap .region-re{background-position:0 -1084px}#loco-admin.wrap .region-sa{background-position:0 -1096px}#loco-admin.wrap .region-sc{background-position:0 -1108px}#loco-admin.wrap .region-st{background-position:0 -1120px}#loco-admin.wrap .region-ke{background-position:0 -1132px}#loco-admin.wrap .region-im{background-position:0 -1144px}#loco-admin.wrap .region-kr{background-position:0 -1161px}#loco-admin.wrap .region-gf{background-position:0 -1173px}#loco-admin.wrap .region-dj{background-position:0 -1185px}#loco-admin.wrap .region-gq{background-position:0 -1197px}#loco-admin.wrap .region-gp{background-position:0 -1209px}#loco-admin.wrap .region-dk{background-position:0 -1221px}#loco-admin.wrap .region-gg{background-position:0 -1233px}#loco-admin.wrap .region-il{background-position:0 -1250px}#loco-admin.wrap .region-pn{background-position:0 -1262px}#loco-admin.wrap .region-sb{background-position:0 -1274px}#loco-admin.wrap .region-py{background-position:0 -1286px}#loco-admin.wrap .region-ru{background-position:0 -1298px}#loco-admin.wrap .region-kw{background-position:0 -1310px}#loco-admin.wrap .region-do{background-position:0 -1322px}#loco-admin.wrap .region-gt{background-position:0 -1334px}#loco-admin.wrap .region-gb{background-position:0 -1346px}#loco-admin.wrap .region-gu{background-position:0 -1358px}#loco-admin.wrap .region-je{background-position:0 -1370px}#loco-admin.wrap .region-hm{background-position:0 -1387px}#loco-admin.wrap .region-sg{background-position:0 -1399px}#loco-admin.wrap .region-pk{background-position:0 -1411px}#loco-admin.wrap .region-sr{background-position:0 -1423px}#loco-admin.wrap .region-se{background-position:0 -1435px}#loco-admin.wrap .region-jp{background-position:0 -1447px}#loco-admin.wrap .region-gw{background-position:0 -1459px}#loco-admin.wrap .region-eh{background-position:0 -1471px}#loco-admin.wrap .region-dz{background-position:0 -1483px}#loco-admin.wrap .region-ga{background-position:0 -1495px}#loco-admin.wrap .region-fr{background-position:0 -1507px}#loco-admin.wrap .region-dm{background-position:0 -1519px}#loco-admin.wrap .region-hn{background-position:0 -1531px}#loco-admin.wrap .region-sd{background-position:0 -1543px}#loco-admin.wrap .region-rw{background-position:0 -1555px}#loco-admin.wrap .region-ph{background-position:0 -1567px}#loco-admin.wrap .region-ss{background-position:0 -1579px}#loco-admin.wrap .region-qa{background-position:0 -1596px}#loco-admin.wrap .region-pe{background-position:0 -1608px}#loco-admin.wrap .region-pr{background-position:0 -1620px}#loco-admin.wrap .region-si{background-position:0 -1632px}#loco-admin.wrap .region-ht{background-position:0 -1644px}#loco-admin.wrap .region-es{background-position:0 -1656px}#loco-admin.wrap .region-gl{background-position:0 -1668px}#loco-admin.wrap .region-gm{background-position:0 -1680px}#loco-admin.wrap .region-er{background-position:0 -1692px}#loco-admin.wrap .region-fi{background-position:0 -1704px}#loco-admin.wrap .region-ee{background-position:0 -1716px}#loco-admin.wrap .region-kn{background-position:0 -1728px}#loco-admin.wrap .region-hu{background-position:0 -1740px}#loco-admin.wrap .region-iq{background-position:0 -1752px}#loco-admin.wrap .region-ky{background-position:0 -1764px}#loco-admin.wrap .region-sh{background-position:0 -1776px}#loco-admin.wrap .region-ps{background-position:0 -1788px}#loco-admin.wrap .region-pf{background-position:0 -1800px}#loco-admin.wrap .region-sj{background-position:0 -1812px}#loco-admin.wrap .region-id{background-position:0 -1824px}#loco-admin.wrap .region-is{background-position:0 -1836px}#loco-admin.wrap .region-eg{background-position:0 -1848px}#loco-admin.wrap .region-fk{background-position:0 -1860px}#loco-admin.wrap .region-fj{background-position:0 -1872px}#loco-admin.wrap .region-gn{background-position:0 -1884px}#loco-admin.wrap .region-gy{background-position:0 -1896px}#loco-admin.wrap .region-ir{background-position:0 -1908px}#loco-admin.wrap .region-km{background-position:0 -1920px}#loco-admin.wrap .region-ie{background-position:0 -1932px}#loco-admin.wrap .region-kz{background-position:0 -1944px}#loco-admin.wrap .region-ro{background-position:0 -1956px}#loco-admin.wrap .region-sk{background-position:0 -1968px}#loco-admin.wrap .region-pg{background-position:0 -1980px}#loco-admin.wrap .region-pt{background-position:0 -1992px}#loco-admin.wrap .region-so{background-position:0 -2004px}#loco-admin.wrap .region-sx{background-position:0 -2016px}#loco-admin.wrap .region-hr{background-position:0 -2033px}#loco-admin.wrap .region-ki{background-position:0 -2045px}#loco-admin.wrap .region-jm{background-position:0 -2057px}#loco-admin.wrap .region-ec{background-position:0 -2069px}#loco-admin.wrap .region-et{background-position:0 -2081px}#loco-admin.wrap .region-fo{background-position:0 -2093px}#loco-admin.wrap .region-kh{background-position:0 -2105px}#loco-admin.wrap .region-sy{background-position:0 -2117px}#loco-admin.wrap .region-sn{background-position:0 -2129px}#loco-admin.wrap .region-pw{background-position:0 -2141px}#loco-admin.wrap .region-sl{background-position:0 -2153px}#loco-admin.wrap .region-fm{background-position:0 -2165px}#loco-admin.wrap .region-gi{background-position:0 -2177px}#loco-admin.wrap .region-de{background-position:0 -2189px}#loco-admin.wrap .region-gh{background-position:0 -2201px}#loco-admin.wrap .region-jo{background-position:0 -2213px}#loco-admin.wrap .region-it{background-position:0 -2225px}#loco-admin.wrap .region-pa{background-position:0 -2237px}#loco-admin.wrap .region-sz{background-position:0 -2249px}#loco-admin.wrap .region-sm{background-position:0 -2261px}#loco-admin.wrap .region-tn{background-position:0 -2273px}#loco-admin.wrap .region-ml{background-position:0 -2285px}#loco-admin.wrap .region-cg{background-position:0 -2297px}#loco-admin.wrap .region-ax{background-position:0 -2309px}#loco-admin.wrap .region-ao{background-position:0 -2321px}#loco-admin.wrap .region-bt{background-position:0 -2333px}#loco-admin.wrap .region-an{background-position:0 -2345px}#loco-admin.wrap .region-bb{background-position:0 -2357px}#loco-admin.wrap .region-cf{background-position:0 -2369px}#loco-admin.wrap .region-mm{background-position:0 -2381px}#loco-admin.wrap .region-li{background-position:0 -2393px}#loco-admin.wrap .region-na{background-position:0 -2405px}#loco-admin.wrap .region-mz{background-position:0 -2417px}#loco-admin.wrap .region-to{background-position:0 -2429px}#loco-admin.wrap .region-vg{background-position:0 -2441px}#loco-admin.wrap .region-ve{background-position:0 -2453px}#loco-admin.wrap .region-tz{background-position:0 -2465px}#loco-admin.wrap .region-tm{background-position:0 -2477px}#loco-admin.wrap .region-mx{background-position:0 -2489px}#loco-admin.wrap .region-nc{background-position:0 -2501px}#loco-admin.wrap .region-mo{background-position:0 -2513px}#loco-admin.wrap .region-lk{background-position:0 -2525px}#loco-admin.wrap .region-cd{background-position:0 -2537px}#loco-admin.wrap .region-al{background-position:0 -2549px}#loco-admin.wrap .region-bw{background-position:0 -2561px}#loco-admin.wrap .region-cs{background-position:0 -2573px}#loco-admin.wrap .region-cr{background-position:0 -2585px}#loco-admin.wrap .region-bv{background-position:0 -2597px}#loco-admin.wrap .region-am{background-position:0 -2609px}#loco-admin.wrap .region-az{background-position:0 -2621px}#loco-admin.wrap .region-ba{background-position:0 -2633px}#loco-admin.wrap .region-mn{background-position:0 -2645px}#loco-admin.wrap .region-nu{background-position:0 -2657px}#loco-admin.wrap .region-my{background-position:0 -2669px}#loco-admin.wrap .region-tl{background-position:0 -2681px}#loco-admin.wrap .region-ws{background-position:0 -2693px}#loco-admin.wrap .region-th{background-position:0 -2705px}#loco-admin.wrap .region-nf{background-position:0 -2717px}#loco-admin.wrap .region-ly{background-position:0 -2729px}#loco-admin.wrap .region-ai{background-position:0 -2741px}#loco-admin.wrap .region-br{background-position:0 -2753px}#loco-admin.wrap .region-cv{background-position:0 -2765px}#loco-admin.wrap .region-be{background-position:0 -2777px}#loco-admin.wrap .region-ca{background-position:0 -2789px}#loco-admin.wrap .region-bd{background-position:0 -2801px}#loco-admin.wrap .region-cw{background-position:0 -2813px}#loco-admin.wrap .region-bs{background-position:0 -2830px}#loco-admin.wrap .region-ng{background-position:0 -2842px}#loco-admin.wrap .region-mk{background-position:0 -2854px}#loco-admin.wrap .region-np{background-position:0 -2866px}#loco-admin.wrap .region-va{background-position:0 -2878px}#loco-admin.wrap .region-uz{background-position:0 -2890px}#loco-admin.wrap .region-um{background-position:0 -2902px}#loco-admin.wrap .region-tk{background-position:0 -2914px}#loco-admin.wrap .region-vc{background-position:0 -2926px}#loco-admin.wrap .region-zw{background-position:0 -2938px}#loco-admin.wrap .region-nr{background-position:0 -2950px}#loco-admin.wrap .region-ne{background-position:0 -2962px}#loco-admin.wrap .region-cu{background-position:0 -2974px}#loco-admin.wrap .region-bq{background-position:0 -2986px}#loco-admin.wrap .region-bf{background-position:0 -2998px}#loco-admin.wrap .region-bg{background-position:0 -3010px}#loco-admin.wrap .region-cc{background-position:0 -3022px}#loco-admin.wrap .region-mh{background-position:0 -3034px}#loco-admin.wrap .region-za{background-position:0 -3046px}#loco-admin.wrap .region-uy{background-position:0 -3058px}#loco-admin.wrap .region-wf{background-position:0 -3070px}#loco-admin.wrap .region-vu{background-position:0 -3082px}#loco-admin.wrap .region-tj{background-position:0 -3094px}#loco-admin.wrap .variant-scotland,#loco-admin.wrap .region-gb.lang-gd{background-position:0 -3106px}#loco-admin.wrap .variant-valencia,#loco-admin.wrap .region-es.variant-valencia{background-position:0 -3118px}#loco-admin.wrap .variant-wales,#loco-admin.wrap .region-gb.lang-cy{background-position:0 -3130px}#loco-admin.wrap .x-eu{background-position:0 -3142px}#loco-admin.wrap span.lang code{display:none}#loco-admin.wrap .icon-share:before{content:"↑"}#loco-admin.wrap .icon-notag:before{content:""}#loco-admin.wrap .icon-magnify:before{content:"🔍"}#loco-admin.wrap .icon-python:before{content:"🐍"}#loco-admin.wrap .icon-unicode:before{content:"u"}#loco-admin.wrap .icon-json:before{content:"{"}#loco-admin.wrap .icon-bullist:before{content:""}#loco-admin.wrap .icon-numlist:before{content:""}#loco-admin.wrap .icon-indent:before{content:""}#loco-admin.wrap .icon-outdent:before{content:""}#loco-admin.wrap .icon-link:before{content:""}#loco-admin.wrap .icon-unlink:before{content:""}#loco-admin.wrap .icon-bold:before{content:"B"}#loco-admin.wrap .icon-italic:before{content:"I"}#loco-admin.wrap .icon-translate:before{content:""}#loco-admin.wrap .icon-proj:before{content:""}#loco-admin.wrap .icon-plural:before{content:"᛬"}#loco-admin.wrap .icon-max:before,#loco-admin.wrap .icon-full-screen:before{content:""}#loco-admin.wrap .icon-min:before{content:""}#loco-admin.wrap .icon-sort:before{content:""}#loco-admin.wrap .icon-ok:before,#loco-admin.wrap .notice-success>.has-icon:before,#loco-admin.wrap .notice-success p>strong.has-icon:before{content:"✓"}#loco-admin.wrap .icon-ok-empty:before{content:"🗌"}#loco-admin.wrap .icon-checkbox-checked:before,#loco-admin.wrap .selector.multi li.checked .icon-checkbox:before{content:"☑"}#loco-admin.wrap .icon-checkbox-unchecked:before{content:"☐"}#loco-admin.wrap .icon-checkbox-partial:before{content:"☉"}#loco-admin.wrap .icon-radio-checked:before{content:"⚫"}#loco-admin.wrap .icon-radio-unchecked:before{content:"⚪"}#loco-admin.wrap .icon-ext:before{content:"⬈"}#loco-admin.wrap .icon-star:before{content:""}#loco-admin.wrap .icon-user:before{content:""}#loco-admin.wrap .icon-remove:before,#loco-admin.wrap a.icon.close:before{content:"×"}#loco-admin.wrap .icon-cog:before{content:""}#loco-admin.wrap .icon-trash:before{content:""}#loco-admin.wrap .icon-time:before,#loco-admin.wrap .icon-history:before{content:""}#loco-admin.wrap .icon-download:before{content:""}#loco-admin.wrap .icon-revert:before{content:""}#loco-admin.wrap .icon-sync:before{content:""}#loco-admin.wrap .icon-lock:before,#loco-admin.wrap .notice-locked>.has-icon:before,#loco-admin.wrap .notice-locked p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-flag:before{content:""}#loco-admin.wrap .icon-tag:before{content:""}#loco-admin.wrap .icon-tags:before{content:""}#loco-admin.wrap .icon-print:before{content:""}#loco-admin.wrap .icon-camera:before{content:""}#loco-admin.wrap .icon-pencil:before{content:""}#loco-admin.wrap .icon-add:before{content:""}#loco-admin.wrap .icon-del:before{content:""}#loco-admin.wrap .icon-clear:before,#loco-admin.wrap a.icon.clear:before{content:""}#loco-admin.wrap .icon-ok-sign:before{content:"✔"}#loco-admin.wrap .icon-help:before{content:"?"}#loco-admin.wrap .icon-info:before,#loco-admin.wrap .notice-info>.has-icon:before,#loco-admin.wrap .notice-info p>strong.has-icon:before{content:"ℹ"}#loco-admin.wrap .icon-cancel:before{content:""}#loco-admin.wrap .icon-warn:before,#loco-admin.wrap .notice-error>.has-icon:before,#loco-admin.wrap .notice-error p>strong.has-icon:before,#loco-admin.wrap .notice-warning>.has-icon:before,#loco-admin.wrap .notice-warning p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-comment:before{content:""}#loco-admin.wrap .icon-bar-chart:before{content:""}#loco-admin.wrap .icon-key:before{content:""}#loco-admin.wrap .icon-cogs:before{content:""}#loco-admin.wrap .icon-comments:before{content:""}#loco-admin.wrap .icon-signout:before{content:""}#loco-admin.wrap .icon-signin:before{content:""}#loco-admin.wrap .icon-upload:before{content:""}#loco-admin.wrap .icon-twitter:before{content:"🐦"}#loco-admin.wrap .icon-facebook:before{content:""}#loco-admin.wrap .icon-github:before{content:""}#loco-admin.wrap .icon-feed:before{content:""}#loco-admin.wrap .icon-globe:before{content:""}#loco-admin.wrap .icon-wrench:before,#loco-admin.wrap .notice-debug>.has-icon:before,#loco-admin.wrap .notice-debug p>strong.has-icon:before{content:""}#loco-admin.wrap .icon-group:before{content:""}#loco-admin.wrap .icon-cloud:before{content:""}#loco-admin.wrap .icon-copy:before{content:""}#loco-admin.wrap .icon-save:before{content:""}#loco-admin.wrap .icon-menu:before{content:""}#loco-admin.wrap .icon-table:before{content:""}#loco-admin.wrap .icon-caret-down:before{content:"▼"}#loco-admin.wrap .icon-caret-up:before{content:"▲"}#loco-admin.wrap .icon-caret-right:before{content:"▶"}#loco-admin.wrap .icon-mail:before{content:""}#loco-admin.wrap .icon-cloud-upload:before{content:""}#loco-admin.wrap .icon-file:before{content:""}#loco-admin.wrap .icon-circle-white:before{content:"⚬"}#loco-admin.wrap .icon-circle-black:before{content:"●"}#loco-admin.wrap .icon-eraser:before{content:""}#loco-admin.wrap .icon-unlock:before{content:""}#loco-admin.wrap .icon-apple:before{content:""}#loco-admin.wrap .icon-android:before{content:""}#loco-admin.wrap .icon-robot:before{content:"🤖"}#loco-admin.wrap .icon-back:before{content:"⬅"}#loco-admin.wrap .icon-next:before{content:"➔"}#loco-admin.wrap .icon-arrow-up:before{content:""}#loco-admin.wrap .icon-calendar:before{content:""}#loco-admin.wrap .icon-ccard:before{content:""}#loco-admin.wrap .icon-caret-left:before{content:"◀"}#loco-admin.wrap .icon-pro:before{content:"⚡"}#loco-admin.wrap .icon-bell:before{content:""}#loco-admin.wrap .icon-code:before{content:""}#loco-admin.wrap .icon-privacy:before{content:"🛡"}#loco-admin.wrap .icon-hellip:before{content:"…"}#loco-admin.wrap .icon-vellip:before{content:"⁞"}#loco-admin.wrap .icon-collapse:before{content:""}#loco-admin.wrap .icon-expand:before{content:""}#loco-admin.wrap .icon-wordpress:before{content:""}#loco-admin.wrap .icon-database:before{content:""}#loco-admin.wrap .icon-restore:before{content:""}#loco-admin.wrap .icon-pilcrow:before{content:"¶"}#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before,#loco-admin.wrap .has-dashicon:before{speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-admin.wrap .icon,#loco-admin.wrap .has-icon:before{font-family:"loco"}#loco-admin.wrap .has-dashicon:before{font-family:"dashicons";font-size:1.4em}#loco-admin.wrap .has-icon:before,#loco-admin.wrap .has-dashicon:before,#loco-admin.wrap .has-icon>span{display:inline-block;vertical-align:middle}#loco-admin.wrap .only-icon{text-align:center}#loco-admin.wrap .only-icon:before{text-align:center;padding:0}#loco-admin.wrap .only-icon span{display:none}#loco-admin.wrap a,#loco-admin.wrap .wp-core-ui .button-link{text-decoration:none}#loco-admin.wrap h3:hover>a.loco-anchor{color:#ccc}#loco-admin.wrap h3:hover>a.loco-anchor:before{content:"¶"}#loco-admin.wrap .has-lang>span{display:inline-block;vertical-align:middle}#loco-admin.wrap a.has-lang:hover>span:last-child{text-decoration:underline}#loco-admin.wrap h1 ul,#loco-admin.wrap h1 li{margin:0;padding:0}#loco-admin.wrap h1 li{display:inline-block}#loco-admin.wrap h1 li:after{content:"/";color:#999;text-shadow:none;display:inline-block}#loco-admin.wrap h1 li:last-child:after{content:""}#loco-admin.wrap h1 li:last-child a{color:inherit;pointer-events:none;cursor:auto}#loco-admin.wrap h2 span{color:#999;font-weight:normal}#loco-admin.wrap h2 .loco-meta,#loco-admin.wrap h3 .loco-meta{color:inherit;font-size:14px;font-weight:normal;vertical-align:middle}#loco-admin.wrap .wp-list-table td:first-child .icon{width:16px;display:inline-block;text-align:center}#loco-admin.wrap .wp-list-table td{white-space:nowrap}#loco-admin.wrap .wp-list-table td>a,#loco-admin.wrap .wp-list-table td>time{display:inline-block;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#loco-admin.wrap .wp-list-table th.loco-sort{cursor:pointer}#loco-admin.wrap .wp-list-table th.loco-sort:hover{color:#000}#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after,#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after{padding:0 0 0 4px;color:#999}#loco-admin.wrap .wp-list-table th.loco-sort.loco-desc:after{content:"▼"}#loco-admin.wrap .wp-list-table th.loco-sort.loco-asc:after{content:"▲"}#loco-admin.wrap .wp-list-table td.has-row-actions{overflow:visible}#loco-admin.wrap form.loco-filter{display:block;margin-bottom:5px}#loco-admin.wrap form.loco-filter .icon-filter{color:#999}#loco-admin.wrap nav.above-list-table{margin-bottom:1em}#loco-admin.wrap nav.above-list-table a{display:inline-block;margin-right:1em}#loco-admin.wrap .wp-core-ui button.inverted,#loco-admin.wrap .wp-core-ui button.inverted:hover,#loco-admin.wrap .po-fuzzy button.icon-cloud{background:-moz-linear-gradient(top, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);background:-webkit-linear-gradient(top, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);background:linear-gradient(to bottom, #cccccc 0%, #e0e0e0 30%, #fefefe 100%);-webkit-box-shadow:0 1px 0 #fff;-moz-box-shadow:0 1px 0 #fff;box-shadow:0 1px 0 #fff;border-color:gray}#loco-admin.wrap .wp-core-ui button:active,#loco-admin.wrap .wp-core-ui button.inverted:active{border-color:#5b9dd9}#loco-admin.wrap .loco-clearable{display:inline-block;vertical-align:middle;position:relative}#loco-admin.wrap .loco-clearable a.clear,#loco-admin.wrap .auto-comp-wrap a.clear{top:0;right:0;outline:none;margin:0;border:solid 1px transparent;padding:5px 5px;position:absolute;font-size:1em;line-height:normal}#loco-admin.wrap .loco-clearable a.clear:before,#loco-admin.wrap .auto-comp-wrap a.clear:before{vertical-align:middle;padding:0;color:#999}#loco-admin.wrap .loco-clearable a.clear:hover:before,#loco-admin.wrap .auto-comp-wrap a.clear:hover:before{color:#333}#loco-admin.wrap .loco-clearable a.clear span,#loco-admin.wrap .auto-comp-wrap a.clear span{display:none}#loco-admin.wrap .loco-clearable ::-ms-clear,#loco-admin.wrap .auto-comp-wrap ::-ms-clear{display:none}#loco-admin.wrap div.progress{color:#000;background:transparent !important}#loco-admin.wrap div.progress *{height:100%;overflow:hidden;white-space:nowrap}#loco-admin.wrap div.progress .t{background-color:#ddd;border:1px solid #ccc}#loco-admin.wrap div.progress .t .bar{float:left;clear:none;background-color:#3db63d}#loco-admin.wrap div.progress .t .bar.f{background-color:#bd2c00}#loco-admin.wrap div.progress .l{display:block}#loco-admin.wrap td div.progress .t{border:none}#loco-admin.wrap td div.progress .l{display:none}#loco-admin.wrap code.path{color:#333;margin:0;padding:0;display:inline;background:transparent}#loco-admin.wrap .loco-danger{color:#d54e21}#loco-admin.wrap .notice,#loco-admin.wrap .panel{background:#fff;position:relative;margin:1em 0;padding:1px 12px}#loco-admin.wrap .notice-generic{border-color:#ddd}#loco-admin.wrap .notice-success>.has-icon,#loco-admin.wrap .notice-success p>strong.has-icon{color:#000}#loco-admin.wrap .notice-warning{border-color:orange}#loco-admin.wrap .notice-error{border-color:#dc3232}#loco-admin.wrap .notice-debug{border-color:#00a0d2}#loco-admin.wrap .notice-danger{border-color:#dc3232}#loco-admin.wrap .notice-locked{border-color:orange}#loco-admin.wrap .notice>.has-icon:before,#loco-admin.wrap .notice p>strong.has-icon:before{padding-right:6px}#loco-admin.wrap .notice>p>a.button.has-icon:before{width:1.2em}#loco-admin.wrap .notice>p>em{color:#d54e21;font-style:normal}#loco-admin.wrap .notice>p>em a{color:inherit}#loco-admin.wrap .notice>p a:hover,#loco-admin.wrap .notice>nav a:hover{text-decoration:underline}#loco-admin.wrap .notice>p a.button,#loco-admin.wrap .notice>nav a.button{text-decoration:inherit}#loco-admin.wrap .notice.has-nav{display:flex;flex-direction:row}#loco-admin.wrap .notice.has-nav p,#loco-admin.wrap .notice.has-nav nav{line-height:22px;flex-grow:1}#loco-admin.wrap .notice.has-nav nav{text-align:right;padding:2px;margin:.5em 0}#loco-admin.wrap .notice.has-nav.is-dismissible{padding-right:38px}#loco-admin.wrap .notice.has-nav a{white-space:nowrap}#loco-admin.wrap .notice.has-nav nav>span{color:#666}#loco-admin.wrap .notice>h3>span{display:inline-block;vertical-align:middle}#loco-admin.wrap ul.problems li{font-style:italic}#loco-admin.wrap label{position:relative}#loco-admin.wrap label.for-disabled,#loco-admin.wrap label.for-disabled>input{cursor:default !important}#loco-admin.wrap input.regular-text,#loco-admin.wrap textarea.regular-text{width:25em}#loco-admin.wrap .button-link{padding:0 10px 1px}#loco-admin.wrap .button-danger{background:#ba0000;border-color:#900 #600 #600;-webkit-box-shadow:0 1px 0 #600;-moz-box-shadow:0 1px 0 #600;box-shadow:0 1px 0 #600;color:#fff;text-shadow:0 -1px 1px #600,1px 0 1px #600,0 1px 1px #600,-1px 0 1px #600}#loco-admin.wrap .button-success{background:#00b500;border-color:#090 #2e892e #2e892e;-webkit-box-shadow:0 1px 0 #2e892e;-moz-box-shadow:0 1px 0 #2e892e;box-shadow:0 1px 0 #2e892e;color:#fff;text-shadow:0 -1px 1px #2e892e,1px 0 1px #2e892e,0 1px 1px #2e892e,-1px 0 1px #2e892e}#loco-admin.wrap .button-success:hover{background:#3db63d}#loco-admin.wrap .button-danger[disabled],#loco-admin.wrap .button-success[disabled]{text-shadow:none !important}#loco-admin.wrap form button.loco-loading.button-large{padding-left:0}#loco-admin.wrap form button.loco-loading.button-large:before{width:16px;height:16px;margin:0 4px;content:" ";font-size:16px;line-height:1;display:inline-block;vertical-align:sub}#loco-admin.wrap ::placeholder{color:#ccc}#loco-admin.wrap ::-webkit-input-placeholder{color:#ccc}#loco-admin.wrap :-moz-placeholder{color:#ccc;opacity:1}#loco-admin.wrap ::-moz-placeholder{color:#ccc;opacity:1}#loco-admin.wrap :-ms-input-placeholder{color:#ccc}#loco-admin.wrap .ielt10 .placeheld{color:#ccc}#loco-admin.wrap a.has-raquo:after{content:" »"}#loco-admin.wrap a.has-laquo:before{content:"« "}#loco-admin.wrap span.inline-spinner{display:inline-block;min-width:16px;min-height:16px;background:transparent url(../img/spin-modal.gif?v=2.6.0) 0 0 no-repeat}.js #wpbody-content>.notice{display:none}.js #wpbody-content>.notice.inline{display:block}.js #loco-admin.wrap .jshide,.no-js #loco-admin.wrap .jsonly{display:none !important}#loco-admin.wrap .invis{visibility:hidden}.form-table tr td{vertical-align:top}.form-table tr.compact td{padding-top:0}.form-table tr th a.icon-help{display:none}.loco-modal{min-width:50%;min-height:100px}.loco-modal-wide{min-width:90% !important}.loco-modal-no-close .ui-dialog-titlebar-close{display:none}.loco-modal .ui-dialog-titlebar-close{overflow:hidden}.loco-modal.request-filesystem-credentials-dialog{top:15% !important;max-height:85% !important}.loco-modal.request-filesystem-credentials-dialog>.ui-dialog-content{background:inherit}.loco-modal.request-filesystem-credentials-dialog .ftp-password>label>em:last-child{display:none}.ui-dialog-content>div.loco-loading{height:100%;background:transparent url(../img/spin-modal.gif?v=2.6.0) center 20px no-repeat}#loco-po-ref ol li{color:#aaa;margin:0;white-space:pre;padding:0 0 0 1em;font:normal 12px/17px Consolas,Monaco,monospace;background:transparent;border-left:1px solid #eee}#loco-po-ref ol li code{margin:0;padding:0;display:inline;background:inherit}#loco-po-ref ol li.highlighted{color:#666;background-color:#f8eec7}#loco-po-ref ol li.highlighted code.T_CONSTANT_ENCAPSED_STRING{color:#c931c7}#loco-credit>*{vertical-align:middle}#loco-credit>a{display:inline-block;position:relative;overflow:hidden;background:transparent url(../img/logo-foot.gif?v=2.6.0) 0 0 no-repeat;height:30px;width:100px;text-indent:200px;-webkit-transition-duration:0s;transition-duration:0s}#loco-credit>a:hover{background-position:0 -35px}#loco-content{position:relative}#footer-upgrade span:before{color:#ccc;content:" | ";display:inline;padding-left:.5em;padding-right:.5em}#footer-upgrade span:first-child:before{content:"";display:none}.loco-clearfix:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}dl.debug dt{font-weight:bold}dl.debug dt,dl.debug dd{white-space:pre}.wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(0,115,170,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#0073aa;foo:#0073aa}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#66c6e4 !important;background:#008ec2 !important;border-color:#008ec2 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../img/skins/fresh/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/editor.css CHANGED
@@ -1 +1 @@
1
- #loco-editor{border:solid 1px #ccc}#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}#loco-editor ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.5.8) 0 0 no-repeat;min-height:75px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.5.8);background-size:16px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.5.8);background-size:16px}}#loco-editor ._green_glow_inner,#loco-editor .is-editable>.wg-content>textarea:focus,#loco-editor .is-editable>.wg-content.has-focus .ace_scroller,#loco-editor .is-editable>.wg-content.has-focus .wysihtml-editor,#loco-editor .is-editable>.wg-content.has-focus .mce-content-body{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-editor ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-editor .loco-font,#loco-editor .is-table .wg-thead .wg-sortable>header:after{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-editor div.ta-mirror{position:absolute;top:0;border:solid 1px transparent;color:transparent;padding:.4em .6em;pointer-events:none}#loco-editor div.ta-mirror span{position:relative}#loco-editor div.ta-mirror span:after{color:#ccc;white-space:pre;display:inline-block;position:absolute;top:0;line-height:normal}#loco-editor div.ta-mirror .crlf:after{content:"¬"}#loco-editor div.ta-mirror .eof:after{content:"¶"}#loco-editor div.ta-mirror .x20:after{content:"·";color:#aaa}#loco-editor div.ta-mirror .x9:after{content:"⟶"}#loco-editor div.ta-mirror,#loco-editor .has-mirror textarea{white-space:pre-wrap;word-wrap:break-word;word-spacing:0px}#loco-editor .has-mirror ::placeholder{color:transparent}#loco-editor .has-mirror ::-webkit-input-placeholder{color:transparent}#loco-editor .has-mirror :-moz-placeholder{color:transparent;opacity:1}#loco-editor .has-mirror ::-moz-placeholder{color:transparent;opacity:1}#loco-editor .has-mirror :-ms-input-placeholder{color:transparent}#loco-editor .has-mirror .ielt10 .placeheld{color:transparent}#loco-editor div.ta-mirror{left:0;text-align:left}#loco-editor div.ta-mirror span:after{left:0}#loco-editor div.ta-mirror .eol:after{padding-left:.2em}#loco-editor [dir=RTL] div.ta-mirror{left:auto;right:0;text-align:right}#loco-editor [dir=RTL] div.ta-mirror span:after{right:0}#loco-editor [dir=RTL] div.ta-mirror .eol:after{padding-left:0;padding-right:.2em}#loco-editor .has-proxy>textarea{display:none !important}#loco-editor .has-proxy .ace_editor{height:100%;font-size:13px !important;line-height:1.4 !important}#loco-editor .has-proxy .ace_editor .ace_marker-layer .ace_bracket{display:none}#loco-editor .has-proxy .ace_print-margin{display:none}#loco-editor .ace_printf{color:#b90690;background-color:#edf1be}#loco-editor .ace_locked{color:gray}#loco-editor .ace_icu-quoted{color:gray}#loco-editor .ace_icu{color:#697eb9}#loco-editor .ace_icu.ace_name{color:#b90600}#loco-editor .resizer{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0 0 6px 0;background:#f0f0f0 url(../img/wg/splity.png?v=2.5.8) center bottom no-repeat;border:1px solid #ddd;overflow:hidden;cursor:move;cursor:row-resize;cursor:s-resize}#loco-editor .resizer>*{height:100%;border:none}#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}#loco-editor ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.5.8) 0 0 no-repeat;min-height:75px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.5.8);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.5.8);background-size:16px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.5.8);background-size:16px}}#loco-editor ._green_glow_inner,#loco-editor .is-editable>.wg-content>textarea:focus,#loco-editor .is-editable>.wg-content.has-focus .ace_scroller,#loco-editor .is-editable>.wg-content.has-focus .wysihtml-editor,#loco-editor .is-editable>.wg-content.has-focus .mce-content-body{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-editor ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-editor .loco-font,#loco-editor .is-table .wg-thead .wg-sortable>header:after{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-editor .wg-cell,#loco-editor .wg-cell>div{clear:both;position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;outline:none}#loco-editor .wg-cell{left:0;top:0;padding:0;margin:0;overflow:hidden}#loco-editor .wg-split{background:#eee}#loco-editor .wg-body:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}#loco-editor .wg-split-x>div>.not-first>*{margin-left:6px}#loco-editor .wg-split-y>div>.not-first>*{margin-top:6px}#loco-editor .wg-split>div>.has-title .wg-content{margin-top:0}#loco-editor .wg-split-x>div>.wg-cell{float:left;clear:none;height:100%}#loco-editor .wg-split-x>div{cursor:move;cursor:ew-resize;cursor:col-resize}#loco-editor .wg-split>div>.not-first:before{display:block;position:absolute;overflow:hidden;content:" "}#loco-editor .wg-split-x>div>.not-first:before{width:6px;height:100%;background:transparent url(../img/wg/splitx.png?v=2.5.8) center center no-repeat}#loco-editor .wg-split-y>div{cursor:move;cursor:ns-resize;cursor:row-resize}#loco-editor .wg-split-y>div>.not-first:before{height:6px;width:100%;background:transparent url(../img/wg/splity.png?v=2.5.8) center center no-repeat}#loco-editor .wg-split>div.locked{cursor:default}#loco-editor .wg-split-x>div.locked>.not-first>*{margin-left:0px}#loco-editor .wg-split-y>div.locked>.not-first>*{margin-top:0px}#loco-editor .wg-split>div.locked>.not-first:before{display:none}#loco-editor .has-title>header{background:#e2e2e2;cursor:default !important;margin:0;white-space:nowrap}#loco-editor .wg-content{background:#fff;cursor:default;padding:4px 6px;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#loco-editor .wg-toolbar{top:0;right:0;margin-top:6px;position:absolute}#loco-editor .wg-toolbar>span{color:#fff;background:#000;display:block;padding:0 6px;cursor:default !important}#loco-editor .wg-toolbar>span:active{color:#000;background-color:#fff}#loco-editor .wg-content,#loco-editor .wg-tbody>div{overflow:scroll;overflow-x:hidden;overflow-y:auto}#loco-editor .is-table{background-color:#fff}#loco-editor .is-table .wg-thead .has-title>header{font-weight:normal;background:transparent;padding:4px 0;margin:0 0 0 10px}#loco-editor .is-table .wg-thead>div>.not-first:before{background-position:center center}#loco-editor .is-table .wg-thead{background:#e2e2e2;border-bottom:solid 1px #ccc}#loco-editor .is-table .wg-tbody{background-image:url(data:image/gif;base64,R0lGODlhAQAsAIABAPz8/P///yH5BAEAAAEALAAAAAABACwAAAIIjI+pAe0PIygAOw==);position:relative}#loco-editor .is-table .wg-cols>div{float:left;clear:none}#loco-editor .is-table .wg-cols>div>div{white-space:nowrap;line-height:1.7em;padding-left:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;background-color:#fff}#loco-editor .is-table .wg-cols>div>div:nth-child(even){background-color:#f7f7f7}#loco-editor .is-table .wg-cols>div>div.selected{background-color:#3db63d;color:#fff}#loco-editor .is-table .wg-cols>div>div.selected::selection{background-color:#fff;color:#000}#loco-editor .is-table .wg-cols>div:first-child>div{padding-left:4px}#loco-editor .is-table .wg-dead{clear:both}#loco-editor .is-table .wg-thead .wg-sortable>header{cursor:pointer !important}#loco-editor .is-table .wg-thead .wg-sortable>header:after{padding:0 0 0 5px;color:#999}#loco-editor .is-table .wg-thead .wg-sortable.wg-asc>header:after{content:"▲"}#loco-editor .is-table .wg-thead .wg-sortable.wg-desc>header:after{content:"▼"}#loco-editor .is-table .wg-thead .wg-sortable:hover>header:after{color:#000}#loco-editor .is-field>.wg-content{cursor:text;padding:0;line-height:normal;overflow:hidden;overflow-y:hidden}#loco-editor .is-field>.wg-content>div,#loco-editor .is-field>.wg-content>textarea{font-size:14px;line-height:1.4;border:1px solid #ddd;width:100%;height:100%;padding:8px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0}#loco-editor .is-field>.wg-content textarea{resize:none;overflow:auto;display:block}#loco-editor .is-field>.wg-content>.ace_editor{padding:0;border-width:0}#loco-editor .is-field>.wg-content>div[contenteditable]{overflow:scroll;overflow-x:hidden;overflow-y:auto}#loco-editor .is-readonly>.wg-content{cursor:default}#loco-editor .is-readonly>.wg-content>div,#loco-editor .is-readonly>.wg-content>textarea,#loco-editor .is-readonly>.wg-content>textarea[readonly]{background:#f8f8f8;text-shadow:0 1px #fff;color:inherit}#loco-editor .is-readonly>.wg-content .ace_scroller{cursor:default;background:#f8f8f8}#loco-editor .is-readonly>.wg-content .ace_cursor-layer{display:none}#loco-editor .is-readonly>.wg-content>textarea[readonly]{cursor:default}#loco-editor .is-editable>.wg-content[dir=RTL] .ace_editor .ace_line{direction:ltr;unicode-bidi:bidi-override}#loco-editor .wg-split-x>nav.wg-tabs{white-space:nowrap;text-align:center;cursor:default}#loco-editor .wg-split-x>nav.wg-tabs>a{display:inline-block;padding:.5em 1em;margin-top:.2em;color:#000;text-decoration:none;-webkit-border-radius:.2em .2em 0 0;-moz-border-radius:.2em .2em 0 0;-ms-border-radius:.2em .2em 0 0;-o-border-radius:.2em .2em 0 0;border-radius:.2em .2em 0 0;background-color:#f3f7fd}#loco-editor .wg-split-x>nav.wg-tabs>a:hover{background-color:#fff}#loco-editor .wg-split-x>nav.wg-tabs>a.active{background-color:#3db63d;color:#fff}#loco-editor .wg-split>div>.has-nav>.wg-body{margin-top:0px}#loco-editor .wg-dead{visibility:hidden}@media all and (max-width: 768px){#loco-editor .wg-split-x>div>.not-first>*{margin-left:20px}#loco-editor .wg-split-y>div>.not-first>*{margin-top:20px}#loco-editor .wg-split-x>div>.not-first:before{width:20px}#loco-editor .wg-split-y>div>.not-first:before{height:20px}#loco-editor .is-table .wg-thead header{padding-left:20px}}#loco-editor .is-table .po-fuzzy{color:#b59829;font-weight:bold}#loco-editor .is-table .po-empty{color:#1f507a;font-weight:bold}#loco-editor .is-table .po-flagged{color:#bd2c00}#loco-editor .is-table .wg-cols>div:first-child>div:before{font-family:loco;vertical-align:inherit;display:inline-block;content:" ";width:1.3em;line-height:1}#loco-editor .is-table .wg-cols>div:first-child>div.po-fuzzy:before{content:""}#loco-editor .is-table .wg-cols>div:first-child>div.po-flagged:before{content:""}#loco-editor .is-table .wg-cols>div:first-child>div.po-comment:before{content:"";color:#999}#loco-editor .is-table .wg-cols>div:first-child>div.po-unsaved:before{content:"";color:#f1d040}#loco-editor .is-table .wg-cols>div:first-child>div.selected:before{color:#fff !important}#loco-editor .wg-cell>.meta{color:#333;margin:0 !important;padding:6px 10px;font-weight:normal;font-size:13px;line-height:1.4em;cursor:default !important}#loco-editor .wg-cell>.meta>*{display:inline-block;margin-top:3px;margin-bottom:3px}#loco-editor .wg-cell>.meta>span{border:1px solid transparent;border-left:none}#loco-editor .wg-cell>.meta>mark{color:#fff;border-radius:2px;background-color:silver;border:1px solid silver;padding:0 .3em}#loco-editor .wg-cell>.meta>mark.tag{color:#999;background-color:#eee}#loco-editor .wg-cell>.meta>p{display:block;white-space:pre-line}#loco-editor .wg-cell>.meta .icon-warn{color:#c00}#loco-editor .wg-cell>.meta .has-icon:before{padding-right:0;width:17px}#loco-editor .wg-cell>.meta code{font-size:12px}#loco-editor .is-table .wg-cols>div>div>mark{display:inline-block;vertical-align:text-bottom;font:inherit;font-weight:normal;color:#fff;border-radius:2px;font-size:90%;line-height:1;padding:.2em .3em;background-color:rgba(0,0,0,.25)}#loco-editor .is-table .wg-cols>div>div.selected.po-flagged{background-color:#bd2c00}#loco-editor .is-table .wg-cols>div>div.selected.po-fuzzy{background-color:#b59829}#loco-editor .is-table .wg-cols>div>div.selected.po-empty{background-color:#999}#loco-editor #po-target header nav{display:block;position:absolute;right:0px;top:0px;padding:2px}#loco-editor #po-target header nav button{margin-left:5px}#loco-editor #po-target header nav.po-empty .icon-cloud{display:none !important}#loco-editor #po-list .wg-content{padding:0}#loco-editor #po-source>.wg-body>.has-title>header{background:transparent;font-weight:normal;float:left;clear:none;min-width:3.4em}#loco-editor #po-source>.wg-body>.has-title>.wg-content{clear:none}#loco-editor .has-title>header{line-height:normal;padding:6px}#loco-editor .has-title>header .lang{margin-right:6px;margin-bottom:1px}#loco-editor .trg-rtl #po-list-tbody .wg-cols>div[for=po-list-col-target]>div,#loco-editor .src-rtl #po-list-tbody .wg-cols>div[for=po-list-col-source]>div{direction:rtl;padding-left:0;padding-right:10px;text-align:right}#loco-editor #po-source>.wg-body>.has-title>h2{min-width:4.5em}#loco-editor .is-table .wg-td{font-size:13px}#loco-editor header,#loco-editor nav{display:block;position:relative}#loco-editor-inner{min-height:600px;font-size:14px;clear:both}#loco-editor-inner>div.loco-loading{height:100px;background:transparent url(../img/spin-editor-button.gif?v=2.5.8) center 20px no-repeat}#loco-editor-inner h2{color:#000;line-height:1}#loco-editor-inner .wg-cell>.meta code{padding:0;color:#0073aa;background:inherit;cursor:pointer}#loco-editor-inner .wg-cell>.meta code:hover{text-decoration:underline}#loco-admin.wrap #loco-editor>nav{font-size:14px;height:50px}#loco-admin.wrap #loco-editor>nav form{display:block;float:left;clear:none;padding:0;margin:0}#loco-admin.wrap #loco-editor>nav form.aux{float:right;margin-right:5px}#loco-admin.wrap #loco-editor>nav fieldset{display:block;position:relative;float:left;clear:none}#loco-admin.wrap #loco-editor>nav button,#loco-admin.wrap #loco-editor>nav input[type=text]{display:block;position:relative;float:left;clear:none;margin:5px 0 0 5px;height:36px;text-align:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#loco-admin.wrap #loco-editor>nav input[type=text]{padding:0 10px;font-size:14px;line-height:normal}#loco-admin.wrap #loco-editor>nav .invalid input[type=text]:focus{border-color:#c00;-webkit-box-shadow:0 0 2px rgba(153,0,0,.5);-moz-box-shadow:0 0 2px rgba(153,0,0,.5);box-shadow:0 0 2px rgba(153,0,0,.5)}#loco-admin.wrap #loco-editor>nav .loco-clearable{padding:0 20px}#loco-admin.wrap #loco-editor>nav .loco-clearable.invalid a.clear:before{color:#c00}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear{right:25px;line-height:2}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear:hover:before{color:#c00}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear:active:before{color:#000}#loco-admin.wrap #loco-editor>nav button.only-icon{width:40px}#loco-admin.wrap button.has-icon:before{width:16px;padding:0}#loco-admin.wrap button.has-icon.loco-loading:before{content:" ";height:16px;background:transparent url(../img/spin-editor-button.gif?v=2.5.8) 0 0 no-repeat}#loco-admin.wrap .button,#loco-admin.wrap .button-link,#loco-admin.wrap input[type=text]{border-color:#aaa;color:#444}#loco-admin.wrap .button:hover,#loco-admin.wrap .button-link:hover{color:#000}#loco-admin.wrap .button-primary,#loco-admin.wrap .button-primary:hover{color:#fff}#loco-admin.wrap button.icon-translate:before{font-size:16px}.loco-modal .loco-api{position:relative;padding:10px;background:#f7f7f7;border:solid 1px #eee;font-size:14px;margin-bottom:16px}.loco-modal .loco-api p{padding:0;margin:0;font-size:inherit}.loco-modal .loco-api blockquote{font-weight:bold;margin:0;padding:10px 0}.loco-modal .loco-api a.loco-api-credit{padding:0;display:block;position:absolute;right:10px;bottom:10px;text-decoration:none;white-space:nowrap;overflow:hidden;font-size:12px}.loco-modal .loco-api a.loco-api-credit:hover{text-decoration:underline}.loco-modal .loco-api-loading{text-indent:20px;background:transparent url(../img/spin-modal.gif?v=2.5.8) 10px center no-repeat}.loco-modal .loco-alert p{margin-bottom:2em;font-size:14px}.loco-modal .loco-alert nav{display:block;position:relative;margin:1em 0}.loco-modal .loco-alert nav a{display:inline-block;margin-right:1em;padding:10px}#loco-auto{display:none;min-width:50%;min-height:300px;position:relative}#loco-auto form blockquote{margin:0;padding:1em 0;font-size:14px}.loco-api a.loco-api-credit{color:inherit}.loco-api-yandex a.loco-api-credit:before{content:"Powered by "}.loco-api-google a.loco-api-credit{text-indent:200px;width:122px;height:16px;background:transparent url(../img/api/google.png?v=2.5.8) 0 0 no-repeat}.loco-api-microsoft a.loco-api-credit{text-indent:200px;width:152px;height:16px;background:transparent url(../img/api/microsoft.png?v=2.5.8) 0 0 no-repeat}.loco-api-deepl a.loco-api-credit{text-indent:200px;width:122px;height:16px;background:transparent url(../img/api/deepl.png?v=2.5.8) 0 0 no-repeat}
1
+ #loco-editor{border:solid 1px #ccc}#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}#loco-editor ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.6.0) 0 0 no-repeat;min-height:75px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.6.0);background-size:16px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.6.0);background-size:16px}}#loco-editor ._green_glow_inner,#loco-editor .is-editable>.wg-content>textarea:focus,#loco-editor .is-editable>.wg-content.has-focus .ace_scroller,#loco-editor .is-editable>.wg-content.has-focus .wysihtml-editor,#loco-editor .is-editable>.wg-content.has-focus .mce-content-body{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-editor ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-editor .loco-font,#loco-editor .is-table .wg-thead .wg-sortable>header:after{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-editor div.ta-mirror{position:absolute;top:0;border:solid 1px transparent;color:transparent;padding:.4em .6em;pointer-events:none}#loco-editor div.ta-mirror span{position:relative}#loco-editor div.ta-mirror span:after{color:#ccc;white-space:pre;display:inline-block;position:absolute;top:0;line-height:normal}#loco-editor div.ta-mirror .crlf:after{content:"¬"}#loco-editor div.ta-mirror .eof:after{content:"¶"}#loco-editor div.ta-mirror .x20:after{content:"·";color:#aaa}#loco-editor div.ta-mirror .x9:after{content:"⟶"}#loco-editor div.ta-mirror,#loco-editor .has-mirror textarea{white-space:pre-wrap;word-wrap:break-word;word-spacing:0px}#loco-editor .has-mirror ::placeholder{color:transparent}#loco-editor .has-mirror ::-webkit-input-placeholder{color:transparent}#loco-editor .has-mirror :-moz-placeholder{color:transparent;opacity:1}#loco-editor .has-mirror ::-moz-placeholder{color:transparent;opacity:1}#loco-editor .has-mirror :-ms-input-placeholder{color:transparent}#loco-editor .has-mirror .ielt10 .placeheld{color:transparent}#loco-editor div.ta-mirror{left:0;text-align:left}#loco-editor div.ta-mirror span:after{left:0}#loco-editor div.ta-mirror .eol:after{padding-left:.2em}#loco-editor [dir=RTL] div.ta-mirror{left:auto;right:0;text-align:right}#loco-editor [dir=RTL] div.ta-mirror span:after{right:0}#loco-editor [dir=RTL] div.ta-mirror .eol:after{padding-left:0;padding-right:.2em}#loco-editor .has-proxy>textarea{display:none !important}#loco-editor .has-proxy .ace_editor{height:100%;font-size:13px !important;line-height:1.4 !important}#loco-editor .has-proxy .ace_editor .ace_marker-layer .ace_bracket{display:none}#loco-editor .has-proxy .ace_print-margin{display:none}#loco-editor .ace_printf{color:#b90690;background-color:#edf1be}#loco-editor .ace_locked{color:gray}#loco-editor .ace_icu-quoted{color:gray}#loco-editor .ace_icu{color:#697eb9}#loco-editor .ace_icu.ace_name{color:#b90600}#loco-editor .resizer{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0 0 6px 0;background:#f0f0f0 url(../img/wg/splity.png?v=2.6.0) center bottom no-repeat;border:1px solid #ddd;overflow:hidden;cursor:move;cursor:row-resize;cursor:s-resize}#loco-editor .resizer>*{height:100%;border:none}#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}#loco-editor ._ajax_loader_f2x4{background:transparent url(../img/ajax-loader-f2-x4.gif?v=2.6.0) 0 0 no-repeat;min-height:75px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc.gif?v=2.6.0);background-repeat:no-repeat;min-height:16px}@media only screen and (-webkit-min-device-pixel-ratio: 2),only screen and (min--moz-device-pixel-ratio: 2),only screen and (-o-min-device-pixel-ratio: 2/1),only screen and (min-device-pixel-ratio: 2),only screen and (min-resolution: 192dpi),only screen and (min-resolution: 2dppx){#loco-editor ._ajax_loader_f2{background-image:url(../img/ajax-loader-f2-x2.gif?v=2.6.0);background-size:16px}#loco-editor ._ajax_loader_cc{background-image:url(../img/ajax-loader-cc-x2.gif?v=2.6.0);background-size:16px}}#loco-editor ._green_glow_inner,#loco-editor .is-editable>.wg-content>textarea:focus,#loco-editor .is-editable>.wg-content.has-focus .ace_scroller,#loco-editor .is-editable>.wg-content.has-focus .wysihtml-editor,#loco-editor .is-editable>.wg-content.has-focus .mce-content-body{-webkit-box-shadow:inset 0 0 10px 0 #3db63d;-moz-box-shadow:inset 0 0 10px 0 #3db63d;box-shadow:inset 0 0 10px 0 #3db63d}#loco-editor ._green_glow_outer{-webkit-box-shadow:0 0 .5em 0 #3db63d;-moz-box-shadow:0 0 .5em 0 #3db63d;box-shadow:0 0 .5em 0 #3db63d}#loco-editor .loco-font,#loco-editor .is-table .wg-thead .wg-sortable>header:after{font-family:"loco";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#loco-editor .wg-cell,#loco-editor .wg-cell>div{clear:both;position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;outline:none}#loco-editor .wg-cell{left:0;top:0;padding:0;margin:0;overflow:hidden}#loco-editor .wg-split{background:#eee}#loco-editor .wg-body:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}#loco-editor .wg-split-x>div>.not-first>*{margin-left:6px}#loco-editor .wg-split-y>div>.not-first>*{margin-top:6px}#loco-editor .wg-split>div>.has-title .wg-content{margin-top:0}#loco-editor .wg-split-x>div>.wg-cell{float:left;clear:none;height:100%}#loco-editor .wg-split-x>div{cursor:move;cursor:ew-resize;cursor:col-resize}#loco-editor .wg-split>div>.not-first:before{display:block;position:absolute;overflow:hidden;content:" "}#loco-editor .wg-split-x>div>.not-first:before{width:6px;height:100%;background:transparent url(../img/wg/splitx.png?v=2.6.0) center center no-repeat}#loco-editor .wg-split-y>div{cursor:move;cursor:ns-resize;cursor:row-resize}#loco-editor .wg-split-y>div>.not-first:before{height:6px;width:100%;background:transparent url(../img/wg/splity.png?v=2.6.0) center center no-repeat}#loco-editor .wg-split>div.locked{cursor:default}#loco-editor .wg-split-x>div.locked>.not-first>*{margin-left:0px}#loco-editor .wg-split-y>div.locked>.not-first>*{margin-top:0px}#loco-editor .wg-split>div.locked>.not-first:before{display:none}#loco-editor .has-title>header{background:#e2e2e2;cursor:default !important;margin:0;white-space:nowrap}#loco-editor .wg-content{background:#fff;cursor:default;padding:4px 6px;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#loco-editor .wg-toolbar{top:0;right:0;margin-top:6px;position:absolute}#loco-editor .wg-toolbar>span{color:#fff;background:#000;display:block;padding:0 6px;cursor:default !important}#loco-editor .wg-toolbar>span:active{color:#000;background-color:#fff}#loco-editor .wg-content,#loco-editor .wg-tbody>div{overflow:scroll;overflow-x:hidden;overflow-y:auto}#loco-editor .is-table{background-color:#fff}#loco-editor .is-table .wg-thead .has-title>header{font-weight:normal;background:transparent;padding:4px 0;margin:0 0 0 10px}#loco-editor .is-table .wg-thead>div>.not-first:before{background-position:center center}#loco-editor .is-table .wg-thead{background:#e2e2e2;border-bottom:solid 1px #ccc}#loco-editor .is-table .wg-tbody{background-image:url(data:image/gif;base64,R0lGODlhAQAsAIABAPz8/P///yH5BAEAAAEALAAAAAABACwAAAIIjI+pAe0PIygAOw==);position:relative}#loco-editor .is-table .wg-cols>div{float:left;clear:none}#loco-editor .is-table .wg-cols>div>div{white-space:nowrap;line-height:1.7em;padding-left:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;background-color:#fff}#loco-editor .is-table .wg-cols>div>div:nth-child(even){background-color:#f7f7f7}#loco-editor .is-table .wg-cols>div>div.selected{background-color:#3db63d;color:#fff}#loco-editor .is-table .wg-cols>div>div.selected::selection{background-color:#fff;color:#000}#loco-editor .is-table .wg-cols>div:first-child>div{padding-left:4px}#loco-editor .is-table .wg-dead{clear:both}#loco-editor .is-table .wg-thead .wg-sortable>header{cursor:pointer !important}#loco-editor .is-table .wg-thead .wg-sortable>header:after{padding:0 0 0 5px;color:#999}#loco-editor .is-table .wg-thead .wg-sortable.wg-asc>header:after{content:"▲"}#loco-editor .is-table .wg-thead .wg-sortable.wg-desc>header:after{content:"▼"}#loco-editor .is-table .wg-thead .wg-sortable:hover>header:after{color:#000}#loco-editor .is-field>.wg-content{cursor:text;padding:0;line-height:normal;overflow:hidden;overflow-y:hidden}#loco-editor .is-field>.wg-content>div,#loco-editor .is-field>.wg-content>textarea{font-size:14px;line-height:1.4;border:1px solid #ddd;width:100%;height:100%;padding:8px 10px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0}#loco-editor .is-field>.wg-content textarea{resize:none;overflow:auto;display:block}#loco-editor .is-field>.wg-content>.ace_editor{padding:0;border-width:0}#loco-editor .is-field>.wg-content>div[contenteditable]{overflow:scroll;overflow-x:hidden;overflow-y:auto}#loco-editor .is-readonly>.wg-content{cursor:default}#loco-editor .is-readonly>.wg-content>div,#loco-editor .is-readonly>.wg-content>textarea,#loco-editor .is-readonly>.wg-content>textarea[readonly]{background:#f8f8f8;text-shadow:0 1px #fff;color:inherit}#loco-editor .is-readonly>.wg-content .ace_scroller{cursor:default;background:#f8f8f8}#loco-editor .is-readonly>.wg-content .ace_cursor-layer{display:none}#loco-editor .is-readonly>.wg-content>textarea[readonly]{cursor:default}#loco-editor .is-editable>.wg-content[dir=RTL] .ace_editor .ace_line{direction:ltr;unicode-bidi:bidi-override}#loco-editor .wg-split-x>nav.wg-tabs{white-space:nowrap;text-align:center;cursor:default}#loco-editor .wg-split-x>nav.wg-tabs>a{display:inline-block;padding:.5em 1em;margin-top:.2em;color:#000;text-decoration:none;-webkit-border-radius:.2em .2em 0 0;-moz-border-radius:.2em .2em 0 0;-ms-border-radius:.2em .2em 0 0;-o-border-radius:.2em .2em 0 0;border-radius:.2em .2em 0 0;background-color:#f3f7fd}#loco-editor .wg-split-x>nav.wg-tabs>a:hover{background-color:#fff}#loco-editor .wg-split-x>nav.wg-tabs>a.active{background-color:#3db63d;color:#fff}#loco-editor .wg-split>div>.has-nav>.wg-body{margin-top:0px}#loco-editor .wg-dead{visibility:hidden}@media all and (max-width: 768px){#loco-editor .wg-split-x>div>.not-first>*{margin-left:20px}#loco-editor .wg-split-y>div>.not-first>*{margin-top:20px}#loco-editor .wg-split-x>div>.not-first:before{width:20px}#loco-editor .wg-split-y>div>.not-first:before{height:20px}#loco-editor .is-table .wg-thead header{padding-left:20px}}#loco-editor .is-table .po-fuzzy{color:#b59829;font-weight:bold}#loco-editor .is-table .po-empty{color:#1f507a;font-weight:bold}#loco-editor .is-table .po-flagged{color:#bd2c00}#loco-editor .is-table .wg-cols>div:first-child>div:before{font-family:loco;vertical-align:inherit;display:inline-block;content:" ";width:1.3em;line-height:1}#loco-editor .is-table .wg-cols>div:first-child>div.po-fuzzy:before{content:""}#loco-editor .is-table .wg-cols>div:first-child>div.po-flagged:before{content:""}#loco-editor .is-table .wg-cols>div:first-child>div.po-comment:before{content:"";color:#999}#loco-editor .is-table .wg-cols>div:first-child>div.po-unsaved:before{content:"";color:#f1d040}#loco-editor .is-table .wg-cols>div:first-child>div.selected:before{color:#fff !important}#loco-editor .wg-cell>.meta{color:#333;margin:0 !important;padding:6px 10px;font-weight:normal;font-size:13px;line-height:1.4em;cursor:default !important}#loco-editor .wg-cell>.meta>*{display:inline-block;margin-top:3px;margin-bottom:3px}#loco-editor .wg-cell>.meta>span{border:1px solid transparent;border-left:none}#loco-editor .wg-cell>.meta>mark{color:#fff;border-radius:2px;background-color:silver;border:1px solid silver;padding:0 .3em}#loco-editor .wg-cell>.meta>mark.tag{color:#999;background-color:#eee}#loco-editor .wg-cell>.meta>p{display:block;white-space:pre-line}#loco-editor .wg-cell>.meta .icon-warn{color:#c00}#loco-editor .wg-cell>.meta .has-icon:before{padding-right:0;width:17px}#loco-editor .wg-cell>.meta code{font-size:12px}#loco-editor .is-table .wg-cols>div>div>mark{display:inline-block;vertical-align:text-bottom;font:inherit;font-weight:normal;color:#fff;border-radius:2px;font-size:90%;line-height:1;padding:.2em .3em;background-color:rgba(0,0,0,.25)}#loco-editor .is-table .wg-cols>div>div.selected.po-flagged{background-color:#bd2c00}#loco-editor .is-table .wg-cols>div>div.selected.po-fuzzy{background-color:#b59829}#loco-editor .is-table .wg-cols>div>div.selected.po-empty{background-color:#999}#loco-editor #po-target header nav{display:block;position:absolute;right:0px;top:0px;padding:2px}#loco-editor #po-target header nav button{margin-left:5px}#loco-editor #po-target header nav.po-empty .icon-cloud{display:none !important}#loco-editor #po-list .wg-content{padding:0}#loco-editor #po-source>.wg-body>.has-title>header{background:transparent;font-weight:normal;float:left;clear:none;min-width:3.4em}#loco-editor #po-source>.wg-body>.has-title>.wg-content{clear:none}#loco-editor .has-title>header{line-height:normal;padding:6px}#loco-editor .has-title>header .lang{margin-right:6px;margin-bottom:1px}#loco-editor .trg-rtl #po-list-tbody .wg-cols>div[for=po-list-col-target]>div,#loco-editor .src-rtl #po-list-tbody .wg-cols>div[for=po-list-col-source]>div{direction:rtl;padding-left:0;padding-right:10px;text-align:right}#loco-editor #po-source>.wg-body>.has-title>h2{min-width:4.5em}#loco-editor .is-table .wg-td{font-size:13px}#loco-editor header,#loco-editor nav{display:block;position:relative}#loco-editor-inner{min-height:600px;font-size:14px;clear:both}#loco-editor-inner>div.loco-loading{height:100px;background:transparent url(../img/spin-editor-button.gif?v=2.6.0) center 20px no-repeat}#loco-editor-inner h2{color:#000;line-height:1}#loco-editor-inner .wg-cell>.meta code{padding:0;color:#0073aa;background:inherit;cursor:pointer}#loco-editor-inner .wg-cell>.meta code:hover{text-decoration:underline}#loco-admin.wrap #loco-editor>nav{font-size:14px;height:50px}#loco-admin.wrap #loco-editor>nav form{display:block;float:left;clear:none;padding:0;margin:0}#loco-admin.wrap #loco-editor>nav form.aux{float:right;margin-right:5px}#loco-admin.wrap #loco-editor>nav fieldset{display:block;position:relative;float:left;clear:none}#loco-admin.wrap #loco-editor>nav button,#loco-admin.wrap #loco-editor>nav input[type=text]{display:block;position:relative;float:left;clear:none;margin:5px 0 0 5px;height:36px;text-align:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#loco-admin.wrap #loco-editor>nav input[type=text]{padding:0 10px;font-size:14px;line-height:normal}#loco-admin.wrap #loco-editor>nav .invalid input[type=text]:focus{border-color:#c00;-webkit-box-shadow:0 0 2px rgba(153,0,0,.5);-moz-box-shadow:0 0 2px rgba(153,0,0,.5);box-shadow:0 0 2px rgba(153,0,0,.5)}#loco-admin.wrap #loco-editor>nav .loco-clearable{padding:0 20px}#loco-admin.wrap #loco-editor>nav .loco-clearable.invalid a.clear:before{color:#c00}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear{right:25px;line-height:2}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear:hover:before{color:#c00}#loco-admin.wrap #loco-editor>nav .loco-clearable a.clear:active:before{color:#000}#loco-admin.wrap #loco-editor>nav button.only-icon{width:40px}#loco-admin.wrap button.has-icon:before{width:16px;padding:0}#loco-admin.wrap button.has-icon.loco-loading:before{content:" ";height:16px;background:transparent url(../img/spin-editor-button.gif?v=2.6.0) 0 0 no-repeat}#loco-admin.wrap .button,#loco-admin.wrap .button-link,#loco-admin.wrap input[type=text]{border-color:#aaa;color:#444}#loco-admin.wrap .button:hover,#loco-admin.wrap .button-link:hover{color:#000}#loco-admin.wrap .button-primary,#loco-admin.wrap .button-primary:hover{color:#fff}#loco-admin.wrap button.icon-translate:before{font-size:16px}.loco-modal .loco-api{position:relative;padding:10px;background:#f7f7f7;border:solid 1px #eee;font-size:14px;margin-bottom:16px}.loco-modal .loco-api p{padding:0;margin:0;font-size:inherit}.loco-modal .loco-api blockquote{font-weight:bold;margin:0;padding:10px 0}.loco-modal .loco-api a.loco-api-credit{padding:0;display:block;position:absolute;right:10px;bottom:10px;text-decoration:none;white-space:nowrap;overflow:hidden;font-size:12px}.loco-modal .loco-api a.loco-api-credit:hover{text-decoration:underline}.loco-modal .loco-api-loading{text-indent:20px;background:transparent url(../img/spin-modal.gif?v=2.6.0) 10px center no-repeat}.loco-modal .loco-alert p{margin-bottom:2em;font-size:14px}.loco-modal .loco-alert nav{display:block;position:relative;margin:1em 0}.loco-modal .loco-alert nav a{display:inline-block;margin-right:1em;padding:10px}#loco-auto{display:none;min-width:50%;min-height:300px;position:relative}#loco-auto form blockquote{margin:0;padding:1em 0;font-size:14px}.loco-api a.loco-api-credit{color:inherit}.loco-api-google a.loco-api-credit{text-indent:200px;width:122px;height:16px;background:transparent url(../img/api/google.png?v=2.6.0) 0 0 no-repeat}.loco-api-microsoft a.loco-api-credit{text-indent:200px;width:152px;height:16px;background:transparent url(../img/api/microsoft.png?v=2.6.0) 0 0 no-repeat}.loco-api-deepl a.loco-api-credit{text-indent:200px;width:122px;height:16px;background:transparent url(../img/api/deepl.png?v=2.6.0) 0 0 no-repeat}
pub/css/podiff.css CHANGED
@@ -1 +1 @@
1
- #loco-admin.wrap .revisions-diff{padding:10px;min-height:20px}#loco-admin.wrap table.diff{border-collapse:collapse;table-layout:auto}#loco-admin.wrap table.diff td{white-space:nowrap;overflow:hidden;font:normal 12px/17px "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;padding:2px}#loco-admin.wrap table.diff td>span{color:#aaa}#loco-admin.wrap table.diff td>span:after{content:". "}#loco-admin.wrap table.diff tbody{border-top:1px dashed #ccc}#loco-admin.wrap table.diff tbody:first-child{border-top:none}#loco-admin.wrap table.diff td>.dashicons{display:none}#loco-admin.wrap .revisions.loading .diff-meta{color:#eee}#loco-admin.wrap .revisions.loading .loading-indicator span.spinner{visibility:visible;background:#fff url(../img/spin-modal.gif?v=2.5.8) center center no-repeat}#loco-admin.wrap .revisions-meta{clear:both;padding:10px 12px;margin:0;position:relative;top:10px}#loco-admin.wrap .revisions-meta .diff-meta{clear:none;float:left;width:50%;padding:0;min-height:auto}#loco-admin.wrap .revisions-meta .diff-meta button{margin-top:5px}#loco-admin.wrap .revisions-meta .diff-meta-current{float:right;text-align:right}#loco-admin.wrap .revisions-meta time{color:#72777c}#loco-admin.wrap .revisions-control-frame{margin:10px 0}#loco-admin.wrap .revisions-diff-frame{margin-top:20px}
1
+ #loco-admin.wrap .revisions-diff{padding:10px;min-height:20px}#loco-admin.wrap table.diff{border-collapse:collapse;table-layout:auto}#loco-admin.wrap table.diff td{white-space:nowrap;overflow:hidden;font:normal 12px/17px "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;padding:2px}#loco-admin.wrap table.diff td>span{color:#aaa}#loco-admin.wrap table.diff td>span:after{content:". "}#loco-admin.wrap table.diff tbody{border-top:1px dashed #ccc}#loco-admin.wrap table.diff tbody:first-child{border-top:none}#loco-admin.wrap table.diff td>.dashicons{display:none}#loco-admin.wrap .revisions.loading .diff-meta{color:#eee}#loco-admin.wrap .revisions.loading .loading-indicator span.spinner{visibility:visible;background:#fff url(../img/spin-modal.gif?v=2.6.0) center center no-repeat}#loco-admin.wrap .revisions-meta{clear:both;padding:10px 12px;margin:0;position:relative;top:10px}#loco-admin.wrap .revisions-meta .diff-meta{clear:none;float:left;width:50%;padding:0;min-height:auto}#loco-admin.wrap .revisions-meta .diff-meta button{margin-top:5px}#loco-admin.wrap .revisions-meta .diff-meta-current{float:right;text-align:right}#loco-admin.wrap .revisions-meta time{color:#72777c}#loco-admin.wrap .revisions-control-frame{margin:10px 0}#loco-admin.wrap .revisions-diff-frame{margin-top:20px}
pub/css/poview.css CHANGED
@@ -1 +1 @@
1
- .js #loco-admin.wrap .loco-loading{min-height:100px;background:#fff url(../img/spin-modal.gif?v=2.5.8) center center no-repeat}.js #loco-admin.wrap .loco-loading ol.msgcat{display:none}#loco-admin.wrap #loco-po{padding-right:0;overflow:auto}#loco-admin.wrap ol.msgcat{margin-left:3em;padding-top:1em;border-top:1px dashed #ccc}#loco-admin.wrap ol.msgcat:first-child{padding-top:0;border-top:none}#loco-admin.wrap ol.msgcat li{color:#aaa;margin:0;padding:0 0 0 1em;font:normal 12px/17px "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;border-left:1px solid #eee}#loco-admin.wrap ol.msgcat li>*{color:#333;white-space:pre}#loco-admin.wrap ol.msgcat li>.po-comment{color:#3cc200}#loco-admin.wrap ol.msgcat li>.po-refs{color:#0073aa}#loco-admin.wrap ol.msgcat li>.po-refs a{color:inherit;text-decoration:none}#loco-admin.wrap ol.msgcat li>.po-refs a:hover{text-decoration:underline}#loco-admin.wrap ol.msgcat li>.po-flags{color:#77904a}#loco-admin.wrap ol.msgcat li>.po-flags em{font-style:normal}#loco-admin.wrap ol.msgcat li>.po-word{color:#000}#loco-admin.wrap ol.msgcat li>.po-junk{font-style:italic;color:#ccc}#loco-admin.wrap ol.msgcat li>.po-string>span{color:#c931c7}#loco-admin.wrap form.loco-filter{top:0;right:0;position:absolute}#loco-admin.wrap .loco-invalid form.loco-filter input[type=text]:focus{border-color:#c00;-webkit-box-shadow:0 0 2px rgba(153,0,0,.5);-moz-box-shadow:0 0 2px rgba(153,0,0,.5);box-shadow:0 0 2px rgba(153,0,0,.5)}#loco-admin.wrap .loco-invalid ol.msgcat{list-style-type:none}#loco-admin.wrap .loco-invalid ol.msgcat li{color:#000}
1
+ .js #loco-admin.wrap .loco-loading{min-height:100px;background:#fff url(../img/spin-modal.gif?v=2.6.0) center center no-repeat}.js #loco-admin.wrap .loco-loading ol.msgcat{display:none}#loco-admin.wrap #loco-po{padding-right:0;overflow:auto}#loco-admin.wrap ol.msgcat{margin-left:3em;padding-top:1em;border-top:1px dashed #ccc}#loco-admin.wrap ol.msgcat:first-child{padding-top:0;border-top:none}#loco-admin.wrap ol.msgcat li{color:#aaa;margin:0;padding:0 0 0 1em;font:normal 12px/17px "Monaco","Menlo","Ubuntu Mono","Consolas","source-code-pro",monospace;border-left:1px solid #eee}#loco-admin.wrap ol.msgcat li>*{color:#333;white-space:pre}#loco-admin.wrap ol.msgcat li>.po-comment{color:#3cc200}#loco-admin.wrap ol.msgcat li>.po-refs{color:#0073aa}#loco-admin.wrap ol.msgcat li>.po-refs a{color:inherit;text-decoration:none}#loco-admin.wrap ol.msgcat li>.po-refs a:hover{text-decoration:underline}#loco-admin.wrap ol.msgcat li>.po-flags{color:#77904a}#loco-admin.wrap ol.msgcat li>.po-flags em{font-style:normal}#loco-admin.wrap ol.msgcat li>.po-word{color:#000}#loco-admin.wrap ol.msgcat li>.po-junk{font-style:italic;color:#ccc}#loco-admin.wrap ol.msgcat li>.po-string>span{color:#c931c7}#loco-admin.wrap form.loco-filter{top:0;right:0;position:absolute}#loco-admin.wrap .loco-invalid form.loco-filter input[type=text]:focus{border-color:#c00;-webkit-box-shadow:0 0 2px rgba(153,0,0,.5);-moz-box-shadow:0 0 2px rgba(153,0,0,.5);box-shadow:0 0 2px rgba(153,0,0,.5)}#loco-admin.wrap .loco-invalid ol.msgcat{list-style-type:none}#loco-admin.wrap .loco-invalid ol.msgcat li{color:#000}
pub/css/skins/blue.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(9,100,132,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#096484;foo:#096484}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1cdc7 !important;background:#db9925 !important;border-color:#db9925 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/blue/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(9,100,132,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#096484;foo:#096484}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1cdc7 !important;background:#db9925 !important;border-color:#db9925 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/blue/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/coffee.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(199,165,137,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#c7a589;foo:#c7a589}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1ccc7 !important;background:#ba906d !important;border-color:#ba906d !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/coffee/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(199,165,137,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#c7a589;foo:#c7a589}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1ccc7 !important;background:#ba906d !important;border-color:#ba906d !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/coffee/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/ectoplasm.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(163,183,69,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#a3b745;foo:#a3b745}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#cfd1c7 !important;background:#89993a !important;border-color:#89993a !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/ectoplasm/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(163,183,69,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#a3b745;foo:#a3b745}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#cfd1c7 !important;background:#89993a !important;border-color:#89993a !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/ectoplasm/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/light.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(136,136,136,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#888;foo:#04a4cc}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#c7cfd1 !important;background:#0384a4 !important;border-color:#0384a4 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/light/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(136,136,136,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#888;foo:#04a4cc}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#c7cfd1 !important;background:#0384a4 !important;border-color:#0384a4 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/light/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/midnight.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(225,77,67,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#e14d43;foo:#e14d43}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1c8c7 !important;background:#d92e23 !important;border-color:#d92e23 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/midnight/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(225,77,67,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#e14d43;foo:#e14d43}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1c8c7 !important;background:#d92e23 !important;border-color:#d92e23 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/midnight/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/modern.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(56,88,233,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#3858e9;foo:#3858e9}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#c7c9d1 !important;background:#193ddf !important;border-color:#193ddf !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/modern/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(56,88,233,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#3858e9;foo:#3858e9}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#c7c9d1 !important;background:#193ddf !important;border-color:#193ddf !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/modern/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/ocean.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(158,186,160,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#9ebaa0;foo:#9ebaa0}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#c7d1c8 !important;background:#86a989 !important;border-color:#86a989 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/ocean/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(158,186,160,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#9ebaa0;foo:#9ebaa0}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#c7d1c8 !important;background:#86a989 !important;border-color:#86a989 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/ocean/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/css/skins/sunrise.css CHANGED
@@ -1 +1 @@
1
- .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(221,130,59,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#dd823b;foo:#dd823b}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1cbc7 !important;background:#cc6d23 !important;border-color:#cc6d23 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/sunrise/spin-primary-button.gif?v=2.5.8) 0 0 no-repeat !important}
1
+ .wrap #loco-editor .is-table .wg-tr:nth-child(even){background-color:rgba(221,130,59,.05)}.wrap #loco-editor .wg-split-x>nav.wg-tabs>a.active,.wrap #loco-editor .is-table .wg-cols>div>div.selected{background-color:#dd823b;foo:#dd823b}.wrap #loco-editor .is-editable>.wg-content>textarea:focus,.wrap #loco-editor .is-editable>.wg-content.has-focus .ace_scroller,.wrap #loco-editor .is-editable>.wg-content.has-focus .mce-content-body{border-color:#5b9dd9;-webkit-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);-moz-box-shadow:inset 0 0 .6em rgba(30,140,190,.8);box-shadow:inset 0 0 .6em rgba(30,140,190,.8)}.wp-core-ui .button-primary.loco-loading[disabled]{color:#d1cbc7 !important;background:#cc6d23 !important;border-color:#cc6d23 !important}.wp-core-ui .button-primary.loco-loading[disabled]:before{background:transparent url(../../img/skins/sunrise/spin-primary-button.gif?v=2.6.0) 0 0 no-repeat !important}
pub/font/loco.eot CHANGED
Binary file
pub/font/loco.svg CHANGED
@@ -18,6 +18,7 @@
18
  <glyph unicode="&#x2026;" glyph-name="hellip" horiz-adv-x="805" d="M0 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM292.571 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM585.143 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857z" />
19
  <glyph unicode="&#x205e;" glyph-name="vellip" horiz-adv-x="219" d="M0 128v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM0 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM0 713.143v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857z" />
20
  <glyph unicode="&#x2139;" glyph-name="info" horiz-adv-x="878" d="M585.143 164.571v91.429q0 8-5.143 13.143t-13.143 5.143h-54.857v292.571q0 8-5.143 13.143t-13.143 5.143h-182.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h54.857v-182.857h-54.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h256q8 0 13.143 5.143t5.143 13.143zM512 676.571v91.429q0 8-5.143 13.143t-13.143 5.143h-109.714q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
 
21
  <glyph unicode="&#x25b2;" glyph-name="caret-up" horiz-adv-x="585" d="M585.143 256q0-14.857-10.857-25.714t-25.714-10.857h-512q-14.857 0-25.714 10.857t-10.857 25.714 10.857 25.714l256 256q10.857 10.857 25.714 10.857t25.714-10.857l256-256q10.857-10.857 10.857-25.714z" />
22
  <glyph unicode="&#x25b6;" glyph-name="caret-right" horiz-adv-x="366" d="M329.143 438.857q0-14.857-10.857-25.714l-256-256q-10.857-10.857-25.714-10.857t-25.714 10.857-10.857 25.714v512q0 14.857 10.857 25.714t25.714 10.857 25.714-10.857l256-256q10.857-10.857 10.857-25.714z" />
23
  <glyph unicode="&#x25bc;" glyph-name="caret-down" horiz-adv-x="585" d="M585.143 548.571q0-14.857-10.857-25.714l-256-256q-10.857-10.857-25.714-10.857t-25.714 10.857l-256 256q-10.857 10.857-10.857 25.714t10.857 25.714 25.714 10.857h512q14.857 0 25.714-10.857t10.857-25.714z" />
@@ -91,7 +92,6 @@
91
  <glyph unicode="&#xe901;" glyph-name="max" d="M1024 960v-384l-138.26 138.26-212-212-107.48 107.48 212 212-138.26 138.26zM245.74 821.74l212-212-107.48-107.48-212 212-138.26-138.26v384h384zM885.74 181.74l138.26 138.26v-384h-384l138.26 138.26-212 212 107.48 107.48zM457.74 286.26l-212-212 138.26-138.26h-384v384l138.26-138.26 212 212z" />
92
  <glyph unicode="&#xe902;" glyph-name="min" d="M64 384h384v-384l-138.26 138.26-202-202-107.48 107.48 202 202zM821.74 245.74l202-202-107.48-107.48-202 202-138.26-138.26v384h384zM960 512h-384v384l138.26-138.26 202 202 107.48-107.48-202-202zM309.74 757.74l138.26 138.26v-384h-384l138.26 138.26-202 202 107.48 107.48z" />
93
  <glyph unicode="&#xe903;" glyph-name="sort" d="M0 576h704v-128h-704v128zM0 768h704v-128h-704v128zM0 384h704v-128h-704v128zM0 192h704v-128h-704v128zM768 384l128-192 128 192h-256zM1024 448l-128 192-128-192h256z" />
94
- <glyph unicode="&#xe904;" glyph-name="share" d="M864 256c-45.16 0-85.92-18.738-115.012-48.83l-431.004 215.502c1.314 8.252 2.016 16.706 2.016 25.328s-0.702 17.076-2.016 25.326l431.004 215.502c29.092-30.090 69.852-48.828 115.012-48.828 88.366 0 160 71.634 160 160s-71.634 160-160 160-160-71.634-160-160c0-8.622 0.704-17.076 2.016-25.326l-431.004-215.504c-29.092 30.090-69.852 48.83-115.012 48.83-88.366 0-160-71.636-160-160 0-88.368 71.634-160 160-160 45.16 0 85.92 18.738 115.012 48.828l431.004-215.502c-1.312-8.25-2.016-16.704-2.016-25.326 0-88.368 71.634-160 160-160s160 71.632 160 160c0 88.364-71.634 160-160 160z" />
95
  <glyph unicode="&#xe906;" glyph-name="notag" d="M949.632 482.994l-408.455 410.066c-10.94 10.997-25.826 17.163-41.323 17.163h-384.156c-32.215 0-58.347-26.132-58.347-58.404v-384.128c0-15.497 6.165-30.354 17.108-41.296l409.289-409.316c11.385-11.385 26.327-17.079 41.239-17.079s29.854 5.694 41.239 17.079l383.323 383.351c22.773 22.772 22.8 59.737 0.084 82.564zM810.028 421.731l-264.964-264.964c-11.109-11.108-29.074-11.108-40.156 0l-333.863 333.89v277.349c0 15.691 12.718 28.437 28.382 28.437h277.46l333.168-334.5c11.108-11.109 11.052-29.104-0.027-40.213zM455.198 597.326c0-47.127-38.185-85.34-85.257-85.34-47.1 0-85.257 38.213-85.257 85.34 0 47.129 38.156 85.34 85.257 85.34 47.070 0 85.257-38.212 85.257-85.34z" />
96
  <glyph unicode="&#xf062;" glyph-name="arrow-up" horiz-adv-x="951" d="M30.286 396q0 30.286 21.714 52l372 372q20 21.143 51.429 21.143 30.857 0 52-21.143l372-372q21.143-22.286 21.143-52 0-29.143-21.143-51.429l-42.857-42.857q-21.714-21.714-52-21.714-30.857 0-51.429 21.714l-168 167.429v-402.286q0-29.714-21.429-48.286t-51.714-18.571h-73.143q-30.286 0-51.714 18.571t-21.429 48.286v402.286l-168-167.429q-20.571-21.714-51.429-21.714t-51.429 21.714l-42.857 42.857q-21.714 21.714-21.714 51.429z" />
97
  <glyph unicode="&#xf073;" glyph-name="calendar" horiz-adv-x="951" d="M0 0v731.429q0 29.714 21.714 51.429t51.429 21.714h73.143v54.857q0 37.714 26.857 64.571t64.571 26.857h36.571q37.714 0 64.571-26.857t26.857-64.571v-54.857h219.429v54.857q0 37.714 26.857 64.571t64.571 26.857h36.571q37.714 0 64.571-26.857t26.857-64.571v-54.857h73.143q29.714 0 51.429-21.714t21.714-51.429v-731.429q0-29.714-21.714-51.429t-51.429-21.714h-804.571q-29.714 0-51.429 21.714t-21.714 51.429zM73.143 0h164.571v164.571h-164.571v-164.571zM73.143 201.143h164.571v182.857h-164.571v-182.857zM73.143 420.571h164.571v164.571h-164.571v-164.571zM219.429 694.857q0-7.429 5.429-12.857t12.857-5.429h36.571q7.429 0 12.857 5.429t5.429 12.857v164.571q0 7.429-5.429 12.857t-12.857 5.429h-36.571q-7.429 0-12.857-5.429t-5.429-12.857v-164.571zM274.286 0h182.857v164.571h-182.857v-164.571zM274.286 201.143h182.857v182.857h-182.857v-182.857zM274.286 420.571h182.857v164.571h-182.857v-164.571zM493.714 0h182.857v164.571h-182.857v-164.571zM493.714 201.143h182.857v182.857h-182.857v-182.857zM493.714 420.571h182.857v164.571h-182.857v-164.571zM658.286 694.857q0-7.429 5.429-12.857t12.857-5.429h36.571q7.429 0 12.857 5.429t5.429 12.857v164.571q0 7.429-5.429 12.857t-12.857 5.429h-36.571q-7.429 0-12.857-5.429t-5.429-12.857v-164.571zM713.143 0h164.571v164.571h-164.571v-164.571zM713.143 201.143h164.571v182.857h-164.571v-182.857zM713.143 420.571h164.571v164.571h-164.571v-164.571z" />
18
  <glyph unicode="&#x2026;" glyph-name="hellip" horiz-adv-x="805" d="M0 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM292.571 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM585.143 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857z" />
19
  <glyph unicode="&#x205e;" glyph-name="vellip" horiz-adv-x="219" d="M0 128v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM0 420.571v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857zM0 713.143v109.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-109.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857z" />
20
  <glyph unicode="&#x2139;" glyph-name="info" horiz-adv-x="878" d="M585.143 164.571v91.429q0 8-5.143 13.143t-13.143 5.143h-54.857v292.571q0 8-5.143 13.143t-13.143 5.143h-182.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h54.857v-182.857h-54.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h256q8 0 13.143 5.143t5.143 13.143zM512 676.571v91.429q0 8-5.143 13.143t-13.143 5.143h-109.714q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
21
+ <glyph unicode="&#x2191;" glyph-name="share" d="M682 724.667l-60-60-68 68v-476h-84v476l-68-68-60 60 170 172zM854 512.667v-470q0-36-25-61t-61-25h-512q-36 0-61 25t-25 61v470q0 34 25 59t61 25h128v-84h-128v-470h512v470h-128v84h128q36 0 61-25t25-59z" />
22
  <glyph unicode="&#x25b2;" glyph-name="caret-up" horiz-adv-x="585" d="M585.143 256q0-14.857-10.857-25.714t-25.714-10.857h-512q-14.857 0-25.714 10.857t-10.857 25.714 10.857 25.714l256 256q10.857 10.857 25.714 10.857t25.714-10.857l256-256q10.857-10.857 10.857-25.714z" />
23
  <glyph unicode="&#x25b6;" glyph-name="caret-right" horiz-adv-x="366" d="M329.143 438.857q0-14.857-10.857-25.714l-256-256q-10.857-10.857-25.714-10.857t-25.714 10.857-10.857 25.714v512q0 14.857 10.857 25.714t25.714 10.857 25.714-10.857l256-256q10.857-10.857 10.857-25.714z" />
24
  <glyph unicode="&#x25bc;" glyph-name="caret-down" horiz-adv-x="585" d="M585.143 548.571q0-14.857-10.857-25.714l-256-256q-10.857-10.857-25.714-10.857t-25.714 10.857l-256 256q-10.857 10.857-10.857 25.714t10.857 25.714 25.714 10.857h512q14.857 0 25.714-10.857t10.857-25.714z" />
92
  <glyph unicode="&#xe901;" glyph-name="max" d="M1024 960v-384l-138.26 138.26-212-212-107.48 107.48 212 212-138.26 138.26zM245.74 821.74l212-212-107.48-107.48-212 212-138.26-138.26v384h384zM885.74 181.74l138.26 138.26v-384h-384l138.26 138.26-212 212 107.48 107.48zM457.74 286.26l-212-212 138.26-138.26h-384v384l138.26-138.26 212 212z" />
93
  <glyph unicode="&#xe902;" glyph-name="min" d="M64 384h384v-384l-138.26 138.26-202-202-107.48 107.48 202 202zM821.74 245.74l202-202-107.48-107.48-202 202-138.26-138.26v384h384zM960 512h-384v384l138.26-138.26 202 202 107.48-107.48-202-202zM309.74 757.74l138.26 138.26v-384h-384l138.26 138.26-202 202 107.48 107.48z" />
94
  <glyph unicode="&#xe903;" glyph-name="sort" d="M0 576h704v-128h-704v128zM0 768h704v-128h-704v128zM0 384h704v-128h-704v128zM0 192h704v-128h-704v128zM768 384l128-192 128 192h-256zM1024 448l-128 192-128-192h256z" />
 
95
  <glyph unicode="&#xe906;" glyph-name="notag" d="M949.632 482.994l-408.455 410.066c-10.94 10.997-25.826 17.163-41.323 17.163h-384.156c-32.215 0-58.347-26.132-58.347-58.404v-384.128c0-15.497 6.165-30.354 17.108-41.296l409.289-409.316c11.385-11.385 26.327-17.079 41.239-17.079s29.854 5.694 41.239 17.079l383.323 383.351c22.773 22.772 22.8 59.737 0.084 82.564zM810.028 421.731l-264.964-264.964c-11.109-11.108-29.074-11.108-40.156 0l-333.863 333.89v277.349c0 15.691 12.718 28.437 28.382 28.437h277.46l333.168-334.5c11.108-11.109 11.052-29.104-0.027-40.213zM455.198 597.326c0-47.127-38.185-85.34-85.257-85.34-47.1 0-85.257 38.213-85.257 85.34 0 47.129 38.156 85.34 85.257 85.34 47.070 0 85.257-38.212 85.257-85.34z" />
96
  <glyph unicode="&#xf062;" glyph-name="arrow-up" horiz-adv-x="951" d="M30.286 396q0 30.286 21.714 52l372 372q20 21.143 51.429 21.143 30.857 0 52-21.143l372-372q21.143-22.286 21.143-52 0-29.143-21.143-51.429l-42.857-42.857q-21.714-21.714-52-21.714-30.857 0-51.429 21.714l-168 167.429v-402.286q0-29.714-21.429-48.286t-51.714-18.571h-73.143q-30.286 0-51.714 18.571t-21.429 48.286v402.286l-168-167.429q-20.571-21.714-51.429-21.714t-51.429 21.714l-42.857 42.857q-21.714 21.714-21.714 51.429z" />
97
  <glyph unicode="&#xf073;" glyph-name="calendar" horiz-adv-x="951" d="M0 0v731.429q0 29.714 21.714 51.429t51.429 21.714h73.143v54.857q0 37.714 26.857 64.571t64.571 26.857h36.571q37.714 0 64.571-26.857t26.857-64.571v-54.857h219.429v54.857q0 37.714 26.857 64.571t64.571 26.857h36.571q37.714 0 64.571-26.857t26.857-64.571v-54.857h73.143q29.714 0 51.429-21.714t21.714-51.429v-731.429q0-29.714-21.714-51.429t-51.429-21.714h-804.571q-29.714 0-51.429 21.714t-21.714 51.429zM73.143 0h164.571v164.571h-164.571v-164.571zM73.143 201.143h164.571v182.857h-164.571v-182.857zM73.143 420.571h164.571v164.571h-164.571v-164.571zM219.429 694.857q0-7.429 5.429-12.857t12.857-5.429h36.571q7.429 0 12.857 5.429t5.429 12.857v164.571q0 7.429-5.429 12.857t-12.857 5.429h-36.571q-7.429 0-12.857-5.429t-5.429-12.857v-164.571zM274.286 0h182.857v164.571h-182.857v-164.571zM274.286 201.143h182.857v182.857h-182.857v-182.857zM274.286 420.571h182.857v164.571h-182.857v-164.571zM493.714 0h182.857v164.571h-182.857v-164.571zM493.714 201.143h182.857v182.857h-182.857v-182.857zM493.714 420.571h182.857v164.571h-182.857v-164.571zM658.286 694.857q0-7.429 5.429-12.857t12.857-5.429h36.571q7.429 0 12.857 5.429t5.429 12.857v164.571q0 7.429-5.429 12.857t-12.857 5.429h-36.571q-7.429 0-12.857-5.429t-5.429-12.857v-164.571zM713.143 0h164.571v164.571h-164.571v-164.571zM713.143 201.143h164.571v182.857h-164.571v-182.857zM713.143 420.571h164.571v164.571h-164.571v-164.571z" />
pub/font/loco.ttf CHANGED
Binary file
pub/font/loco.woff CHANGED
Binary file
pub/js/min/admin.js CHANGED
@@ -1,23 +1,23 @@
1
- (function(y, w, k, J) {
2
  var n = function() {
3
  function f(d) {
4
  throw Error("Failed to require " + d);
5
  }
6
  var d = {};
7
  return {
8
- register: function(f, m) {
9
- d[f] = m;
10
  },
11
- require: function(k, m) {
12
- return d[k] || f(m);
13
  },
14
- include: function(k, m, g) {
15
- return d[k] || (g ? f(m) : null);
16
  }
17
  };
18
  }();
19
  n.register("$1", function(f, d, k) {
20
- function m(g) {
21
  var c = typeof g;
22
  if ("string" === c) if (/[^ <>!=()%^&|?:n0-9]/.test(g)) console.error("Invalid plural: " + g); else return new Function("n", "return " + g);
23
  "function" !== c && (g = function(b) {
@@ -40,7 +40,7 @@ e = Number(g(e));
40
  isNaN(e) && (e = 0);
41
  return c(a, e ? b : a, e);
42
  }
43
- g = m(g);
44
  var h = {};
45
  return {
46
  __: b,
@@ -54,13 +54,13 @@ h = a || {};
54
  return this;
55
  },
56
  pluraleq: function(a) {
57
- g = m(a);
58
  return this;
59
  }
60
  };
61
  };
62
  return f;
63
- }({}, y, w));
64
  n.register("$2", function(f, d, k) {
65
  f.ie = function() {
66
  var f = !1, g = 0;
@@ -74,7 +74,7 @@ f.init = function() {
74
  return f;
75
  };
76
  return f;
77
- }({}, y, w));
78
  n.register("$3", function(f, d, k) {
79
  Number.prototype.format = function(d, g, c) {
80
  d = Math.pow(10, d || 0);
@@ -108,7 +108,7 @@ d = d.substr(1);
108
  return d;
109
  };
110
  return f;
111
- }({}, y, w));
112
  n.register("$4", function(f, d, k) {
113
  Array.prototype.indexOf || (Array.prototype.indexOf = function(d) {
114
  if (null == this) throw new TypeError();
@@ -121,14 +121,14 @@ for (g = 0 <= g ? g : Math.max(b - Math.abs(g), 0); g < b; g++) if (g in c && c[
121
  return -1;
122
  });
123
  return f;
124
- }({}, y, w));
125
  n.register("$5", function(f, d, n) {
126
  d.JSON || (d.JSON = {
127
  parse: k.parseJSON,
128
  stringify: null
129
  });
130
  return f = d.JSON;
131
- }({}, y, w));
132
  n.register("$6", function(f, d, k) {
133
  f.trim = function(d, g) {
134
  for (g || (g = " \n"); d && -1 !== g.indexOf(d.substr(0, 1)); ) d = d.substr(1);
@@ -142,16 +142,16 @@ return "%" === e ? "%" : (a ? c[Number(a) - 1] : c[g++]) || "";
142
  });
143
  };
144
  return f;
145
- }({}, y, w));
146
  n.register("$21", function(f, d, k) {
147
- function m(g) {
148
  return function(c, b) {
149
  for (var a = c[g] || 0; (c = c.offsetParent) && c !== (b || k.body); ) a += c[g] || 0;
150
  return a;
151
  };
152
  }
153
- f.top = m("offsetTop");
154
- f.left = m("offsetLeft");
155
  f.el = function(g, c) {
156
  var b = k.createElement(g || "div");
157
  c && (b.className = c);
@@ -161,23 +161,23 @@ f.txt = function(g) {
161
  return k.createTextNode(g || "");
162
  };
163
  return f;
164
- }({}, y, w));
165
  n.register("$7", function(f, d, D) {
166
- function m(a, b, e) {
167
  function c() {
168
- p();
169
  v = setTimeout(b, e);
170
  }
171
- function p() {
172
  v && clearTimeout(v);
173
  v = null;
174
  }
175
  var v;
176
  c();
177
- k(a).on("mouseenter", p).on("mouseleave", c);
178
  return {
179
  die: function() {
180
- p();
181
  k(a).off("mouseenter mouseleave");
182
  }
183
  };
@@ -195,33 +195,33 @@ function c(a, b) {
195
  function e(b) {
196
  q[v] = null;
197
  g(k(a), 250);
198
- p && p.die();
199
  var c;
200
  if (c = b) b.stopPropagation(), b.preventDefault(), c = !1;
201
  return c;
202
  }
203
  function c(b) {
204
- p && p.die();
205
- return p = m(a, e, b);
206
  }
207
- var p, v, h, l = k(a), B = l.find("button");
208
  0 === B.length && (l.addClass("is-dismissible"), B = k('<button type="button" class="notice-dismiss"> </a>').appendTo(l));
209
  B.off("click").on("click", e);
210
  k(d).triggerHandler("resize");
211
  A();
212
  v = q.length;
213
  q.push(e);
214
- b && (p = c(b));
215
  return {
216
  link: function(b, v) {
217
- var e = v || b, c = k(a).find("nav"), e = k("<nav></nav>").append(k("<a></a>").attr("href", b).text(e));
218
- h ? (h.push(e.html()), c.html(h.join("<span> | </span>"))) : (h = [ e.html() ],
219
  k(a).addClass("has-nav").append(e));
220
  return this;
221
  },
222
  stick: function() {
223
- p && p.die();
224
- p = null;
225
  q[v] = null;
226
  return this;
227
  },
@@ -232,16 +232,16 @@ return this;
232
  };
233
  }
234
  function b(a, b, e) {
235
- var c = n.require("$21", "dom.js").el;
236
  a = k('<div class="notice notice-' + a + ' loco-notice inline"></div>').prependTo(k("#loco-notices"));
237
- var p = k(c("p"));
238
- e = k(c("span")).text(e);
239
- b = k(c("strong", "has-icon")).text(b + ": ");
240
- p.append(b).append(e).appendTo(a);
241
  return a;
242
  }
243
- function a(a, e, p, h) {
244
- a = b(p, e, a).css("opacity", "0").fadeTo(500, 1);
245
  k(d).triggerHandler("resize");
246
  return c(a, h);
247
  }
@@ -260,13 +260,13 @@ var q = [], l = d.console || {
260
  log: function() {}
261
  }, A = Date.now || function() {
262
  return new Date().getTime();
263
- }, z, s, p, B;
264
  f.error = function(b) {
265
- return a(b, z, "error");
266
  };
267
  f.warn = e;
268
  f.info = function(b) {
269
- return a(b, p, "info");
270
  };
271
  f.success = function(b) {
272
  return a(b, B, "success", 5e3);
@@ -279,7 +279,7 @@ f.debug = function() {
279
  (l.debug || l.log).apply(l, arguments);
280
  };
281
  f.clear = function() {
282
- for (var a = -1, b, e = q, c = e.length; ++a < c; ) (b = e[a]) && b.call && b();
283
  q = [];
284
  return f;
285
  };
@@ -289,17 +289,17 @@ f.raise = function(a) {
289
  };
290
  f.convert = c;
291
  f.init = function(a) {
292
- z = a._("Error");
293
  s = a._("Warning");
294
- p = a._("Notice");
295
  B = a._("OK");
296
  setTimeout(h, 1e3);
297
  return f;
298
  };
299
  return f;
300
- }({}, y, w));
301
  n.register("$8", function(f, d, D) {
302
- function m(a) {
303
  var b = k("<pre>" + a + "</pre>").text();
304
  b && (b = b.replace(/[\r\n]+/g, "\n").replace(/(^|\n)\s+/g, "$1").replace(/\s+$/, ""));
305
  b || (b = a) || (b = "Blank response from server");
@@ -328,23 +328,23 @@ a.append(b, e);
328
  function h(a, b, e, c) {
329
  function h(b, c, v) {
330
  if ("abort" !== c) {
331
- var p = l || {
332
  _: function(a) {
333
  return a;
334
  }
335
- }, r = b.status || 0, d = b.responseText || "", x = m(d), z = b.getResponseHeader("Content-Type") || "Unknown type", f = b.getResponseHeader("Content-Length") || d.length;
336
- "success" === c && v ? q.error(v) : (q.error(g(x) + ".\n" + p._("Check console output for debugging information")),
337
  q.log("Ajax failure for " + a, {
338
  status: r,
339
  error: c,
340
  message: v,
341
  output: d
342
- }), "parsererror" === c && (v = "Response not JSON"), q.log([ p._("Provide the following text when reporting a problem") + ":", "----", "Status " + r + ' "' + (v || p._("Unknown error")) + '" (' + z + " " + f + " bytes)", x, "====" ].join("\n")));
343
  e && e.call && e(b, c, v);
344
  A = b;
345
  }
346
  }
347
- c.url = z;
348
  c.dataType = "json";
349
  var q = n.require("$7", "notices.js").clear();
350
  A = null;
@@ -353,7 +353,7 @@ var c = a && a.data, l = a && a.notices, g = l && l.length, A = -1;
353
  for (!c || a.error ? h(v, e, a && a.error && a.error.message) : b && b(c, e, v); ++A < g; ) q.raise(l[A]);
354
  });
355
  }
356
- var q = {}, l, A, z = d.ajaxurl || "/wp-admin/admin-ajax.php";
357
  f.init = function(a) {
358
  q = a.nonces || q;
359
  return f;
@@ -365,7 +365,7 @@ return f;
365
  f.xhr = function() {
366
  return A;
367
  };
368
- f.strip = m;
369
  f.parse = g;
370
  f.submit = function(a, b, e) {
371
  function c(a, b) {
@@ -402,12 +402,12 @@ type: a.method,
402
  data: A
403
  });
404
  };
405
- f.post = function(l, p, A, g) {
406
- var r = !0, G = p || {}, z = q[l] || c(l);
407
- d.FormData && G instanceof FormData ? (r = !1, p = e) : p = Array.isArray(G) ? a : b;
408
- p(G, "action", "loco_json");
409
- p(G, "route", l);
410
- p(G, "loco-nonce", z);
411
  return h(l, A, g, {
412
  type: "post",
413
  data: G,
@@ -431,7 +431,7 @@ q[a] = b;
431
  return f;
432
  };
433
  return f;
434
- }({}, y, w));
435
  n.register("$22", {
436
  arab: 1,
437
  aran: 1,
@@ -471,28 +471,28 @@ ur: 1,
471
  yi: 1
472
  });
473
  n.register("$9", function(f, d, k) {
474
- function m() {}
475
  var g, c = n.require("$22", "rtl.json");
476
  f.init = function() {
477
- return new m();
478
  };
479
  f.cast = function(b) {
480
- return b instanceof m ? b : "string" === typeof b ? f.parse(b) : f.clone(b);
481
  };
482
  f.clone = function(b) {
483
- var a, e = new m();
484
  for (a in b) e[a] = b[a];
485
  return e;
486
  };
487
  f.parse = function(b) {
488
  if (!(g || (g = /^([a-z]{2,3})(?:[-_]([a-z]{2}))?(?:[-_]([a-z0-9]{3,8}))?$/i)).exec(b)) return null;
489
- var a = new m();
490
  a.lang = RegExp.$1.toLowerCase();
491
  if (b = RegExp.$2) a.region = b.toUpperCase();
492
  if (b = RegExp.$3) a.variant = b.toLowerCase();
493
  return a;
494
  };
495
- d = m.prototype;
496
  d.isValid = function() {
497
  return !!this.lang;
498
  };
@@ -517,7 +517,7 @@ return !!c[String(this.lang).toLowerCase()];
517
  };
518
  d = null;
519
  return f;
520
- }({}, y, w));
521
  n.register("$23", {
522
  "á": "a",
523
  "à": "a",
@@ -944,12 +944,12 @@ function c(a) {
944
  return g(String(a || "").toLowerCase().replace(h, d), q, [], {});
945
  }
946
  function b(a, b) {
947
- for (var c = [], p = {}, l, x = b.length, r = q; 0 !== x--; ) (l = b[x]) && g(String(l || "").toLowerCase().replace(h, d), r, c, p);
948
  e[a] = c;
949
  }
950
  function a(a, b) {
951
- var c = [], h = -1, q = e, l = q.length, r, g, d, u, v, F, f = a.length, k = b ? !0 : !1;
952
- a: for (;++h < l; ) if (d = q[h], null != d && (u = d.length)) {
953
  v = 0;
954
  b: for (;v < f; v++) {
955
  F = a[v];
@@ -990,11 +990,11 @@ e[a] = null;
990
  };
991
  };
992
  return f;
993
- }({}, y, w));
994
  n.register("$11", function(f, d, n) {
995
  f.listen = function(f, g) {
996
  function c() {
997
- p[h ? "show" : "hide"]();
998
  }
999
  function b(a) {
1000
  s && A.setAttribute("size", 2 + a.length);
@@ -1008,11 +1008,11 @@ g(h);
1008
  }
1009
  function e(e) {
1010
  var c = A.value;
1011
- z && c === z && (c = "");
1012
  c !== h ? (q && clearTimeout(q), b(c), e ? q = setTimeout(a, e) : a()) : q && null == e && (clearTimeout(q),
1013
  a());
1014
  }
1015
- var h, q, l = 150, A = f instanceof jQuery ? f[0] : f, z = d.attachEvent && A.getAttribute("placeholder"), s = 1 === Number(A.size), p = k('<a href="#clear" tabindex="-1" class="icon clear"><span>clear</span></a>').on("click", function() {
1016
  A.value = "";
1017
  e();
1018
  return !1;
@@ -1024,7 +1024,7 @@ return !0;
1024
  }).on("blur focus change", function() {
1025
  e(null);
1026
  return !0;
1027
- }).after(p);
1028
  c();
1029
  return {
1030
  delay: function(a) {
@@ -1032,7 +1032,7 @@ l = a;
1032
  return this;
1033
  },
1034
  ping: function(c) {
1035
- c ? (q && clearTimeout(q), c = A.value, z && c === z && (c = ""), b(c), a(), c = void 0) : c = e();
1036
  return c;
1037
  },
1038
  val: function(a) {
@@ -1053,9 +1053,9 @@ q && clearTimeout(q);
1053
  };
1054
  };
1055
  return f;
1056
- }({}, y, w));
1057
  n.register("$12", function(f, d, n) {
1058
- function m(b, a) {
1059
  this.$element = k(b);
1060
  this.options = a;
1061
  this.enabled = !0;
@@ -1089,7 +1089,7 @@ k(n.body).on("overlayOpened overlayClosing", function(b) {
1089
  f.kill();
1090
  return !0;
1091
  });
1092
- m.prototype = {
1093
  show: function() {
1094
  var b = this.getTitle();
1095
  if (b && this.enabled) {
@@ -1181,7 +1181,7 @@ this.enabled = !this.enabled;
1181
  k.fn.tipsy = function(b) {
1182
  function a(a) {
1183
  var e = k.data(a, "tipsy");
1184
- e || (e = new m(a, k.fn.tipsy.elementOptions(a, b)), k.data(a, "tipsy", e));
1185
  return e;
1186
  }
1187
  function e() {
@@ -1243,8 +1243,8 @@ return e + (c ? c : "");
1243
  };
1244
  };
1245
  return f;
1246
- }({}, y, w));
1247
- n.register("$36", function(f, d, k) {
1248
  "".localeCompare || (String.prototype.localeCompare = function() {
1249
  return 0;
1250
  });
@@ -1274,18 +1274,18 @@ return A;
1274
  };
1275
  }();
1276
  return f;
1277
- }({}, y, w));
1278
- n.register("$37", function(f, d, k) {
1279
- function m() {}
1280
  var g, c, b = n.require("$22", "rtl.json");
1281
  f.init = function() {
1282
- return new m();
1283
  };
1284
  f.cast = function(a) {
1285
- return a instanceof m ? a : "string" === typeof a ? f.parse(a) : f.clone(a);
1286
  };
1287
  f.clone = function(a) {
1288
- var b, c = new m();
1289
  for (b in a) c[b] = a[b];
1290
  return c;
1291
  };
@@ -1293,7 +1293,7 @@ f.parse = function(a) {
1293
  g || (c = /[-_+]/, g = /^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}|[0-9]{3}))?(?:-([0-9][a-z0-9]{3,8}|[a-z0-9]{5,8}))?(?:-([a-z]-[-a-z]+))?$/i);
1294
  a = String(a).split(c).join("-");
1295
  if (!g.exec(a)) return null;
1296
- var b = new m();
1297
  b.lang = RegExp.$1.toLowerCase();
1298
  if (a = RegExp.$2) b.script = a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
1299
  if (a = RegExp.$3) b.region = a.toUpperCase();
@@ -1301,7 +1301,7 @@ if (a = RegExp.$4) b.variant = a.toLowerCase();
1301
  if (a = RegExp.$5) b.extension = a;
1302
  return b;
1303
  };
1304
- d = m.prototype;
1305
  d.isValid = function() {
1306
  return !!this.lang;
1307
  };
@@ -1328,13 +1328,13 @@ return !!b[String(this.script || this.lang).toLowerCase()];
1328
  };
1329
  d = null;
1330
  return f;
1331
- }({}, y, w));
1332
- n.register("$38", function(f, d, k) {
1333
- function m(a) {
1334
  d.console && console.error && console.error(a);
1335
  }
1336
  function g() {
1337
- m("Method not implemented");
1338
  }
1339
  function c() {}
1340
  function b(a) {}
@@ -1343,8 +1343,8 @@ return "[Undefined]";
1343
  };
1344
  b.prototype._validate = function(a) {
1345
  var b, h, q = !0;
1346
- for (b in this) h = this[b], h === g ? (m(a + "." + b + "() must be implemented"),
1347
- q = !1) : h instanceof c && (m(a + "." + b + " must be defined"), q = !1);
1348
  return q;
1349
  };
1350
  f.init = function(a, e) {
@@ -1358,16 +1358,16 @@ var b = /function (\w+)\(/.exec(a.toString()) ? RegExp.$1 : "";
1358
  a.prototype._validate(b || "Object");
1359
  };
1360
  return f;
1361
- }({}, y, w));
1362
- n.register("$50", function(f, d, k) {
1363
- var m = d.requestAnimationFrame, g = d.cancelAnimationFrame, c = 0;
1364
- if (!m || !g) for (var b in {
1365
  ms: 1,
1366
  moz: 1,
1367
  webkit: 1,
1368
  o: 1
1369
- }) if (m = d[b + "RequestAnimationFrame"]) if (g = d[b + "CancelAnimationFrame"] || d[b + "CancelRequestAnimationFrame"]) break;
1370
- m && g || (m = function(b) {
1371
  var h = a();
1372
  timeToCall = Math.max(0, 16 - (h - c));
1373
  nextTime = h + timeToCall;
@@ -1384,7 +1384,7 @@ return new Date().getTime();
1384
  };
1385
  f.loop = function(a, b) {
1386
  function c() {
1387
- d = m(c, b);
1388
  a(l++);
1389
  }
1390
  var l = 0, d;
@@ -1397,19 +1397,19 @@ d = null;
1397
  };
1398
  };
1399
  return f;
1400
- }({}, y, w));
1401
- n.register("$47", function(f, d, k) {
1402
- function m(a, c, e, p) {
1403
  if (b) {
1404
  var l = e;
1405
  e = function(a) {
1406
  if ((a.MSPOINTER_TYPE_TOUCH || "touch") === a.pointerType) return l(a);
1407
  };
1408
  }
1409
- a.addEventListener(c, e, p);
1410
  return {
1411
  unbind: function() {
1412
- a.removeEventListener(c, e, p);
1413
  }
1414
  };
1415
  }
@@ -1431,22 +1431,22 @@ f.dragger = function(b, c) {
1431
  function l(a) {
1432
  b.addEventListener(a, d[a], !1);
1433
  }
1434
- function p(a) {
1435
  b.removeEventListener(a, d[a], !1);
1436
  }
1437
  var d = {};
1438
  d[a] = function(b) {
1439
- q(b, function(e, p) {
1440
- p.type = a;
1441
- c(b, p, f);
1442
  });
1443
  l(e);
1444
  l(h);
1445
  return !0;
1446
  };
1447
  d[h] = function(a) {
1448
- p(e);
1449
- p(h);
1450
  q(a, function(b, e) {
1451
  e.type = h;
1452
  c(a, e, f);
@@ -1454,38 +1454,38 @@ c(a, e, f);
1454
  return !0;
1455
  };
1456
  d[e] = function(a) {
1457
- q(a, function(b, p) {
1458
- p.type = e;
1459
- c(a, p, f);
1460
  });
1461
  return g(a);
1462
  };
1463
  l(a);
1464
  var f = {
1465
  kill: function() {
1466
- p(a);
1467
- p(e);
1468
- p(h);
1469
  b = f = c = null;
1470
  }
1471
  };
1472
  return f;
1473
  };
1474
  f.swiper = function(c, d, f) {
1475
- function p(a) {
1476
  c.addEventListener(a, u[a], !1);
1477
  }
1478
  function B(a) {
1479
  c.removeEventListener(a, u[a], !1);
1480
  }
1481
- function x() {
1482
  r && r.stop();
1483
  r = null;
1484
  }
1485
  var r, G, E, u = {}, v = [], F = [], k = [];
1486
  u[a] = function(a) {
1487
  G = !1;
1488
- x();
1489
  var b = l();
1490
  q(a, function(a, c) {
1491
  v[a] = b;
@@ -1513,13 +1513,13 @@ if (e && Math.abs(e) > Math.abs(b)) return G = !0;
1513
  b && (G = !0, c.scrollLeft = Math.max(0, E + b));
1514
  return g(a);
1515
  };
1516
- if (!b || f) p(a), p(e), p(h), b && (c.className += " mstouch");
1517
  return {
1518
  kill: function() {
1519
  B(a);
1520
  B(e);
1521
  B(h);
1522
- x();
1523
  },
1524
  swiped: function() {
1525
  return G;
@@ -1532,31 +1532,31 @@ b && !f && (c.style["-ms-scroll-snap-points-x"] = "snapInterval(0px," + a + "px)
1532
  c.style["-ms-scroll-snap-type"] = "mandatory", c.style["-ms-scroll-chaining"] = "none");
1533
  },
1534
  scroll: function(a, b, e) {
1535
- x();
1536
- var v = c.scrollLeft, p = a > v ? 1 : -1, l = Math[1 === p ? "min" : "max"], h = Math.round(16 * b * p);
1537
- return r = n.require("$50", "fps.js").loop(function(b) {
1538
- b && (v = Math.max(0, l(a, v + h)), c.scrollLeft = v, a === v && (x(), e && e(v)));
1539
  }, c);
1540
  }
1541
  };
1542
  };
1543
  f.start = function(b, c) {
1544
- return m(b, a, c, !1);
1545
  };
1546
  f.move = function(a, b) {
1547
- return m(a, e, b, !1);
1548
  };
1549
  f.end = function(a, b) {
1550
- return m(a, h, b, !1);
1551
  };
1552
  var q = f.each = function(a, c) {
1553
- if (b) (a.MSPOINTER_TYPE_TOUCH || "touch") === a.pointerType && c(0, a); else for (var e = -1, p = (a.originalEvent || a).changedTouches || []; ++e < p.length; ) c(e, p[e]);
1554
  }, l = Date.now || function() {
1555
  return new Date().getTime();
1556
  };
1557
  return f;
1558
- }({}, y, w));
1559
- n.register("$51", function(f, d, n) {
1560
  f.init = function(d) {
1561
  function g() {
1562
  e.style.top = String(-d.scrollTop) + "px";
@@ -1589,9 +1589,9 @@ k(a).removeClass("has-mirror");
1589
  };
1590
  };
1591
  return f;
1592
- }({}, y, w));
1593
  n.register("$29", function(f, d, k) {
1594
- function m(b, a) {
1595
  for (var c = 0, h = -1, q = a && d[a], l = g[b] || [], f = l.length; ++h < f; ) callback = l[h],
1596
  "function" === typeof callback && (callback(q), c++);
1597
  return c;
@@ -1600,27 +1600,27 @@ var g = {}, c;
1600
  f.load = function(b, a, c) {
1601
  function h() {
1602
  f && (clearTimeout(f), f = null);
1603
- z && (z.onreadystatechange = null, z = z = z.onload = null);
1604
  b && (delete g[b], b = null);
1605
  }
1606
- function q(a, p) {
1607
- var l = z && z.readyState;
1608
- if (p || !l || "loaded" === l || "complete" === l) p || m(b, c), h();
1609
  }
1610
  function l() {
1611
- if (0 === m(b)) throw Error('Failed to load "' + (c || b) + '"');
1612
  h();
1613
  }
1614
  if (c && d[c]) "function" === typeof a && a(d[c]); else if (null != g[b]) g[b].push(a); else {
1615
  g[b] = [ a ];
1616
- var f = setTimeout(l, 4e3), z = k.createElement("script");
1617
- z.setAttribute("src", b);
1618
- z.setAttribute("async", "true");
1619
- z.onreadystatechange = q;
1620
- z.onload = q;
1621
- z.onerror = l;
1622
- z.onabort = h;
1623
- k.getElementsByTagName("head")[0].appendChild(z);
1624
  }
1625
  };
1626
  f.stat = function(b) {
@@ -1636,9 +1636,9 @@ a = c = h || "/static";
1636
  return a + b;
1637
  };
1638
  return f;
1639
- }({}, y, w));
1640
  n.register("$16", function(f, d, D) {
1641
- function m(a, b) {
1642
  a.setReadOnly(!1);
1643
  a.on("change", function(a, c) {
1644
  return b.val(c.getValue());
@@ -1665,9 +1665,9 @@ function b(b, c) {
1665
  function e() {
1666
  this.HighlightRules = h;
1667
  }
1668
- var h = a(c), p = b.require, d = p("ace/lib/oop");
1669
- d.inherits(h, p("ace/mode/text_highlight_rules").TextHighlightRules);
1670
- d.inherits(e, p("ace/mode/text").Mode);
1671
  return new e();
1672
  }
1673
  function a(a) {
@@ -1763,32 +1763,32 @@ return h || "%%";
1763
  }
1764
  var h, q = "auto";
1765
  f.init = function(a, e, h) {
1766
- var f, p = !1, B = h || q, x = a.parentNode, r = x.appendChild(D.createElement("div"));
1767
- k(x).addClass("has-proxy has-ace");
1768
  n.require("$29", "remote.js").load("https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js", function(h) {
1769
  if (r) {
1770
  if (!h) throw Error("Failed to load code editor");
1771
  f = h.edit(r);
1772
- var d = f.session, q = f.renderer;
1773
  f.$blockScrolling = Infinity;
1774
- f.setShowInvisibles(p);
1775
  f.setWrapBehavioursEnabled(!1);
1776
  f.setBehavioursEnabled(!1);
1777
  f.setHighlightActiveLine(!1);
1778
  d.setUseSoftTabs(!1);
1779
- q.setShowGutter(!0);
1780
- q.setPadding(10);
1781
- q.setScrollMargin(8);
1782
  d.setMode(b(h, B));
1783
  f.setValue(a.value, -1);
1784
  d.setUseWrapMode(!0);
1785
- e ? m(f, e) : c(f);
1786
  }
1787
  }, "ace");
1788
  return {
1789
  kill: function() {
1790
  f && (g(f), f.destroy(), f = null);
1791
- r && (x.removeChild(r), k(x).removeClass("has-proxy has-ace"), r = null);
1792
  return this;
1793
  },
1794
  disable: function() {
@@ -1798,7 +1798,7 @@ return this;
1798
  },
1799
  enable: function(a) {
1800
  e = a;
1801
- f && m(f, a);
1802
  return this;
1803
  },
1804
  resize: function() {
@@ -1811,7 +1811,7 @@ return this;
1811
  },
1812
  invs: function(a) {
1813
  a = a || !1;
1814
- p !== a && (p = a, f && f.setShowInvisibles(a));
1815
  return this;
1816
  },
1817
  strf: function(a) {
@@ -1830,9 +1830,9 @@ h = b;
1830
  return f;
1831
  };
1832
  return f;
1833
- }({}, y, w));
1834
- n.register("$52", function(f, d, D) {
1835
- function m(a, b) {
1836
  function c() {
1837
  return b.val(a.getContent());
1838
  }
@@ -1864,7 +1864,7 @@ return f;
1864
  };
1865
  f.init = function(a, e) {
1866
  function h(a) {
1867
- z = a;
1868
  s = "<p>" === a.substr(0, 3) && "</p>" === a.substr(-4);
1869
  return a.replace(/(<\/?)script/gi, "$1loco:script");
1870
  }
@@ -1876,7 +1876,7 @@ a = this._getContent(a);
1876
  a = a.replace(/(<\/?)loco:script/gi, "$1script");
1877
  if (!s && "<p>" === a.substr(0, 3) && "</p>" === a.substr(-4)) {
1878
  var b = a.substr(3, a.length - 7);
1879
- if (b === z || -1 === b.indexOf("</p>")) a = b;
1880
  }
1881
  return a;
1882
  };
@@ -1884,18 +1884,18 @@ a._setContent = a.setContent;
1884
  a.setContent = function(a, b) {
1885
  return this._setContent(h(a), b);
1886
  };
1887
- e ? (m(a, e), e.reset()) : c(a);
1888
- k(x).removeClass("loading");
1889
  }
1890
- var l, A = !1, z = "", s = !1, p = a.parentNode, B = p.parentNode, x = p.appendChild(D.createElement("div")), r = B.insertBefore(D.createElement("nav"), p);
1891
  r.id = "_tb" + String(++b);
1892
- k(p).addClass("has-proxy has-mce");
1893
- k(x).addClass("mce-content-body loading").html(h(a.value));
1894
  f.load(function(a) {
1895
  if (!a) throw Error("Failed to load HTML editor");
1896
- x && a.init({
1897
  inline: !0,
1898
- target: x,
1899
  hidden_input: !1,
1900
  theme: "modern",
1901
  skin: !1,
@@ -1938,19 +1938,19 @@ init_instance_callback: d
1938
  return {
1939
  val: function(b) {
1940
  b = h(b);
1941
- null == l ? (a.value = b, k(x).html(b)) : l.getContent() !== b && l.setContent(b);
1942
  e && e.val(b);
1943
  return this;
1944
  },
1945
  kill: function() {
1946
  l && (e && e.val(l.getContent()), g(l), l.destroy(), l = null);
1947
- x && (p.removeChild(x), k(p).removeClass("has-proxy has-mce"), x = null);
1948
  r && (B.removeChild(r), r = null);
1949
  return this;
1950
  },
1951
  enable: function(a) {
1952
  e = a;
1953
- l && m(l, a);
1954
  return this;
1955
  },
1956
  disable: function() {
@@ -1964,61 +1964,61 @@ return this;
1964
  },
1965
  invs: function(a) {
1966
  a = a || !1;
1967
- A !== a && (A = a, k(p)[a ? "addClass" : "removeClass"]("show-invs"));
1968
  return this;
1969
  }
1970
  };
1971
  };
1972
  return f;
1973
- }({}, y, w));
1974
- n.register("$48", function(f, d, D) {
1975
- function m(b) {
1976
  function a() {
1977
- g && (f.off("input", e), g = !1);
1978
  }
1979
  function e() {
1980
  var a = b.value;
1981
- a !== p && (f.trigger("changing", [ a, p ]), p = a);
1982
  }
1983
- function h() {
1984
  e();
1985
- g && B !== p && f.trigger("changed", [ p ]);
1986
  }
1987
- function d() {
1988
  c = b;
1989
- B = p;
1990
- g || (f.on("input", e), g = !0);
1991
- f.trigger("editFocus");
1992
  s.addClass("has-focus");
1993
  return !0;
1994
  }
1995
  function l() {
1996
  c === b && (c = null);
1997
- f.trigger("editBlur");
1998
  s.removeClass("has-focus");
1999
- g && (h(), a());
2000
  return !0;
2001
  }
2002
- var g = !1, f = k(b), s = k(b.parentNode), p = b.value, B;
2003
- f.on("blur", l).on("focus", d);
2004
  return {
2005
  val: function(a) {
2006
- p !== a && (b.value = a, f.triggerHandler("input"), p = a);
2007
  return !0;
2008
  },
2009
  kill: function() {
2010
  a();
2011
- f.off("blur", l).off("focus", d);
2012
  },
2013
  fire: function() {
2014
- p = null;
2015
  e();
2016
  },
2017
- ping: h,
2018
  blur: l,
2019
- focus: d,
2020
  reset: function() {
2021
- B = p = b.value;
2022
  }
2023
  };
2024
  }
@@ -2101,7 +2101,7 @@ return this;
2101
  TextAreaPrototype.listen = function() {
2102
  var b = this.l;
2103
  b && b.kill();
2104
- this.l = m(this.e);
2105
  return this;
2106
  };
2107
  TextAreaPrototype.unlisten = function() {
@@ -2111,7 +2111,7 @@ return this;
2111
  };
2112
  TextAreaPrototype.setInvs = function(b, a) {
2113
  var c = this.i || !1;
2114
- if (a || c !== b) this._i && (this._i.kill(), delete this._i), (c = this.p) ? c.invs && c.invs(b) : b && (this._i = n.require("$51", "mirror.js").init(this.e)),
2115
  this.i = b;
2116
  return this;
2117
  };
@@ -2120,7 +2120,7 @@ return this.i || !1;
2120
  };
2121
  TextAreaPrototype.setMode = function(b) {
2122
  var a = this.p, e = this.i || !1;
2123
- b !== (this.m || "") && (this.m = b, a && a.kill(), this.p = a = "code" === b ? n.require("$16", "ace.js").init(this.e, this.l, this["%"]) : "html" === b ? n.require("$52", "mce.js").init(this.e, this.l) : null,
2124
  this.setInvs(e, !0), c && this.focus());
2125
  return this;
2126
  };
@@ -2143,9 +2143,9 @@ b && b.resize && b.resize();
2143
  };
2144
  TextAreaPrototype = null;
2145
  return f;
2146
- }({}, y, w));
2147
- n.register("$49", function(f, d, n) {
2148
- function m(a) {
2149
  var b = d.console;
2150
  b && b.error && b.error(a);
2151
  }
@@ -2187,7 +2187,7 @@ return !1;
2187
  }
2188
  function h(a, b, c) {
2189
  function e(a) {
2190
- m("row[" + a + "] disappeared");
2191
  return {
2192
  cellVal: function() {
2193
  return "";
@@ -2216,7 +2216,7 @@ this.d = b || [];
2216
  this.i = a || 0;
2217
  this.length = b.length;
2218
  }
2219
- function z(a) {
2220
  this.live = a;
2221
  this.rows = [];
2222
  }
@@ -2233,14 +2233,14 @@ d.eachCol(function(a, b, c) {
2233
  v[a] = l + "-col-" + b;
2234
  F[a] = c || b;
2235
  });
2236
- for (var N = g(), s = -1, z = v.length, m = g("wg-cols"), n = f.splitx.apply(f, v); ++s < z; ) n[s].header(F[s]),
2237
- m.appendChild(N.cloneNode(!1)).setAttribute("for", v[s]);
2238
  d.eachRow(function(a, b, c) {
2239
  E[a] = new A(a, b, c);
2240
  u[a] = a;
2241
  });
2242
  this.rows = E;
2243
- this.cols = m;
2244
  this.ww = null;
2245
  this.root = N = q.body;
2246
  this.head = f;
@@ -2249,7 +2249,7 @@ f = q.fixed = n[0].bodyY() || 20;
2249
  h.lock().resize(f, q);
2250
  h.css.push("is-table");
2251
  h.restyle();
2252
- this.sc ? this._re_sort(z) : d.sort && d.sort(u);
2253
  this.redrawDirty();
2254
  this.render();
2255
  k(N).attr("tabindex", "-1").on("keydown", e(this)).on("mousedown", b(this)).on("scroll", a(this));
@@ -2263,10 +2263,10 @@ void 0;
2263
  return this;
2264
  };
2265
  s.render = function() {
2266
- for (var a, b, c = [], e = this.rows || [], d = -1, h, g = this.idxs, v = g.length, q = this.idxr = {}, l = this.r, f = this._r, k = this.root, A = this.cols; ++d < v; ) {
2267
- 0 === d % 100 && (a = A.cloneNode(!0), b = new z(a), b.h = 2200, b.insert(k), c.push(b));
2268
  h = g[d];
2269
- q[h] = d;
2270
  a = e[h];
2271
  if (null == a) throw Error("Render error, no data at [" + h + "]");
2272
  a.page = b;
@@ -2277,8 +2277,8 @@ this.pages = c;
2277
  this.mx = this.mn = null;
2278
  this.redrawDirty();
2279
  this.redraw();
2280
- null == l ? null != f && (a = e[f]) && a.page && (delete this._r, this.select(f, !0)) : (a = e[l]) && a.page ? this.select(l, !0) : (this.deselect(),
2281
- this._r = l);
2282
  return this;
2283
  };
2284
  s.resize = function() {
@@ -2336,7 +2336,7 @@ var e = this.idxs, d = e.length, h = (this.idxr || {})[c];
2336
  for (c = h; c !== (h += a) && !(0 <= h && d > h); ) if (b && d) h = 1 === a ? -1 : d,
2337
  b = !1; else return null;
2338
  c = e[h];
2339
- return null == c || null == this.rows[c] ? (m("Bad next: [" + h + "] does not map to data row"),
2340
  null) : c;
2341
  };
2342
  s.selectNext = function(a, b, c) {
@@ -2354,11 +2354,11 @@ return this.select(this.idxs[a]);
2354
  };
2355
  s.select = function(a, b) {
2356
  var c = this.rows[a], e = c && c.page;
2357
- if (!e) return this.deselect(!1), m("Row is filtered out"), this;
2358
  this.deselect(!0);
2359
  var d, h = this.w.cells[1];
2360
  e.rendered || (d = e.top(), h.scrollY(d), this.redrawDirty() && this.redraw());
2361
- if (!c.rendered) return e.rendered || m("Failed to render page"), m("Row [" + c.i + "] not rendered"),
2362
  this;
2363
  e = c.cells();
2364
  k(e).addClass("selected");
@@ -2467,7 +2467,7 @@ a = this.d[a]() || "";
2467
  return String(a.textContent || a);
2468
  };
2469
  s = null;
2470
- s = z.prototype;
2471
  s.size = function() {
2472
  return this.rows.length;
2473
  };
@@ -2483,7 +2483,7 @@ return (this.rendered ? this.live : this.dead).offsetTop;
2483
  s.height = function() {
2484
  var a = this.h;
2485
  null == a && (this.h = a = this.rendered ? this.live.firstChild.offsetHeight : this.dead.offsetHight);
2486
- a || m("row has zero height");
2487
  return a;
2488
  };
2489
  s.render = function(a) {
@@ -2521,12 +2521,12 @@ for (a.parentNode.removeChild(a); 0 !== c--; ) b[c].destroy();
2521
  };
2522
  s = null;
2523
  return f;
2524
- }({}, y, w));
2525
- n.register("$39", function(f, d, D) {
2526
- function m(a, b) {
2527
- var c = a.id, e = c && p[c], d = e && e.parent();
2528
  if (!e || !d) return null;
2529
- var h = d.dir === s, c = h ? "X" : "Y", g = "page" + c, h = h ? z : A, l = h(d.el), c = b["offset" + c], q = d.el, f = q.className;
2530
  null == c && (c = b[g] - h(a));
2531
  c && (l += c);
2532
  q.className = f + " is-resizing";
@@ -2543,23 +2543,23 @@ return !0;
2543
  function g(a, c) {
2544
  function e() {
2545
  k(D).off("mousemove", d);
2546
- x && (x.done(), x = null);
2547
  return !0;
2548
  }
2549
  function d(a) {
2550
- x ? x.move(a) : e();
2551
  return !0;
2552
  }
2553
- if (x) return !0;
2554
- x = m(a.target, a);
2555
- if (!x) return !0;
2556
  k(D).one("mouseup", e).on("mousemove", d);
2557
  return b(a);
2558
  }
2559
  function c(a, b) {
2560
  var c = b.type;
2561
- "touchmove" === c ? x && x.move(b) : "touchstart" === c ? x = m(a.target, b) : "touchend" === c && x && (x.done(),
2562
- x = null);
2563
  }
2564
  function b(a) {
2565
  a.stopPropagation();
@@ -2586,14 +2586,14 @@ this.el = a;
2586
  this.pos = this.index = 0;
2587
  this.css = [ c || "wg-root", "wg-cell" ];
2588
  this._cn = c;
2589
- p[b] = this;
2590
  this.clear();
2591
  }
2592
- var q = n.include("$46", "html.js") || n.include("$2", "html.js", !0), l = n.require("$21", "dom.js"), A = l.top, z = l.left, s = 1, p = {}, B, x = !1;
2593
  f.init = function(a) {
2594
  var b = new h(a);
2595
  b.redraw();
2596
- n.require("$47", "touch.js").ok(function(b) {
2597
  b.dragger(a, c);
2598
  });
2599
  k(a).on("mousedown", g);
@@ -2611,7 +2611,7 @@ for (var b = -1, c = this.cells, e = c.length; ++b < e; ) a(c[b], b);
2611
  return this;
2612
  };
2613
  d.indexOf = function(a) {
2614
- return (a = p[a.id || String(a)]) && a.pid === this.id ? a.index : -1;
2615
  };
2616
  d.on = function() {
2617
  return this.$("on", arguments);
@@ -2636,7 +2636,7 @@ a = this.css.indexOf(a);
2636
  return this;
2637
  };
2638
  d.parent = function() {
2639
- return this.pid && p[this.pid];
2640
  };
2641
  d.splitx = function() {
2642
  return this._split(s, arguments);
@@ -2649,7 +2649,7 @@ d._split = function(a, b) {
2649
  for (var c = -1, e, d = b.length, g = 1 / d, q = 0; ++c < d; ) {
2650
  e = l.el();
2651
  this.body.appendChild(e);
2652
- for (var f = e, k = b[c], A = k, s = 1; p[k]; ) k = A + "-" + ++s;
2653
  f.id = k;
2654
  e = new h(e);
2655
  e.index = c;
@@ -2666,7 +2666,7 @@ return this.cells;
2666
  };
2667
  d.destroy = function() {
2668
  this.clear();
2669
- delete p[this.id];
2670
  var a = this.el;
2671
  a.innerHTML = "";
2672
  this.body = null;
@@ -2675,10 +2675,10 @@ k(a).off();
2675
  return this;
2676
  };
2677
  d.exists = function() {
2678
- return this === p[this.id];
2679
  };
2680
  d.clear = function() {
2681
- for (var a = this.el, b = this.cells, c = this.field, e = this.body, d = this.nav, h = this.length || 0; 0 !== h--; ) delete p[b[h].destroy().id];
2682
  this.cells = [];
2683
  this.length = 0;
2684
  d && (a.removeChild(d), this.nav = null);
@@ -2722,7 +2722,7 @@ d.redraw = function(a) {
2722
  this.restyle();
2723
  var b = this.el, c = this.body, e = this.field;
2724
  if (c) {
2725
- var d, h = b.clientWidth || 0, g = b.clientHeight || 0, q = c.offsetTop || 0, g = q > g ? 0 : g - q;
2726
  this._h !== g && (this._h = g, c.style.height = String(g) + "px", d = e);
2727
  this._w !== h && (this._w = h, d = e);
2728
  d && d.redraw();
@@ -2730,8 +2730,8 @@ d && d.redraw();
2730
  c = this.length;
2731
  h = 1;
2732
  g = this.nav;
2733
- for (q = 2 === this.dir ? "height" : "width"; 0 !== c--; ) e = this.cells[c], g ? d = 1 : (e.fixed && (e.pos = e.fixed / k(b)[q]()),
2734
- d = h - e.pos, h = e.pos), e.el.style[q] = String(100 * d) + "%", e.redraw(a);
2735
  return this;
2736
  };
2737
  d.contents = function(a, b) {
@@ -2751,13 +2751,13 @@ var d = c.editable();
2751
  c.reload(a, b);
2752
  d !== b && this.restyle();
2753
  } else this.length && this.clear(), d = l.el("textarea"), d.setAttribute("wrap", "virtual"),
2754
- d.value = a, this.contents(d), c = n.require("$48", "field.js")._new(d)[b ? "enable" : "disable"](),
2755
  e(this, d), this.field = c, this.restyle();
2756
  this.lang || this.locale("en");
2757
  return c;
2758
  };
2759
  d.locale = function(a) {
2760
- a = n.require("$37", "locale.js").cast(a);
2761
  return this._locale(String(a), a.isRTL());
2762
  };
2763
  d._locale = function(a, b, c) {
@@ -2826,7 +2826,7 @@ this.body.scrollTop = a;
2826
  };
2827
  d.tabulate = function(a) {
2828
  var b = this.table;
2829
- b ? b.clear() : b = n.require("$49", "wgtable.js").create(this);
2830
  b.init(a);
2831
  return this.table = b;
2832
  };
@@ -2851,13 +2851,13 @@ function e(a) {
2851
  var b = h[a], c = f[a], d = k(b.el).show();
2852
  c.addClass("active");
2853
  q = a;
2854
- p.data("idx", a);
2855
  b.fire("wgTabSelect", [ a ]);
2856
  return d;
2857
  }
2858
  var d = this, h = d.cells, g = d.nav, q, f = [];
2859
  g && d.el.removeChild(g);
2860
- var g = d.nav = d.el.insertBefore(l.el("nav", "wg-tabs"), d.body), p = k(g).on("click", function(a) {
2861
  var c = k(a.target).data("idx");
2862
  if (null == c) return !0;
2863
  if (null != q) {
@@ -2869,9 +2869,9 @@ e(c);
2869
  d.redraw();
2870
  return b(a);
2871
  });
2872
- null == c && (c = p.data("idx") || 0);
2873
  d.each(function(b, c) {
2874
- f[c] = k('<a href="#' + b.id + '"></a>').data("idx", c).text(a[c]).appendTo(p);
2875
  b.pos = 0;
2876
  k(b.el).hide();
2877
  });
@@ -2886,9 +2886,9 @@ if (a) return k(a).data("idx");
2886
  };
2887
  d = null;
2888
  return f;
2889
- }({}, y, w));
2890
  n.register("$24", function(f, d, D) {
2891
- function m(a) {
2892
  var b = [];
2893
  a && (a.saved() || b.push("po-unsaved"), a.fuzzy() ? b.push("po-fuzzy") : a.flagged() && b.push("po-flagged"),
2894
  a.translation() || b.push("po-empty"), a.comment() && b.push("po-comment"));
@@ -2897,7 +2897,7 @@ return b.join(" ");
2897
  function g(a, b, c) {
2898
  b = k(a.title(b).parentNode);
2899
  var e = b.find("span.lang");
2900
- c ? (c = n.require("$37", "locale.js").cast(c), e.length || (e = k("<span></span>").prependTo(b)),
2901
  e.attr("lang", c.lang).attr("class", c.getIcon() || "lang region region-" + (c.region || "zz").toLowerCase())) : (e.remove(),
2902
  c = "en");
2903
  a.locale(c);
@@ -2914,21 +2914,21 @@ function b() {
2914
  this.dirty = 0;
2915
  }
2916
  n.require("$3", "number.js");
2917
- var a = "poUpdate", e = "changing", h = "changed", q = 0, l = 1, A = 2, z = 3, s = 4, p = 5, B, x, r = n.require("$36", "string.js").html, y = n.require("$6", "string.js").sprintf;
2918
  f.extend = function(a) {
2919
  return a.prototype = new b();
2920
  };
2921
  f.localise = function(a) {
2922
- x = a;
2923
  return f;
2924
  };
2925
- var w = function() {
2926
  var a = D.createElement("p");
2927
  return function(b) {
2928
  a.innerHTML = b.replace("src=", "x=");
2929
  return a.textContent.trim() || b.trim();
2930
  };
2931
- }(), u = b.prototype = n.require("$38", "abstract.js").init([ "getListColumns", "getListHeadings", "getListEntry" ], [ "editable", "t" ]);
2932
  u.init = function() {
2933
  this.localise();
2934
  this.editable = {
@@ -2940,12 +2940,12 @@ this.html = !1;
2940
  return this;
2941
  };
2942
  u.localise = function(a) {
2943
- a || (a = x || n.require("$1", "t.js").init());
2944
  var b = [];
2945
  b[q] = a._x("Source text", "Editor") + ":";
2946
- b[z] = a._x("%s translation", "Editor") + ":";
2947
  b[s] = a._x("Context", "Editor") + ":";
2948
- b[p] = a._x("Comments", "Editor") + ":";
2949
  b[l] = a._x("Single", "Editor") + ":";
2950
  b[A] = a._x("Plural", "Editor") + ":";
2951
  b[6] = a._x("Untranslated", "Editor");
@@ -2961,7 +2961,7 @@ function b(a) {
2961
  c.redraw(!0, a);
2962
  return !0;
2963
  }
2964
- var c = n.require("$39", "wingrid.js").init(a);
2965
  k(d).on("resize", b);
2966
  this.redraw = b;
2967
  k(a).on("wgFocus wgBlur", function(a, b) {
@@ -2996,12 +2996,12 @@ u.setTargetCell = function(a) {
2996
  this.targetCell = a;
2997
  };
2998
  u.next = function(a, b, c) {
2999
- for (var e = this.listTable, d = e.selected(), h = d, g, q = this.po; null != (d = e.next(a, c, d)); ) {
3000
  if (h === d) {
3001
  d = null;
3002
  break;
3003
  }
3004
- if (b && (g = q.row(d), g.translated(0))) continue;
3005
  break;
3006
  }
3007
  null != d && e.select(d, !0);
@@ -3067,7 +3067,7 @@ u.markUnsaved = function(a) {
3067
  var b = this.po.indexOf(a);
3068
  if ((b = this.listTable.tr(b)) && b.length) {
3069
  var c = b[0].className;
3070
- a = c.replace(/(?:^| +)po-[a-z]+/g, "") + " " + m(a);
3071
  a !== c && k(b).attr("class", a);
3072
  }
3073
  };
@@ -3094,11 +3094,11 @@ u.getSorter = function() {
3094
  return null;
3095
  };
3096
  u.reload = function() {
3097
- var a = this, b, c = a.listCell, e = a.listTable, d = a.po, h = d && d.locale(), g = h && h.isRTL(), q = d && d.length || 0;
3098
  if (!d || !d.row) return c && c.clear().header("Error").contents("Invalid messages list"),
3099
  !1;
3100
  a.targetLocale = h;
3101
- a.lastSearch && (a.lastSearch = "", a.lastFound = q, a.fire("poFilter", [ "", q ]));
3102
  e && (b = e.thead().distribution());
3103
  a.listTable = e = c.tabulate({
3104
  eachCol: function(b) {
@@ -3107,17 +3107,17 @@ for (e in d) c = d[e], b(c, e, h[c]);
3107
  },
3108
  eachRow: function(b) {
3109
  d.each(function(c, e) {
3110
- b(e.idx, a.getListEntry(e), m(e));
3111
  });
3112
  },
3113
  sort: a.getSorter()
3114
  });
3115
- var l, c = a.getListColumns();
3116
- for (l in c) e.sortable(c[l]);
3117
  b && e.thead().distribute(b);
3118
  e.tbody().$(g ? "addClass" : "removeClass", [ "is-rtl" ]);
3119
  a.fire("poLoad");
3120
- return !!q;
3121
  };
3122
  u.load = function(a, b) {
3123
  this.po = a;
@@ -3149,13 +3149,13 @@ u.setStatus = function() {
3149
  return null;
3150
  };
3151
  u.setSrcMeta = function(a, b) {
3152
- var e = [], d, h = !1, g = this.$smeta, q = this.labels, l = [], f = a.tags(), p = f && f.length;
3153
- if (d = a.context()) l.push("<span>" + r(q[s]) + "</span>"), l.push("<mark>" + r(d) + "</mark>");
3154
- if (p && this.getTag) for (l.push("<span>Tagged:</span>"); 0 <= --p; ) (d = this.getTag(f[p])) && l.push('<mark class="tag">' + r(d.mod_name) + "</mark>");
3155
- l.length && e.push(l.join(" "));
3156
- if (this.getMono() && (d = a.refs()) && (f = d.split(/\s/), p = f.length)) {
3157
- for (l = []; 0 <= --p; ) d = f[p], l.push("<code>" + r(d) + "</code>");
3158
- e.push('<p class="has-icon icon-file">' + l.join(" ") + "</p>");
3159
  }
3160
  (d = a.notes()) && e.push('<p class="has-icon icon-info">' + r(d, !0) + "</p>");
3161
  e.length ? (g || (g = b.find("div.meta"), g.length || (g = k('<div class="meta"></div>').insertAfter(b.header())),
@@ -3188,18 +3188,18 @@ a.titled() !== k && g(a, k, e || "en");
3188
  k = !1;
3189
  r.setSrcMeta(b, a) && (k = !0);
3190
  if (b.plural()) {
3191
- var k = -1, p = [], s = [], z = a.id + "-", m = b.sourceForms() || e && e.plurals || [ "One", "Other" ], n = m.length;
3192
- if (2 !== n || "=" === m[0].charAt(0) && "=1" !== m[0]) for (;++k < n; ) p[k] = z + String(k),
3193
- s[k] = c(m[k]) + ":"; else p = [ z + "-0", z + "-1" ], s = [ L[l], L[A] ];
3194
- a.splity.apply(a, p);
3195
  a.each(function(a, c) {
3196
- a.header(s[c]).textarea(b.source(null, c), h).setStrf(C).setMode(x).setInvs(w);
3197
  });
3198
  a.lock();
3199
  h && a.each(function(a, b) {
3200
  f(a, b);
3201
  });
3202
- } else k && a.redraw(), a.textarea(b.source(), h).setStrf(C).setMode(x).setInvs(w),
3203
  h && f(a, 0);
3204
  }
3205
  function f(c, d) {
@@ -3218,15 +3218,15 @@ M && a.eachTextarea(function(a) {
3218
  a.ping();
3219
  });
3220
  a.off();
3221
- var h = e.isKnown() && e.label || "Target", h = y(L[z], h);
3222
  a.titled() !== h && g(a, h, e);
3223
  h = !1;
3224
  !this.sourceCell && r.setSrcMeta(b, a) && (h = !0);
3225
  r.setTrgMeta(b, d, a) && (h = !0);
3226
  r.setStatus(b, d);
3227
  if (1 !== e.nplurals && b.pluralized()) {
3228
- var q = [], l = [], f = a.id + "-", p = b.targetForms() || e.plurals || [ "One", "Other" ], h = p.length, A = function(a) {
3229
- var b = p[a];
3230
  l.push(b ? c(b, !0) : "Form " + a);
3231
  q.push(f + String(a));
3232
  };
@@ -3234,8 +3234,8 @@ for (b.each(A); (e = q.length) < h; ) A(e);
3234
  a.splitx.apply(a, q);
3235
  a.each(function(a, c) {
3236
  var e = M && !b.disabled(c);
3237
- a.textarea(b.translation(c), e).setStrf(C).setMode(x).setInvs(w);
3238
- M && m(a, c);
3239
  });
3240
  a.navigize(l, d || null).on("wgTabSelect", function(c, e) {
3241
  var d = M && c.cell.editable();
@@ -3244,10 +3244,10 @@ r.setTrgMeta(b, e, a);
3244
  r.setStatus(b, e);
3245
  r.fire("poTab", [ e ]);
3246
  });
3247
- } else h && a.redraw(), a.textarea(b.translation(), M && !b.disabled(0)).setStrf(C).setMode(x).setInvs(w),
3248
- M && m(a, 0);
3249
  }
3250
- function m(c, d) {
3251
  c.on(e, function(a, c, e) {
3252
  b.translate(c, d);
3253
  0 === d && r.updateListCell(b, "target");
@@ -3263,7 +3263,7 @@ function n(c) {
3263
  c.off();
3264
  var d = L[s];
3265
  c.titled() !== d && (g(c, d), r.setStatus(null));
3266
- c.textarea(b.context(), !0).setMode(x).setInvs(w);
3267
  X && c.on(e, function(a, c) {
3268
  b.context(c);
3269
  r.updateListCell(b, "source");
@@ -3275,7 +3275,7 @@ r.fire(a, [ b ]);
3275
  });
3276
  }
3277
  function u(a) {
3278
- var c = L[p];
3279
  a.titled() !== c && g(a, c);
3280
  a.off().on(e, function(a, c) {
3281
  b.comment(c);
@@ -3283,8 +3283,8 @@ r.fire("poComment", [ b, c ]);
3283
  r.unsave(b, O);
3284
  }).textarea(b.comment(), !0);
3285
  }
3286
- var r = this, x = r.mode, D = b.isHTML(), w = r.inv || !1, E = this.fmt || null, C = b.format() || null, I = b.is(r.active), O = 0, T = r.sourceCell, S = r.targetCell, U = r.contextCell, V = r.commentCell, M = r.editable.target, J = r.editable.source, X = r.editable.context, P = B, Y = r.sourceLocale, W = r.targetLocale, L = r.labels;
3287
- r.html !== D && (r.html = D, "code" !== r.mode && (x = D ? "html" : "", r.setMode(x)));
3288
  r.active = b;
3289
  T && d(T, Y);
3290
  U && n(U);
@@ -3325,7 +3325,7 @@ var c = this.getListColumns()[b], e = this.po.indexOf(a);
3325
  (e = this.listTable.row(e)) && e.rendered && e.update(c);
3326
  };
3327
  u.cellText = function(a) {
3328
- return (a = -1 !== a.indexOf("<") || -1 !== a.indexOf("&") ? w(a) : a.trim()) || " ";
3329
  };
3330
  u.fuzzy = function(a, b, c) {
3331
  b = b || this.active;
@@ -3405,9 +3405,9 @@ return this;
3405
  };
3406
  u = null;
3407
  return f;
3408
- }({}, y, w));
3409
  n.register("$13", function(f, d, D) {
3410
- function m() {
3411
  this.init()._validate();
3412
  this.sourceLocale = {
3413
  lang: "en",
@@ -3434,7 +3434,7 @@ a.fire("poHint");
3434
  }
3435
  d = n.require("$24", "base.js");
3436
  f.init = function(a) {
3437
- var b = new m();
3438
  a = b.setRootCell(a);
3439
  var c = a.splity("po-list", "po-edit"), d = c[0], g = c[1], c = g.splitx("po-trans", "po-comment"), f = c[0], k = c[1].header("Loading.."), c = f.splity("po-source", "po-target"), f = c[0].header("Loading.."), c = c[1].header("Loading..");
3440
  a.distribute([ .34 ]);
@@ -3446,7 +3446,7 @@ b.commentCell = k;
3446
  b.editable.source = !1;
3447
  return b;
3448
  };
3449
- d = m.prototype = d.extend(m);
3450
  d.getListHeadings = function() {
3451
  var a = this.t || {
3452
  _x: function(a) {
@@ -3535,9 +3535,9 @@ return f(g.row(a), g.row(b));
3535
  };
3536
  };
3537
  return f;
3538
- }({}, y, w));
3539
  n.register("$14", function(f, d, n) {
3540
- var m = {
3541
  copy: 66,
3542
  clear: 75,
3543
  save: 83,
@@ -3595,12 +3595,12 @@ var h = {};
3595
  k(a || d).on("keydown", e);
3596
  return {
3597
  add: function(a, b) {
3598
- c[m[a]] = b;
3599
  return this;
3600
  },
3601
  enable: function() {
3602
  var a, b;
3603
- for (b in arguments) a = m[arguments[b]], h[a] = !0;
3604
  return this;
3605
  },
3606
  disable: function() {
@@ -3610,15 +3610,15 @@ b = a = h = null;
3610
  };
3611
  };
3612
  return f;
3613
- }({}, y, w));
3614
  n.register("$25", function(f, d, k) {
3615
- function m() {
3616
  this.reIndex([]);
3617
  }
3618
  f.init = function() {
3619
- return new m();
3620
  };
3621
- d = m.prototype;
3622
  d.reIndex = function(d) {
3623
  for (var c = {}, b = -1, a = d.length; ++b < a; ) c[d[b]] = b;
3624
  this.keys = d;
@@ -3679,9 +3679,9 @@ return [].join.call(this, d);
3679
  };
3680
  d = null;
3681
  return f;
3682
- }({}, y, w));
3683
  n.register("$26", function(f, d, k) {
3684
- function m(d, c) {
3685
  var b = RegExp("^.{0," + (d - 1) + "}[" + c + "]"), a = RegExp("^[^" + c + "]+");
3686
  return function(c, h) {
3687
  for (var f = c.length, l; f > d; ) {
@@ -3709,7 +3709,7 @@ var b, a, e = /(?:\r\n|[\r\n\v\f\u2028\u2029])/g, h = /[ \r\n]+/g, f = /[\t\v\f\
3709
  "\b": "\\b"
3710
  };
3711
  if (null == d || isNaN(d = Number(d))) d = 79;
3712
- 0 < d && (b = m(d - 3, " "), a = m(d - 2, "-– \\.,:;\\?!\\)\\]\\}\\>"));
3713
  return {
3714
  pair: function(b, h) {
3715
  if (!h) return b + ' ""';
@@ -3720,8 +3720,8 @@ l++;
3720
  return "\\n\n";
3721
  });
3722
  if (!(l || d && d < h.length + b.length + 3)) return b + ' "' + h + '"';
3723
- var k = [ b + ' "' ], m = h.split("\n");
3724
- if (a) for (var n = -1, r = m.length; ++n < r; ) a(m[n], k); else k = k.concat(m);
3725
  return k.join('"\n"') + '"';
3726
  },
3727
  prefix: function(a, b) {
@@ -3736,15 +3736,15 @@ return "#: " + a;
3736
  };
3737
  };
3738
  return f;
3739
- }({}, y, w));
3740
- n.register("$40", function(f, d, k) {
3741
- function m() {
3742
  this.length = 0;
3743
  }
3744
  f.init = function() {
3745
- return new m();
3746
  };
3747
- d = m.prototype;
3748
  d.push = function(d) {
3749
  this[this.length++] = d;
3750
  return this;
@@ -3758,13 +3758,13 @@ for (var c = -1, b = this.length; ++c < b; ) d(c, this[c]);
3758
  return this;
3759
  };
3760
  return f;
3761
- }({}, y, w));
3762
  n.register("$27", function(f, d, k) {
3763
- function m() {}
3764
  f.extend = function(d) {
3765
- return d.prototype = new m();
3766
  };
3767
- d = m.prototype = n.require("$38", "abstract.js").init([ "add", "load" ]);
3768
  d.row = function(d) {
3769
  return this.rows[d];
3770
  };
@@ -3782,7 +3782,7 @@ this.loc = null;
3782
  return d;
3783
  };
3784
  d.locale = function(d) {
3785
- null == d ? d = this.loc : this.loc = d = n.require("$37", "locale.js").cast(d);
3786
  return d;
3787
  };
3788
  d.each = function(d) {
@@ -3820,14 +3820,14 @@ this.rows.sort(d);
3820
  return this;
3821
  };
3822
  d["export"] = function() {
3823
- for (var d = -1, c = this.rows, b = c.length, a = n.require("$40", "list.js").init(); ++d < b; ) a.push(c[d]);
3824
  return a;
3825
  };
3826
  d = null;
3827
  return f;
3828
- }({}, y, w));
3829
  n.register("$28", function(f, d, k) {
3830
- function m(c, b, a) {
3831
  if (null == a) return c[b] || "";
3832
  c[b] = a || "";
3833
  return c;
@@ -3922,19 +3922,19 @@ for (c = 0; c < a; c++) if (b[c]) return !1;
3922
  return !0;
3923
  };
3924
  d.comment = function(c) {
3925
- return m(this, "cmt", c);
3926
  };
3927
  d.notes = function(c) {
3928
- return m(this, "xcmt", c);
3929
  };
3930
  d.refs = function(c) {
3931
- return m(this, "rf", c);
3932
  };
3933
  d.format = function(c) {
3934
- return m(this, "fmt", c);
3935
  };
3936
  d.context = function(c) {
3937
- return m(this, "ctx", c);
3938
  };
3939
  d.tags = function() {
3940
  return this.tg;
@@ -3988,9 +3988,9 @@ this.htm = c;
3988
  };
3989
  d = null;
3990
  return f;
3991
- }({}, y, w));
3992
  n.register("$15", function(f, d, k) {
3993
- function m(a) {
3994
  return {
3995
  "Project-Id-Version": "PACKAGE VERSION",
3996
  "Report-Msgid-Bugs-To": "",
@@ -4020,7 +4020,7 @@ return n.require("$26", "format.js").create(a);
4020
  function a(a) {
4021
  this.locale(a);
4022
  this.clear();
4023
- this.head = m(this.now());
4024
  }
4025
  function e(a, b) {
4026
  this.src = [ a || "" ];
@@ -4050,7 +4050,7 @@ c[a] = b || "";
4050
  return this;
4051
  };
4052
  k.headers = function(a) {
4053
- var b, c = this.now(), d = this.head || (this.head = m(c));
4054
  if (null != a) {
4055
  for (b in a) d[b] = a[b];
4056
  return this;
@@ -4079,23 +4079,23 @@ this.length = this.rows.length);
4079
  return a;
4080
  };
4081
  k.load = function(a) {
4082
- for (var b = -1, d, f, g, k, p, m, n = (g = this.locale()) && g.nplurals || 2, r = []; ++b < a.length; ) d = a[b],
4083
- null == d.parent ? (f = d.source || d.id, g = d.target || "", k = d.context, f || k ? (p = new e(f, g),
4084
- p._id = d._id, k && p.context(k), d.flag && p.flag(d.flag, 0), d.comment && p.comment(d.comment),
4085
- d.notes && p.notes(d.notes), d.refs && p.refs(d.refs), p.format(d.format), d.message = p,
4086
- this.add(p), d.prev && d.prev[0] && (p.prev(d.prev[0].source, d.prev[0].context),
4087
- d.prev[1] && p._src.push(d.prev[1].source || ""))) : 0 === b && "object" === typeof g && (this.head = g,
4088
  this.headcmt = d.comment)) : r.push(d);
4089
  for (b = -1; ++b < r.length; ) try {
4090
  d = r[b];
4091
  f = d.source || d.id;
4092
- p = a[d.parent] && a[d.parent].message;
4093
- if (!p) throw Error("parent missing for plural " + f);
4094
- m = d.plural;
4095
- 1 === m && p.plural(f);
4096
- m >= n || (d.flag && p.flag(d.flag, m), p.translate(d.target || "", m), d.format && !p.format() && p.format(d.format));
4097
- } catch (w) {
4098
- c(w);
4099
  }
4100
  return this;
4101
  };
@@ -4104,7 +4104,7 @@ this.fmtr = b(a);
4104
  return this;
4105
  };
4106
  k.toString = function() {
4107
- var a, c = this.locale(), d = [], f = [], g = this.headers(), k = !c, p = c && c.nplurals || 2, m = this.fmtr || b();
4108
  g[c ? "PO-Revision-Date" : "POT-Creation-Date"] = this.now();
4109
  for (a in g) f.push(a + ": " + g[a]);
4110
  f = new e("", f.join("\n"));
@@ -4113,7 +4113,7 @@ k && f.fuzzy(0, !0);
4113
  d.push(f.toString());
4114
  d.push("");
4115
  this.rows.each(function(a, b) {
4116
- a && (d.push(b.cat(m, k, p)), d.push(""));
4117
  });
4118
  return d.join("\n");
4119
  };
@@ -4165,7 +4165,7 @@ return a;
4165
  };
4166
  k = k = null;
4167
  return f;
4168
- }({}, y, w));
4169
  n.register("$17", function(f, d, n) {
4170
  f.init = function(d, f) {
4171
  function c() {
@@ -4208,16 +4208,16 @@ d.ajax.post("fsReference", h, a, b);
4208
  };
4209
  };
4210
  return f;
4211
- }({}, y, w));
4212
  n.register("$30", function(f, d, k) {
4213
- function m(d) {
4214
  this.api = d;
4215
  this.chars = 0;
4216
  }
4217
  f.create = function(d) {
4218
- return new m(d);
4219
  };
4220
- d = m.prototype;
4221
  d.init = function(d, c) {
4222
  function b(a) {
4223
  var b = {
@@ -4226,18 +4226,18 @@ html: a.html,
4226
  sources: []
4227
  };
4228
  B.push(b);
4229
- return x[a.html ? 1 : 0] = b;
4230
  }
4231
  function a(a, d) {
4232
  var g = a.source(null, d);
4233
  if (g && (a.untranslated(d) || c)) {
4234
- var u = p[g];
4235
  if (u) u.push(a); else {
4236
- var u = g.length, v = e.isHtml(g), v = x[v ? 1 : 0], B = v.sources;
4237
  if (s && u > s) l++; else {
4238
- if (v.length + u > n || B.length === m) v = b(v), B = v.sources;
4239
  B.push(g);
4240
- p[g] = [ a ];
4241
  v.length += u;
4242
  f += u;
4243
  k += 1;
@@ -4245,7 +4245,7 @@ k += 1;
4245
  }
4246
  }
4247
  }
4248
- var e = this.api, f = 0, k = 0, l = 0, m = 50, n = 1e4, s = e.maxChr(), p = {}, B = [], x = [];
4249
  s && (n = Math.min(n, s));
4250
  b({
4251
  html: !1
@@ -4257,8 +4257,8 @@ d.each(function(b, c) {
4257
  a(c, 0);
4258
  a(c, 1);
4259
  });
4260
- delete x;
4261
- this.map = p;
4262
  this.chars = f;
4263
  this.length = k;
4264
  this.batches = B;
@@ -4273,39 +4273,39 @@ d.dispatch = function() {
4273
  function d(a, b) {
4274
  function e(c, d, h) {
4275
  b !== h && (a === d || 1 < c && f.source(null, 1) === a) && (f.translate(b, c),
4276
- p++, r++);
4277
- return p;
4278
  }
4279
  if (!c()) return !1;
4280
  if (!b) return !0;
4281
- var f, h = n[a] || [], g = h.length, l = -1, p;
4282
- for (B++; ++l < g; ) if (f = h[l]) p = 0, f.each(e), p && k("each", [ f ]);
4283
  return !0;
4284
  }
4285
  function c() {
4286
- return "abort" === l.state ? (m && (m.abort(), f()), !1) : !0;
4287
  }
4288
  function b() {
4289
  var b = s.shift(), c;
4290
- b ? (c = b.sources) && c.length ? m.batch(c, p, b.html, d).fail(a).always(e) : e() : f();
4291
  }
4292
  function a() {
4293
  l.abort();
4294
  f();
4295
  }
4296
  function e() {
4297
- x++;
4298
- k("prog", [ x, y ]);
4299
  c() && b();
4300
  }
4301
  function f() {
4302
- m = s = null;
4303
  k("done");
4304
  }
4305
  function k(a, b) {
4306
  for (var c = u[a] || [], d = c.length; 0 <= --d; ) c[d].apply(null, b);
4307
  }
4308
- var l = this, m = l.api, n = l.map, s = l.batches || [], p = l.locale, B = 0, x = 0, r = 0, w = l.length, y = s.length, u = {
4309
  done: [],
4310
  each: [],
4311
  prog: []
@@ -4328,7 +4328,7 @@ return this;
4328
  stat: function() {
4329
  return {
4330
  todo: function() {
4331
- return Math.max(w - B, 0);
4332
  },
4333
  did: function() {
4334
  return B;
@@ -4338,72 +4338,16 @@ return B;
4338
  };
4339
  };
4340
  return f;
4341
- }({}, y, w));
4342
- n.register("$41", {
4343
- nn: [ "no" ]
4344
- });
4345
- n.register("$31", function(f, d, k) {
4346
- function m() {}
4347
- function g(c) {
4348
- c.parseError = function(b) {
4349
- return b && b.code && 200 !== b.code && b.message ? "Error " + b.code + ": " + b.message : "";
4350
- };
4351
- c.batch = function(b, a, d, f) {
4352
- function g(c) {
4353
- for (var d = b.length, e = -1; ++e < d && !1 !== f(b[e], c[e] || "", a); ) ;
4354
- }
4355
- d = d ? "html" : "plain";
4356
- var k = this.getSrc(), m = this.toLang(a);
4357
- return c._call({
4358
- url: "https://translate.yandex.net/api/v1.5/tr.json/translate?format=" + d + "&lang=" + k + "-" + m,
4359
- method: "POST",
4360
- traditional: !0,
4361
- data: {
4362
- key: c.key(),
4363
- text: b
4364
- }
4365
- }).done(function(a, b, d) {
4366
- a && 200 === a.code ? g(a.text || []) : (c.stderr(c.parseError(a) || c.httpError(d)),
4367
- g([]));
4368
- }).fail(function() {
4369
- g([]);
4370
- });
4371
- };
4372
- }
4373
- f.create = function(c) {
4374
- var b = m.prototype = new c();
4375
- b.toString = function() {
4376
- return "Yandex.Translate";
4377
- };
4378
- b.getId = function() {
4379
- return "yandex";
4380
- };
4381
- b.getUrl = function() {
4382
- return "https://translate.yandex.com/";
4383
- };
4384
- b.init = function(a) {
4385
- c.prototype.init.call(this, a);
4386
- /^trnsl\./.test(this.key()) && g(this);
4387
- };
4388
- b.toLang = function(a) {
4389
- return this.mapLang(a, n.require("$41", "yandex.json"));
4390
- };
4391
- b.maxChr = function() {
4392
- return 1e4;
4393
- };
4394
- return new m();
4395
- };
4396
- return f;
4397
- }({}, y, w));
4398
- n.register("$42", {
4399
  zh: [ "zh", "zh-CN", "zh-TW" ],
4400
  he: [ "iw" ],
4401
  jv: [ "jw" ]
4402
  });
4403
- n.register("$32", function(f, d, k) {
4404
- function m() {}
4405
  f.create = function(d) {
4406
- d = m.prototype = new d();
4407
  d.toString = function() {
4408
  return "Google Translate";
4409
  };
@@ -4426,9 +4370,9 @@ for (var h = c.length, g = -1, k; ++g < h && (k = a[g] || {}, !1 !== d(c[g], k.t
4426
  }
4427
  var g = this, k = this.getSrc();
4428
  a = a ? "html" : "text";
4429
- var m = g.mapLang(b, n.require("$42", "google.json"));
4430
  return g._call({
4431
- url: "https://translation.googleapis.com/language/translate/v2?source=" + k + "&target=" + m + "&format=" + a,
4432
  method: "POST",
4433
  traditional: !0,
4434
  data: {
@@ -4442,11 +4386,11 @@ f([]));
4442
  f([]);
4443
  });
4444
  };
4445
- return new m();
4446
  };
4447
  return f;
4448
- }({}, y, w));
4449
- n.register("$43", {
4450
  nn: [ "no" ],
4451
  pt: [ "pt", "pt-pt" ],
4452
  sr: [ "sr-Cyrl", "sr-Latn" ],
@@ -4458,10 +4402,10 @@ zh_HK: [ "zh-Hans" ],
4458
  zh_SG: [ "zh-Hans" ],
4459
  zh_TW: [ "zh-Hant" ]
4460
  });
4461
- n.register("$33", function(f, d, k) {
4462
- function m() {}
4463
  f.create = function(d) {
4464
- d = m.prototype = new d();
4465
  d.toString = function() {
4466
  return "Microsoft Translator text API";
4467
  };
@@ -4479,16 +4423,16 @@ return 1e4;
4479
  };
4480
  d.batch = function(c, b, a, d) {
4481
  function f(a) {
4482
- for (var h = -1, g; ++h < z && (g = a[h] || {}, g = g.translations || [], g = g[0] || {},
4483
  !1 !== d(c[h], g.text || "", b)); ) ;
4484
  }
4485
- var g = this, k = [], m = g.getSrc(), z = c.length, s = -1;
4486
  a = a ? "html" : "plain";
4487
- for (var p = g.mapLang(b, n.require("$43", "ms.json")); ++s < z; ) k.push({
4488
  text: c[s]
4489
  });
4490
  return g._call({
4491
- url: "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=" + m + "&to=" + p + "&textType=" + a,
4492
  method: "POST",
4493
  data: JSON.stringify(k),
4494
  headers: {
@@ -4502,17 +4446,17 @@ a && a.length ? f(a) : (g.stderr(g.parseError(a) || g.httpError(c)), f([]));
4502
  f([]);
4503
  });
4504
  };
4505
- return new m();
4506
  };
4507
  return f;
4508
- }({}, y, w));
4509
- n.register("$44", {
4510
  pt: [ "pt-PT", "pt-BR" ]
4511
  });
4512
- n.register("$34", function(f, d, k) {
4513
- function m() {}
4514
  f.create = function(d) {
4515
- d = m.prototype = new d();
4516
  d.toString = function() {
4517
  return "DeepL Translator";
4518
  };
@@ -4531,16 +4475,16 @@ for (var h = c.length, g = -1, k; ++g < h && (k = a[g] || {}, !1 !== d(c[g], k.t
4531
  }
4532
  var g = this;
4533
  a = this.getSrc();
4534
- var k = g.param("url") || "https://api.deepl.com", m = g.mapLang(b, n.require("$44", "deepl.json")), z = b.tone, s = "default";
4535
- null == z && (z = String(b.variant || "").toLowerCase());
4536
- "formal" === z ? s = "more" : "informal" === z && (s = "less");
4537
  return g._call({
4538
  url: g.fixURL(k + "/v2/translate"),
4539
  method: "POST",
4540
  traditional: !0,
4541
  data: {
4542
  source_lang: a.toUpperCase(),
4543
- target_lang: m.toUpperCase(),
4544
  formality: s,
4545
  preserve_formatting: "1",
4546
  auth_key: g.key(),
@@ -4553,18 +4497,18 @@ f([]));
4553
  f([]);
4554
  });
4555
  };
4556
- return new m();
4557
  };
4558
  return f;
4559
- }({}, y, w));
4560
- n.register("$45", {
4561
  zh: [ "zh", "zh-CN", "zh-TW" ],
4562
  pt: [ "pt", "pt-PT", "pt-BR" ]
4563
  });
4564
- n.register("$35", function(f, d, k) {
4565
- function m() {}
4566
  f.create = function(d) {
4567
- d = m.prototype = new d();
4568
  d.getUrl = function() {
4569
  return "https://lecto.ai/?ref=loco";
4570
  };
@@ -4586,12 +4530,12 @@ translated: []
4586
  }
4587
  var g = this;
4588
  a = this.getSrc();
4589
- var k = g.param("url") || "https://api.lecto.ai", m = g.mapLang(b, n.require("$45", "lecto.json"));
4590
  return g._call({
4591
  url: g.fixURL(k + "/v1/translate/text"),
4592
  method: "POST",
4593
  data: JSON.stringify({
4594
- to: [ m ],
4595
  from: a,
4596
  texts: c
4597
  }),
@@ -4606,16 +4550,16 @@ a ? f(a.translations || []) : (g.stderr(g.parseError(a) || g.httpError(c)), f([]
4606
  f([]);
4607
  });
4608
  };
4609
- return new m();
4610
  };
4611
  return f;
4612
- }({}, y, w));
4613
- n.register("$18", function(f, d, w) {
4614
- function m() {
4615
  this.inf = {};
4616
  }
4617
  function g() {
4618
- var a = w.createElement("p"), b = /&(#\d+|#x[0-9a-f]|[a-z]+);/i, c = /<[a-z]+\s/i, d, f;
4619
  return {
4620
  sniff: function(g) {
4621
  if (g === d) return f;
@@ -4625,7 +4569,7 @@ return f = !1;
4625
  }
4626
  };
4627
  }
4628
- var c = m.prototype;
4629
  c.init = function(a) {
4630
  this.inf = a || {};
4631
  };
@@ -4712,7 +4656,7 @@ c.batch = function(a, b, c, f) {
4712
  function g(c) {
4713
  for (var d = a.length, h = -1; ++h < d && !1 !== f(a[h], c[h], b); ) ;
4714
  }
4715
- var m = d.loco.ajax;
4716
  c = {
4717
  hook: this.getId(),
4718
  type: c ? "html" : "text",
@@ -4721,7 +4665,7 @@ source: this.getSrc(),
4721
  sources: a
4722
  };
4723
  var n = k.Deferred();
4724
- this.abortable(m.post("apis", c, function(a) {
4725
  g(a && a.targets || []);
4726
  n.resolve();
4727
  }, function() {
@@ -4733,7 +4677,7 @@ return n.promise();
4733
  f.create = function(a) {
4734
  var b;
4735
  b = a.id;
4736
- b = "yandex" === b ? n.require("$31", "yandex.js").create(m) : "google" === b ? n.require("$32", "google.js").create(m) : "microsoft" === b ? n.require("$33", "ms.js").create(m) : "deepl" === b ? n.require("$34", "deepl.js").create(m) : "lecto" === b ? n.require("$35", "lecto.js").create(m) : new m();
4737
  b.init(a);
4738
  return b;
4739
  };
@@ -4743,7 +4687,7 @@ for (f = 0; f < k; f++) g = a[f], g.translate(b, c, d);
4743
  };
4744
  var b;
4745
  return f;
4746
- }({}, y, w));
4747
  n.register("$19", function(f, d, n) {
4748
  f.init = function(f) {
4749
  function g() {
@@ -4759,7 +4703,7 @@ this.checked && k("#ssh-keys").toggleClass("hidden", "ssh" !== k(this).val());
4759
  return H;
4760
  }
4761
  function c() {
4762
- R && (b(k(x)), R = !1);
4763
  if (E && J) {
4764
  var a = J, c = k(Q);
4765
  c.find("span.loco-msg").text(a);
@@ -4773,15 +4717,15 @@ k(this).addClass("jshide");
4773
  }
4774
  function a() {
4775
  if (E) return H && H.dialog("close"), c(), k(f).find('button[type="submit"]').attr("disabled", !1),
4776
- k(d).triggerHandler("resize"), y && y(!0), !0;
4777
- v && H ? (R || (k(x).removeClass("jshide").hide().fadeIn(500), R = !0), K && (b(k(Q)),
4778
  K = !1)) : c();
4779
  k(f).find('input[type="submit"]').attr("disabled", !0);
4780
- y && y(!1);
4781
  return !1;
4782
  }
4783
  function e(a) {
4784
- var b, c, d = p || {};
4785
  for (b in d) d.hasOwnProperty(b) && (c = d[b], a[b] ? a[b].value = c : k('<input type="hidden" />').attr("name", b).appendTo(a).val(c));
4786
  }
4787
  function h(a) {
@@ -4801,13 +4745,13 @@ a.preventDefault();
4801
  H.dialog("open").find('input[name="connection_type"]').change();
4802
  return !1;
4803
  }
4804
- function w(b) {
4805
  E = b.authed;
4806
  r = b.method;
4807
- k(x).find("span.loco-msg").text(b.message || "Something went wrong.");
4808
  J = b.warning || "";
4809
  b.notice && u.notices.info(b.notice);
4810
- if (E) "direct" !== r && (p = b.creds, e(f), C && b.success && u.notices.success(b.success)),
4811
  a(); else if (b.reason) u.notices.info(b.reason); else if (b = b.prompt) {
4812
  var c = g();
4813
  c.html(b).find("form").on("submit", h);
@@ -4818,17 +4762,17 @@ a();
4818
  k(d).triggerHandler("resize");
4819
  } else u.notices.error("Server didn't return credentials, nor a prompt for credentials");
4820
  }
4821
- function z() {
4822
  a();
4823
  }
4824
  function s(a) {
4825
  C = !1;
4826
- u.ajax.setNonce("fsConnect", N).post("fsConnect", a, w, z);
4827
  return a;
4828
  }
4829
- var p, y, x = f, r = null, C = !1, E = !1, u = d.loco, v = f.path.value, F = f.auth.value, N = f["loco-nonce"].value, I = k(x).find("button.button-primary"), Q = n.getElementById(x.id + "-warn"), R = !1, K = !1, J = "", H;
4830
  u.notices.convert(Q).stick();
4831
- f.connection_type ? (p = {}, p.connection_type = f.connection_type.value, E = !0) : v && F && s({
4832
  path: v,
4833
  auth: F
4834
  });
@@ -4836,7 +4780,7 @@ a();
4836
  return {
4837
  applyCreds: function(a) {
4838
  if (a.nodeType) e(a); else {
4839
- var b, c = p || {};
4840
  for (b in c) c.hasOwnProperty(b) && (a[b] = c[b]);
4841
  }
4842
  return this;
@@ -4854,7 +4798,7 @@ s(k(f).serializeArray());
4854
  return this;
4855
  },
4856
  listen: function(a) {
4857
- y = a;
4858
  E && a(!0);
4859
  return this;
4860
  },
@@ -4864,9 +4808,9 @@ return E;
4864
  };
4865
  };
4866
  return f;
4867
- }({}, y, w));
4868
- n.register("$20", function(f, d, w) {
4869
- function m(d, f, k, l) {
4870
  f = "n" === k ? c(f) : b(f);
4871
  l && (f = a(f));
4872
  return g([].sort, [ f ])(d);
@@ -4896,32 +4840,32 @@ return -1 * a(b, c);
4896
  f.init = function(a) {
4897
  function b(a) {
4898
  var c = -1, d = a.length;
4899
- for (k("tr", x).remove(); ++c < d; ) x.appendChild(a[c].$);
4900
  }
4901
  function c(a) {
4902
- s = a ? y.find(a, d) : d.slice(0);
4903
- w && (a = f[w], s = m(s, w, a.type, a.desc));
4904
  b(s);
4905
  }
4906
- var d = [], f = [], g = 0, s, p, w, x = a.getElementsByTagName("tbody")[0], r = a.getElementsByTagName("thead")[0], y = n.require("$10", "fulltext.js").init();
4907
- r && x && (k("th", r).each(function(a, c) {
4908
  var e = c.getAttribute("data-sort-type");
4909
  e && (a = g, k(c).addClass("loco-sort").on("click", function(c) {
4910
  c.preventDefault();
4911
  c = a;
4912
  var e = f[c], g = e.type, n = !(e.desc = !e.desc);
4913
- s = m(s || d.slice(0), c, g, n);
4914
  b(s);
4915
- p && p.removeClass("loco-desc loco-asc");
4916
- p = k(e.$).addClass(n ? "loco-desc" : "loco-asc").removeClass(n ? "loco-asc" : "loco-desc");
4917
- w = c;
4918
  return !1;
4919
  }), f[g] = {
4920
  $: c,
4921
  type: e
4922
  });
4923
  c.hasAttribute("colspan") ? g += Number(c.getAttribute("colspan")) : g++;
4924
- }), k("tr", x).each(function(a, b) {
4925
  var c, e, g, h = [], k = {
4926
  _: a,
4927
  $: b
@@ -4937,7 +4881,7 @@ g = Number(g);
4937
  k[e] = g;
4938
  }
4939
  d[a] = k;
4940
- y.index(a, h);
4941
  }), a = k('form.loco-filter input[type="text"]', a.parentNode), a.length && (a = a[0],
4942
  r = k(a.form), 1 < d.length ? n.require("$11", "LocoTextListener.js").listen(a, c) : r.hide(),
4943
  r.on("submit", function(a) {
@@ -4946,12 +4890,12 @@ return !1;
4946
  })));
4947
  };
4948
  return f;
4949
- }({}, y, w));
4950
- var C = y.loco || {}, I = C.conf || {
4951
  $v: [ 0, 0 ]
4952
  };
4953
- y = n.require("$1", "t.js").init();
4954
- w = I.wplang;
4955
  C.version = function(f) {
4956
  return I.$v[f || 0];
4957
  };
@@ -4959,12 +4903,12 @@ n.require("$2", "html.js");
4959
  n.require("$3", "number.js");
4960
  n.require("$4", "array.js");
4961
  n.require("$5", "json.js");
4962
- C.l10n = y;
4963
- y.load(I.wpl10n);
4964
- w && y.pluraleq(w.pluraleq);
4965
  C.string = n.require("$6", "string.js");
4966
- C.notices = n.require("$7", "notices.js").init(y);
4967
- C.ajax = n.require("$8", "ajax.js").init(I).localise(y);
4968
  C.locale = n.require("$9", "wplocale.js");
4969
  C.fulltext = n.require("$10", "fulltext.js");
4970
  C.watchtext = n.require("$11", "LocoTextListener.js").listen;
@@ -4982,7 +4926,7 @@ k("#loco-admin.wrap table.wp-list-table").each(function(f, d) {
4982
  n.require("$20", "tables.js").init(d);
4983
  });
4984
  C.validate = function(f) {
4985
- return "2.5.8" !== (/^\d+\.\d+\.\d+/.exec(f && f[0] || "") && RegExp.lastMatch) ? (C.notices.warn("admin.js is the wrong version (2.5.8). Please empty all relevant caches and reload this page."),
4986
  !1) : !0;
4987
  };
4988
  })(window, document, window.jQuery);
1
+ (function(z, x, k, J) {
2
  var n = function() {
3
  function f(d) {
4
  throw Error("Failed to require " + d);
5
  }
6
  var d = {};
7
  return {
8
+ register: function(f, p) {
9
+ d[f] = p;
10
  },
11
+ require: function(k, p) {
12
+ return d[k] || f(p);
13
  },
14
+ include: function(k, p, g) {
15
+ return d[k] || (g ? f(p) : null);
16
  }
17
  };
18
  }();
19
  n.register("$1", function(f, d, k) {
20
+ function p(g) {
21
  var c = typeof g;
22
  if ("string" === c) if (/[^ <>!=()%^&|?:n0-9]/.test(g)) console.error("Invalid plural: " + g); else return new Function("n", "return " + g);
23
  "function" !== c && (g = function(b) {
40
  isNaN(e) && (e = 0);
41
  return c(a, e ? b : a, e);
42
  }
43
+ g = p(g);
44
  var h = {};
45
  return {
46
  __: b,
54
  return this;
55
  },
56
  pluraleq: function(a) {
57
+ g = p(a);
58
  return this;
59
  }
60
  };
61
  };
62
  return f;
63
+ }({}, z, x));
64
  n.register("$2", function(f, d, k) {
65
  f.ie = function() {
66
  var f = !1, g = 0;
74
  return f;
75
  };
76
  return f;
77
+ }({}, z, x));
78
  n.register("$3", function(f, d, k) {
79
  Number.prototype.format = function(d, g, c) {
80
  d = Math.pow(10, d || 0);
108
  return d;
109
  };
110
  return f;
111
+ }({}, z, x));
112
  n.register("$4", function(f, d, k) {
113
  Array.prototype.indexOf || (Array.prototype.indexOf = function(d) {
114
  if (null == this) throw new TypeError();
121
  return -1;
122
  });
123
  return f;
124
+ }({}, z, x));
125
  n.register("$5", function(f, d, n) {
126
  d.JSON || (d.JSON = {
127
  parse: k.parseJSON,
128
  stringify: null
129
  });
130
  return f = d.JSON;
131
+ }({}, z, x));
132
  n.register("$6", function(f, d, k) {
133
  f.trim = function(d, g) {
134
  for (g || (g = " \n"); d && -1 !== g.indexOf(d.substr(0, 1)); ) d = d.substr(1);
142
  });
143
  };
144
  return f;
145
+ }({}, z, x));
146
  n.register("$21", function(f, d, k) {
147
+ function p(g) {
148
  return function(c, b) {
149
  for (var a = c[g] || 0; (c = c.offsetParent) && c !== (b || k.body); ) a += c[g] || 0;
150
  return a;
151
  };
152
  }
153
+ f.top = p("offsetTop");
154
+ f.left = p("offsetLeft");
155
  f.el = function(g, c) {
156
  var b = k.createElement(g || "div");
157
  c && (b.className = c);
161
  return k.createTextNode(g || "");
162
  };
163
  return f;
164
+ }({}, z, x));
165
  n.register("$7", function(f, d, D) {
166
+ function p(a, b, e) {
167
  function c() {
168
+ m();
169
  v = setTimeout(b, e);
170
  }
171
+ function m() {
172
  v && clearTimeout(v);
173
  v = null;
174
  }
175
  var v;
176
  c();
177
+ k(a).on("mouseenter", m).on("mouseleave", c);
178
  return {
179
  die: function() {
180
+ m();
181
  k(a).off("mouseenter mouseleave");
182
  }
183
  };
195
  function e(b) {
196
  q[v] = null;
197
  g(k(a), 250);
198
+ m && m.die();
199
  var c;
200
  if (c = b) b.stopPropagation(), b.preventDefault(), c = !1;
201
  return c;
202
  }
203
  function c(b) {
204
+ m && m.die();
205
+ return m = p(a, e, b);
206
  }
207
+ var m, v, h, l = k(a), B = l.find("button");
208
  0 === B.length && (l.addClass("is-dismissible"), B = k('<button type="button" class="notice-dismiss"> </a>').appendTo(l));
209
  B.off("click").on("click", e);
210
  k(d).triggerHandler("resize");
211
  A();
212
  v = q.length;
213
  q.push(e);
214
+ b && (m = c(b));
215
  return {
216
  link: function(b, v) {
217
+ var e = v || b, m = k(a).find("nav"), e = k("<nav></nav>").append(k("<a></a>").attr("href", b).text(e));
218
+ h ? (h.push(e.html()), m.html(h.join("<span> | </span>"))) : (h = [ e.html() ],
219
  k(a).addClass("has-nav").append(e));
220
  return this;
221
  },
222
  stick: function() {
223
+ m && m.die();
224
+ m = null;
225
  q[v] = null;
226
  return this;
227
  },
232
  };
233
  }
234
  function b(a, b, e) {
235
+ var m = n.require("$21", "dom.js").el;
236
  a = k('<div class="notice notice-' + a + ' loco-notice inline"></div>').prependTo(k("#loco-notices"));
237
+ var c = k(m("p"));
238
+ e = k(m("span")).text(e);
239
+ b = k(m("strong", "has-icon")).text(b + ": ");
240
+ c.append(b).append(e).appendTo(a);
241
  return a;
242
  }
243
+ function a(a, e, m, h) {
244
+ a = b(m, e, a).css("opacity", "0").fadeTo(500, 1);
245
  k(d).triggerHandler("resize");
246
  return c(a, h);
247
  }
260
  log: function() {}
261
  }, A = Date.now || function() {
262
  return new Date().getTime();
263
+ }, w, s, m, B;
264
  f.error = function(b) {
265
+ return a(b, w, "error");
266
  };
267
  f.warn = e;
268
  f.info = function(b) {
269
+ return a(b, m, "info");
270
  };
271
  f.success = function(b) {
272
  return a(b, B, "success", 5e3);
279
  (l.debug || l.log).apply(l, arguments);
280
  };
281
  f.clear = function() {
282
+ for (var a = -1, b, e = q, m = e.length; ++a < m; ) (b = e[a]) && b.call && b();
283
  q = [];
284
  return f;
285
  };
289
  };
290
  f.convert = c;
291
  f.init = function(a) {
292
+ w = a._("Error");
293
  s = a._("Warning");
294
+ m = a._("Notice");
295
  B = a._("OK");
296
  setTimeout(h, 1e3);
297
  return f;
298
  };
299
  return f;
300
+ }({}, z, x));
301
  n.register("$8", function(f, d, D) {
302
+ function p(a) {
303
  var b = k("<pre>" + a + "</pre>").text();
304
  b && (b = b.replace(/[\r\n]+/g, "\n").replace(/(^|\n)\s+/g, "$1").replace(/\s+$/, ""));
305
  b || (b = a) || (b = "Blank response from server");
328
  function h(a, b, e, c) {
329
  function h(b, c, v) {
330
  if ("abort" !== c) {
331
+ var m = l || {
332
  _: function(a) {
333
  return a;
334
  }
335
+ }, r = b.status || 0, d = b.responseText || "", y = p(d), w = b.getResponseHeader("Content-Type") || "Unknown type", f = b.getResponseHeader("Content-Length") || d.length;
336
+ "success" === c && v ? q.error(v) : (q.error(g(y) + ".\n" + m._("Check console output for debugging information")),
337
  q.log("Ajax failure for " + a, {
338
  status: r,
339
  error: c,
340
  message: v,
341
  output: d
342
+ }), "parsererror" === c && (v = "Response not JSON"), q.log([ m._("Provide the following text when reporting a problem") + ":", "----", "Status " + r + ' "' + (v || m._("Unknown error")) + '" (' + w + " " + f + " bytes)", y, "====" ].join("\n")));
343
  e && e.call && e(b, c, v);
344
  A = b;
345
  }
346
  }
347
+ c.url = w;
348
  c.dataType = "json";
349
  var q = n.require("$7", "notices.js").clear();
350
  A = null;
353
  for (!c || a.error ? h(v, e, a && a.error && a.error.message) : b && b(c, e, v); ++A < g; ) q.raise(l[A]);
354
  });
355
  }
356
+ var q = {}, l, A, w = d.ajaxurl || "/wp-admin/admin-ajax.php";
357
  f.init = function(a) {
358
  q = a.nonces || q;
359
  return f;
365
  f.xhr = function() {
366
  return A;
367
  };
368
+ f.strip = p;
369
  f.parse = g;
370
  f.submit = function(a, b, e) {
371
  function c(a, b) {
402
  data: A
403
  });
404
  };
405
+ f.post = function(l, m, A, g) {
406
+ var r = !0, G = m || {}, w = q[l] || c(l);
407
+ d.FormData && G instanceof FormData ? (r = !1, m = e) : m = Array.isArray(G) ? a : b;
408
+ m(G, "action", "loco_json");
409
+ m(G, "route", l);
410
+ m(G, "loco-nonce", w);
411
  return h(l, A, g, {
412
  type: "post",
413
  data: G,
431
  return f;
432
  };
433
  return f;
434
+ }({}, z, x));
435
  n.register("$22", {
436
  arab: 1,
437
  aran: 1,
471
  yi: 1
472
  });
473
  n.register("$9", function(f, d, k) {
474
+ function p() {}
475
  var g, c = n.require("$22", "rtl.json");
476
  f.init = function() {
477
+ return new p();
478
  };
479
  f.cast = function(b) {
480
+ return b instanceof p ? b : "string" === typeof b ? f.parse(b) : f.clone(b);
481
  };
482
  f.clone = function(b) {
483
+ var a, e = new p();
484
  for (a in b) e[a] = b[a];
485
  return e;
486
  };
487
  f.parse = function(b) {
488
  if (!(g || (g = /^([a-z]{2,3})(?:[-_]([a-z]{2}))?(?:[-_]([a-z0-9]{3,8}))?$/i)).exec(b)) return null;
489
+ var a = new p();
490
  a.lang = RegExp.$1.toLowerCase();
491
  if (b = RegExp.$2) a.region = b.toUpperCase();
492
  if (b = RegExp.$3) a.variant = b.toLowerCase();
493
  return a;
494
  };
495
+ d = p.prototype;
496
  d.isValid = function() {
497
  return !!this.lang;
498
  };
517
  };
518
  d = null;
519
  return f;
520
+ }({}, z, x));
521
  n.register("$23", {
522
  "á": "a",
523
  "à": "a",
944
  return g(String(a || "").toLowerCase().replace(h, d), q, [], {});
945
  }
946
  function b(a, b) {
947
+ for (var c = [], m = {}, l, y = b.length, r = q; 0 !== y--; ) (l = b[y]) && g(String(l || "").toLowerCase().replace(h, d), r, c, m);
948
  e[a] = c;
949
  }
950
  function a(a, b) {
951
+ var c = [], h = -1, l = e, q = l.length, r, g, d, u, v, F, f = a.length, k = b ? !0 : !1;
952
+ a: for (;++h < q; ) if (d = l[h], null != d && (u = d.length)) {
953
  v = 0;
954
  b: for (;v < f; v++) {
955
  F = a[v];
990
  };
991
  };
992
  return f;
993
+ }({}, z, x));
994
  n.register("$11", function(f, d, n) {
995
  f.listen = function(f, g) {
996
  function c() {
997
+ m[h ? "show" : "hide"]();
998
  }
999
  function b(a) {
1000
  s && A.setAttribute("size", 2 + a.length);
1008
  }
1009
  function e(e) {
1010
  var c = A.value;
1011
+ w && c === w && (c = "");
1012
  c !== h ? (q && clearTimeout(q), b(c), e ? q = setTimeout(a, e) : a()) : q && null == e && (clearTimeout(q),
1013
  a());
1014
  }
1015
+ var h, q, l = 150, A = f instanceof jQuery ? f[0] : f, w = d.attachEvent && A.getAttribute("placeholder"), s = 1 === Number(A.size), m = k('<a href="#clear" tabindex="-1" class="icon clear"><span>clear</span></a>').on("click", function() {
1016
  A.value = "";
1017
  e();
1018
  return !1;
1024
  }).on("blur focus change", function() {
1025
  e(null);
1026
  return !0;
1027
+ }).after(m);
1028
  c();
1029
  return {
1030
  delay: function(a) {
1032
  return this;
1033
  },
1034
  ping: function(c) {
1035
+ c ? (q && clearTimeout(q), c = A.value, w && c === w && (c = ""), b(c), a(), c = void 0) : c = e();
1036
  return c;
1037
  },
1038
  val: function(a) {
1053
  };
1054
  };
1055
  return f;
1056
+ }({}, z, x));
1057
  n.register("$12", function(f, d, n) {
1058
+ function p(b, a) {
1059
  this.$element = k(b);
1060
  this.options = a;
1061
  this.enabled = !0;
1089
  f.kill();
1090
  return !0;
1091
  });
1092
+ p.prototype = {
1093
  show: function() {
1094
  var b = this.getTitle();
1095
  if (b && this.enabled) {
1181
  k.fn.tipsy = function(b) {
1182
  function a(a) {
1183
  var e = k.data(a, "tipsy");
1184
+ e || (e = new p(a, k.fn.tipsy.elementOptions(a, b)), k.data(a, "tipsy", e));
1185
  return e;
1186
  }
1187
  function e() {
1243
  };
1244
  };
1245
  return f;
1246
+ }({}, z, x));
1247
+ n.register("$35", function(f, d, k) {
1248
  "".localeCompare || (String.prototype.localeCompare = function() {
1249
  return 0;
1250
  });
1274
  };
1275
  }();
1276
  return f;
1277
+ }({}, z, x));
1278
+ n.register("$36", function(f, d, k) {
1279
+ function p() {}
1280
  var g, c, b = n.require("$22", "rtl.json");
1281
  f.init = function() {
1282
+ return new p();
1283
  };
1284
  f.cast = function(a) {
1285
+ return a instanceof p ? a : "string" === typeof a ? f.parse(a) : f.clone(a);
1286
  };
1287
  f.clone = function(a) {
1288
+ var b, c = new p();
1289
  for (b in a) c[b] = a[b];
1290
  return c;
1291
  };
1293
  g || (c = /[-_+]/, g = /^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}|[0-9]{3}))?(?:-([0-9][a-z0-9]{3,8}|[a-z0-9]{5,8}))?(?:-([a-z]-[-a-z]+))?$/i);
1294
  a = String(a).split(c).join("-");
1295
  if (!g.exec(a)) return null;
1296
+ var b = new p();
1297
  b.lang = RegExp.$1.toLowerCase();
1298
  if (a = RegExp.$2) b.script = a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
1299
  if (a = RegExp.$3) b.region = a.toUpperCase();
1301
  if (a = RegExp.$5) b.extension = a;
1302
  return b;
1303
  };
1304
+ d = p.prototype;
1305
  d.isValid = function() {
1306
  return !!this.lang;
1307
  };
1328
  };
1329
  d = null;
1330
  return f;
1331
+ }({}, z, x));
1332
+ n.register("$37", function(f, d, k) {
1333
+ function p(a) {
1334
  d.console && console.error && console.error(a);
1335
  }
1336
  function g() {
1337
+ p("Method not implemented");
1338
  }
1339
  function c() {}
1340
  function b(a) {}
1343
  };
1344
  b.prototype._validate = function(a) {
1345
  var b, h, q = !0;
1346
+ for (b in this) h = this[b], h === g ? (p(a + "." + b + "() must be implemented"),
1347
+ q = !1) : h instanceof c && (p(a + "." + b + " must be defined"), q = !1);
1348
  return q;
1349
  };
1350
  f.init = function(a, e) {
1358
  a.prototype._validate(b || "Object");
1359
  };
1360
  return f;
1361
+ }({}, z, x));
1362
+ n.register("$48", function(f, d, k) {
1363
+ var p = d.requestAnimationFrame, g = d.cancelAnimationFrame, c = 0;
1364
+ if (!p || !g) for (var b in {
1365
  ms: 1,
1366
  moz: 1,
1367
  webkit: 1,
1368
  o: 1
1369
+ }) if (p = d[b + "RequestAnimationFrame"]) if (g = d[b + "CancelAnimationFrame"] || d[b + "CancelRequestAnimationFrame"]) break;
1370
+ p && g || (p = function(b) {
1371
  var h = a();
1372
  timeToCall = Math.max(0, 16 - (h - c));
1373
  nextTime = h + timeToCall;
1384
  };
1385
  f.loop = function(a, b) {
1386
  function c() {
1387
+ d = p(c, b);
1388
  a(l++);
1389
  }
1390
  var l = 0, d;
1397
  };
1398
  };
1399
  return f;
1400
+ }({}, z, x));
1401
+ n.register("$45", function(f, d, k) {
1402
+ function p(a, c, e, m) {
1403
  if (b) {
1404
  var l = e;
1405
  e = function(a) {
1406
  if ((a.MSPOINTER_TYPE_TOUCH || "touch") === a.pointerType) return l(a);
1407
  };
1408
  }
1409
+ a.addEventListener(c, e, m);
1410
  return {
1411
  unbind: function() {
1412
+ a.removeEventListener(c, e, m);
1413
  }
1414
  };
1415
  }
1431
  function l(a) {
1432
  b.addEventListener(a, d[a], !1);
1433
  }
1434
+ function m(a) {
1435
  b.removeEventListener(a, d[a], !1);
1436
  }
1437
  var d = {};
1438
  d[a] = function(b) {
1439
+ q(b, function(e, m) {
1440
+ m.type = a;
1441
+ c(b, m, f);
1442
  });
1443
  l(e);
1444
  l(h);
1445
  return !0;
1446
  };
1447
  d[h] = function(a) {
1448
+ m(e);
1449
+ m(h);
1450
  q(a, function(b, e) {
1451
  e.type = h;
1452
  c(a, e, f);
1454
  return !0;
1455
  };
1456
  d[e] = function(a) {
1457
+ q(a, function(b, m) {
1458
+ m.type = e;
1459
+ c(a, m, f);
1460
  });
1461
  return g(a);
1462
  };
1463
  l(a);
1464
  var f = {
1465
  kill: function() {
1466
+ m(a);
1467
+ m(e);
1468
+ m(h);
1469
  b = f = c = null;
1470
  }
1471
  };
1472
  return f;
1473
  };
1474
  f.swiper = function(c, d, f) {
1475
+ function m(a) {
1476
  c.addEventListener(a, u[a], !1);
1477
  }
1478
  function B(a) {
1479
  c.removeEventListener(a, u[a], !1);
1480
  }
1481
+ function y() {
1482
  r && r.stop();
1483
  r = null;
1484
  }
1485
  var r, G, E, u = {}, v = [], F = [], k = [];
1486
  u[a] = function(a) {
1487
  G = !1;
1488
+ y();
1489
  var b = l();
1490
  q(a, function(a, c) {
1491
  v[a] = b;
1513
  b && (G = !0, c.scrollLeft = Math.max(0, E + b));
1514
  return g(a);
1515
  };
1516
+ if (!b || f) m(a), m(e), m(h), b && (c.className += " mstouch");
1517
  return {
1518
  kill: function() {
1519
  B(a);
1520
  B(e);
1521
  B(h);
1522
+ y();
1523
  },
1524
  swiped: function() {
1525
  return G;
1532
  c.style["-ms-scroll-snap-type"] = "mandatory", c.style["-ms-scroll-chaining"] = "none");
1533
  },
1534
  scroll: function(a, b, e) {
1535
+ y();
1536
+ var v = c.scrollLeft, m = a > v ? 1 : -1, l = Math[1 === m ? "min" : "max"], h = Math.round(16 * b * m);
1537
+ return r = n.require("$48", "fps.js").loop(function(b) {
1538
+ b && (v = Math.max(0, l(a, v + h)), c.scrollLeft = v, a === v && (y(), e && e(v)));
1539
  }, c);
1540
  }
1541
  };
1542
  };
1543
  f.start = function(b, c) {
1544
+ return p(b, a, c, !1);
1545
  };
1546
  f.move = function(a, b) {
1547
+ return p(a, e, b, !1);
1548
  };
1549
  f.end = function(a, b) {
1550
+ return p(a, h, b, !1);
1551
  };
1552
  var q = f.each = function(a, c) {
1553
+ if (b) (a.MSPOINTER_TYPE_TOUCH || "touch") === a.pointerType && c(0, a); else for (var e = -1, m = (a.originalEvent || a).changedTouches || []; ++e < m.length; ) c(e, m[e]);
1554
  }, l = Date.now || function() {
1555
  return new Date().getTime();
1556
  };
1557
  return f;
1558
+ }({}, z, x));
1559
+ n.register("$49", function(f, d, n) {
1560
  f.init = function(d) {
1561
  function g() {
1562
  e.style.top = String(-d.scrollTop) + "px";
1589
  };
1590
  };
1591
  return f;
1592
+ }({}, z, x));
1593
  n.register("$29", function(f, d, k) {
1594
+ function p(b, a) {
1595
  for (var c = 0, h = -1, q = a && d[a], l = g[b] || [], f = l.length; ++h < f; ) callback = l[h],
1596
  "function" === typeof callback && (callback(q), c++);
1597
  return c;
1600
  f.load = function(b, a, c) {
1601
  function h() {
1602
  f && (clearTimeout(f), f = null);
1603
+ w && (w.onreadystatechange = null, w = w = w.onload = null);
1604
  b && (delete g[b], b = null);
1605
  }
1606
+ function q(a, m) {
1607
+ var l = w && w.readyState;
1608
+ if (m || !l || "loaded" === l || "complete" === l) m || p(b, c), h();
1609
  }
1610
  function l() {
1611
+ if (0 === p(b)) throw Error('Failed to load "' + (c || b) + '"');
1612
  h();
1613
  }
1614
  if (c && d[c]) "function" === typeof a && a(d[c]); else if (null != g[b]) g[b].push(a); else {
1615
  g[b] = [ a ];
1616
+ var f = setTimeout(l, 4e3), w = k.createElement("script");
1617
+ w.setAttribute("src", b);
1618
+ w.setAttribute("async", "true");
1619
+ w.onreadystatechange = q;
1620
+ w.onload = q;
1621
+ w.onerror = l;
1622
+ w.onabort = h;
1623
+ k.getElementsByTagName("head")[0].appendChild(w);
1624
  }
1625
  };
1626
  f.stat = function(b) {
1636
  return a + b;
1637
  };
1638
  return f;
1639
+ }({}, z, x));
1640
  n.register("$16", function(f, d, D) {
1641
+ function p(a, b) {
1642
  a.setReadOnly(!1);
1643
  a.on("change", function(a, c) {
1644
  return b.val(c.getValue());
1665
  function e() {
1666
  this.HighlightRules = h;
1667
  }
1668
+ var h = a(c), m = b.require, d = m("ace/lib/oop");
1669
+ d.inherits(h, m("ace/mode/text_highlight_rules").TextHighlightRules);
1670
+ d.inherits(e, m("ace/mode/text").Mode);
1671
  return new e();
1672
  }
1673
  function a(a) {
1763
  }
1764
  var h, q = "auto";
1765
  f.init = function(a, e, h) {
1766
+ var f, m = !1, B = h || q, y = a.parentNode, r = y.appendChild(D.createElement("div"));
1767
+ k(y).addClass("has-proxy has-ace");
1768
  n.require("$29", "remote.js").load("https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js", function(h) {
1769
  if (r) {
1770
  if (!h) throw Error("Failed to load code editor");
1771
  f = h.edit(r);
1772
+ var d = f.session, g = f.renderer;
1773
  f.$blockScrolling = Infinity;
1774
+ f.setShowInvisibles(m);
1775
  f.setWrapBehavioursEnabled(!1);
1776
  f.setBehavioursEnabled(!1);
1777
  f.setHighlightActiveLine(!1);
1778
  d.setUseSoftTabs(!1);
1779
+ g.setShowGutter(!0);
1780
+ g.setPadding(10);
1781
+ g.setScrollMargin(8);
1782
  d.setMode(b(h, B));
1783
  f.setValue(a.value, -1);
1784
  d.setUseWrapMode(!0);
1785
+ e ? p(f, e) : c(f);
1786
  }
1787
  }, "ace");
1788
  return {
1789
  kill: function() {
1790
  f && (g(f), f.destroy(), f = null);
1791
+ r && (y.removeChild(r), k(y).removeClass("has-proxy has-ace"), r = null);
1792
  return this;
1793
  },
1794
  disable: function() {
1798
  },
1799
  enable: function(a) {
1800
  e = a;
1801
+ f && p(f, a);
1802
  return this;
1803
  },
1804
  resize: function() {
1811
  },
1812
  invs: function(a) {
1813
  a = a || !1;
1814
+ m !== a && (m = a, f && f.setShowInvisibles(a));
1815
  return this;
1816
  },
1817
  strf: function(a) {
1830
  return f;
1831
  };
1832
  return f;
1833
+ }({}, z, x));
1834
+ n.register("$50", function(f, d, D) {
1835
+ function p(a, b) {
1836
  function c() {
1837
  return b.val(a.getContent());
1838
  }
1864
  };
1865
  f.init = function(a, e) {
1866
  function h(a) {
1867
+ w = a;
1868
  s = "<p>" === a.substr(0, 3) && "</p>" === a.substr(-4);
1869
  return a.replace(/(<\/?)script/gi, "$1loco:script");
1870
  }
1876
  a = a.replace(/(<\/?)loco:script/gi, "$1script");
1877
  if (!s && "<p>" === a.substr(0, 3) && "</p>" === a.substr(-4)) {
1878
  var b = a.substr(3, a.length - 7);
1879
+ if (b === w || -1 === b.indexOf("</p>")) a = b;
1880
  }
1881
  return a;
1882
  };
1884
  a.setContent = function(a, b) {
1885
  return this._setContent(h(a), b);
1886
  };
1887
+ e ? (p(a, e), e.reset()) : c(a);
1888
+ k(y).removeClass("loading");
1889
  }
1890
+ var l, A = !1, w = "", s = !1, m = a.parentNode, B = m.parentNode, y = m.appendChild(D.createElement("div")), r = B.insertBefore(D.createElement("nav"), m);
1891
  r.id = "_tb" + String(++b);
1892
+ k(m).addClass("has-proxy has-mce");
1893
+ k(y).addClass("mce-content-body loading").html(h(a.value));
1894
  f.load(function(a) {
1895
  if (!a) throw Error("Failed to load HTML editor");
1896
+ y && a.init({
1897
  inline: !0,
1898
+ target: y,
1899
  hidden_input: !1,
1900
  theme: "modern",
1901
  skin: !1,
1938
  return {
1939
  val: function(b) {
1940
  b = h(b);
1941
+ null == l ? (a.value = b, k(y).html(b)) : l.getContent() !== b && l.setContent(b);
1942
  e && e.val(b);
1943
  return this;
1944
  },
1945
  kill: function() {
1946
  l && (e && e.val(l.getContent()), g(l), l.destroy(), l = null);
1947
+ y && (m.removeChild(y), k(m).removeClass("has-proxy has-mce"), y = null);
1948
  r && (B.removeChild(r), r = null);
1949
  return this;
1950
  },
1951
  enable: function(a) {
1952
  e = a;
1953
+ l && p(l, a);
1954
  return this;
1955
  },
1956
  disable: function() {
1964
  },
1965
  invs: function(a) {
1966
  a = a || !1;
1967
+ A !== a && (A = a, k(m)[a ? "addClass" : "removeClass"]("show-invs"));
1968
  return this;
1969
  }
1970
  };
1971
  };
1972
  return f;
1973
+ }({}, z, x));
1974
+ n.register("$46", function(f, d, D) {
1975
+ function p(b) {
1976
  function a() {
1977
+ f && (w.off("input", e), f = !1);
1978
  }
1979
  function e() {
1980
  var a = b.value;
1981
+ a !== m && (w.trigger("changing", [ a, m ]), m = a);
1982
  }
1983
+ function d() {
1984
  e();
1985
+ f && B !== m && w.trigger("changed", [ m ]);
1986
  }
1987
+ function g() {
1988
  c = b;
1989
+ B = m;
1990
+ f || (w.on("input", e), f = !0);
1991
+ w.trigger("editFocus");
1992
  s.addClass("has-focus");
1993
  return !0;
1994
  }
1995
  function l() {
1996
  c === b && (c = null);
1997
+ w.trigger("editBlur");
1998
  s.removeClass("has-focus");
1999
+ f && (d(), a());
2000
  return !0;
2001
  }
2002
+ var f = !1, w = k(b), s = k(b.parentNode), m = b.value, B;
2003
+ w.on("blur", l).on("focus", g);
2004
  return {
2005
  val: function(a) {
2006
+ m !== a && (b.value = a, w.triggerHandler("input"), m = a);
2007
  return !0;
2008
  },
2009
  kill: function() {
2010
  a();
2011
+ w.off("blur", l).off("focus", g);
2012
  },
2013
  fire: function() {
2014
+ m = null;
2015
  e();
2016
  },
2017
+ ping: d,
2018
  blur: l,
2019
+ focus: g,
2020
  reset: function() {
2021
+ B = m = b.value;
2022
  }
2023
  };
2024
  }
2101
  TextAreaPrototype.listen = function() {
2102
  var b = this.l;
2103
  b && b.kill();
2104
+ this.l = p(this.e);
2105
  return this;
2106
  };
2107
  TextAreaPrototype.unlisten = function() {
2111
  };
2112
  TextAreaPrototype.setInvs = function(b, a) {
2113
  var c = this.i || !1;
2114
+ if (a || c !== b) this._i && (this._i.kill(), delete this._i), (c = this.p) ? c.invs && c.invs(b) : b && (this._i = n.require("$49", "mirror.js").init(this.e)),
2115
  this.i = b;
2116
  return this;
2117
  };
2120
  };
2121
  TextAreaPrototype.setMode = function(b) {
2122
  var a = this.p, e = this.i || !1;
2123
+ b !== (this.m || "") && (this.m = b, a && a.kill(), this.p = a = "code" === b ? n.require("$16", "ace.js").init(this.e, this.l, this["%"]) : "html" === b ? n.require("$50", "mce.js").init(this.e, this.l) : null,
2124
  this.setInvs(e, !0), c && this.focus());
2125
  return this;
2126
  };
2143
  };
2144
  TextAreaPrototype = null;
2145
  return f;
2146
+ }({}, z, x));
2147
+ n.register("$47", function(f, d, n) {
2148
+ function p(a) {
2149
  var b = d.console;
2150
  b && b.error && b.error(a);
2151
  }
2187
  }
2188
  function h(a, b, c) {
2189
  function e(a) {
2190
+ p("row[" + a + "] disappeared");
2191
  return {
2192
  cellVal: function() {
2193
  return "";
2216
  this.i = a || 0;
2217
  this.length = b.length;
2218
  }
2219
+ function w(a) {
2220
  this.live = a;
2221
  this.rows = [];
2222
  }
2233
  v[a] = l + "-col-" + b;
2234
  F[a] = c || b;
2235
  });
2236
+ for (var N = g(), w = -1, s = v.length, p = g("wg-cols"), n = f.splitx.apply(f, v); ++w < s; ) n[w].header(F[w]),
2237
+ p.appendChild(N.cloneNode(!1)).setAttribute("for", v[w]);
2238
  d.eachRow(function(a, b, c) {
2239
  E[a] = new A(a, b, c);
2240
  u[a] = a;
2241
  });
2242
  this.rows = E;
2243
+ this.cols = p;
2244
  this.ww = null;
2245
  this.root = N = q.body;
2246
  this.head = f;
2249
  h.lock().resize(f, q);
2250
  h.css.push("is-table");
2251
  h.restyle();
2252
+ this.sc ? this._re_sort(s) : d.sort && d.sort(u);
2253
  this.redrawDirty();
2254
  this.render();
2255
  k(N).attr("tabindex", "-1").on("keydown", e(this)).on("mousedown", b(this)).on("scroll", a(this));
2263
  return this;
2264
  };
2265
  s.render = function() {
2266
+ for (var a, b, c = [], e = this.rows || [], d = -1, h, g = this.idxs, v = g.length, l = this.idxr = {}, q = this.r, f = this._r, k = this.root, A = this.cols; ++d < v; ) {
2267
+ 0 === d % 100 && (a = A.cloneNode(!0), b = new w(a), b.h = 2200, b.insert(k), c.push(b));
2268
  h = g[d];
2269
+ l[h] = d;
2270
  a = e[h];
2271
  if (null == a) throw Error("Render error, no data at [" + h + "]");
2272
  a.page = b;
2277
  this.mx = this.mn = null;
2278
  this.redrawDirty();
2279
  this.redraw();
2280
+ null == q ? null != f && (a = e[f]) && a.page && (delete this._r, this.select(f, !0)) : (a = e[q]) && a.page ? this.select(q, !0) : (this.deselect(),
2281
+ this._r = q);
2282
  return this;
2283
  };
2284
  s.resize = function() {
2336
  for (c = h; c !== (h += a) && !(0 <= h && d > h); ) if (b && d) h = 1 === a ? -1 : d,
2337
  b = !1; else return null;
2338
  c = e[h];
2339
+ return null == c || null == this.rows[c] ? (p("Bad next: [" + h + "] does not map to data row"),
2340
  null) : c;
2341
  };
2342
  s.selectNext = function(a, b, c) {
2354
  };
2355
  s.select = function(a, b) {
2356
  var c = this.rows[a], e = c && c.page;
2357
+ if (!e) return this.deselect(!1), p("Row is filtered out"), this;
2358
  this.deselect(!0);
2359
  var d, h = this.w.cells[1];
2360
  e.rendered || (d = e.top(), h.scrollY(d), this.redrawDirty() && this.redraw());
2361
+ if (!c.rendered) return e.rendered || p("Failed to render page"), p("Row [" + c.i + "] not rendered"),
2362
  this;
2363
  e = c.cells();
2364
  k(e).addClass("selected");
2467
  return String(a.textContent || a);
2468
  };
2469
  s = null;
2470
+ s = w.prototype;
2471
  s.size = function() {
2472
  return this.rows.length;
2473
  };
2483
  s.height = function() {
2484
  var a = this.h;
2485
  null == a && (this.h = a = this.rendered ? this.live.firstChild.offsetHeight : this.dead.offsetHight);
2486
+ a || p("row has zero height");
2487
  return a;
2488
  };
2489
  s.render = function(a) {
2521
  };
2522
  s = null;
2523
  return f;
2524
+ }({}, z, x));
2525
+ n.register("$38", function(f, d, D) {
2526
+ function p(a, b) {
2527
+ var c = a.id, e = c && m[c], d = e && e.parent();
2528
  if (!e || !d) return null;
2529
+ var h = d.dir === s, c = h ? "X" : "Y", g = "page" + c, h = h ? w : A, l = h(d.el), c = b["offset" + c], q = d.el, f = q.className;
2530
  null == c && (c = b[g] - h(a));
2531
  c && (l += c);
2532
  q.className = f + " is-resizing";
2543
  function g(a, c) {
2544
  function e() {
2545
  k(D).off("mousemove", d);
2546
+ y && (y.done(), y = null);
2547
  return !0;
2548
  }
2549
  function d(a) {
2550
+ y ? y.move(a) : e();
2551
  return !0;
2552
  }
2553
+ if (y) return !0;
2554
+ y = p(a.target, a);
2555
+ if (!y) return !0;
2556
  k(D).one("mouseup", e).on("mousemove", d);
2557
  return b(a);
2558
  }
2559
  function c(a, b) {
2560
  var c = b.type;
2561
+ "touchmove" === c ? y && y.move(b) : "touchstart" === c ? y = p(a.target, b) : "touchend" === c && y && (y.done(),
2562
+ y = null);
2563
  }
2564
  function b(a) {
2565
  a.stopPropagation();
2586
  this.pos = this.index = 0;
2587
  this.css = [ c || "wg-root", "wg-cell" ];
2588
  this._cn = c;
2589
+ m[b] = this;
2590
  this.clear();
2591
  }
2592
+ var q = n.include("$44", "html.js") || n.include("$2", "html.js", !0), l = n.require("$21", "dom.js"), A = l.top, w = l.left, s = 1, m = {}, B, y = !1;
2593
  f.init = function(a) {
2594
  var b = new h(a);
2595
  b.redraw();
2596
+ n.require("$45", "touch.js").ok(function(b) {
2597
  b.dragger(a, c);
2598
  });
2599
  k(a).on("mousedown", g);
2611
  return this;
2612
  };
2613
  d.indexOf = function(a) {
2614
+ return (a = m[a.id || String(a)]) && a.pid === this.id ? a.index : -1;
2615
  };
2616
  d.on = function() {
2617
  return this.$("on", arguments);
2636
  return this;
2637
  };
2638
  d.parent = function() {
2639
+ return this.pid && m[this.pid];
2640
  };
2641
  d.splitx = function() {
2642
  return this._split(s, arguments);
2649
  for (var c = -1, e, d = b.length, g = 1 / d, q = 0; ++c < d; ) {
2650
  e = l.el();
2651
  this.body.appendChild(e);
2652
+ for (var f = e, k = b[c], A = k, w = 1; m[k]; ) k = A + "-" + ++w;
2653
  f.id = k;
2654
  e = new h(e);
2655
  e.index = c;
2666
  };
2667
  d.destroy = function() {
2668
  this.clear();
2669
+ delete m[this.id];
2670
  var a = this.el;
2671
  a.innerHTML = "";
2672
  this.body = null;
2675
  return this;
2676
  };
2677
  d.exists = function() {
2678
+ return this === m[this.id];
2679
  };
2680
  d.clear = function() {
2681
+ for (var a = this.el, b = this.cells, c = this.field, e = this.body, d = this.nav, h = this.length || 0; 0 !== h--; ) delete m[b[h].destroy().id];
2682
  this.cells = [];
2683
  this.length = 0;
2684
  d && (a.removeChild(d), this.nav = null);
2722
  this.restyle();
2723
  var b = this.el, c = this.body, e = this.field;
2724
  if (c) {
2725
+ var d, h = b.clientWidth || 0, g = b.clientHeight || 0, l = c.offsetTop || 0, g = l > g ? 0 : g - l;
2726
  this._h !== g && (this._h = g, c.style.height = String(g) + "px", d = e);
2727
  this._w !== h && (this._w = h, d = e);
2728
  d && d.redraw();
2730
  c = this.length;
2731
  h = 1;
2732
  g = this.nav;
2733
+ for (l = 2 === this.dir ? "height" : "width"; 0 !== c--; ) e = this.cells[c], g ? d = 1 : (e.fixed && (e.pos = e.fixed / k(b)[l]()),
2734
+ d = h - e.pos, h = e.pos), e.el.style[l] = String(100 * d) + "%", e.redraw(a);
2735
  return this;
2736
  };
2737
  d.contents = function(a, b) {
2751
  c.reload(a, b);
2752
  d !== b && this.restyle();
2753
  } else this.length && this.clear(), d = l.el("textarea"), d.setAttribute("wrap", "virtual"),
2754
+ d.value = a, this.contents(d), c = n.require("$46", "field.js")._new(d)[b ? "enable" : "disable"](),
2755
  e(this, d), this.field = c, this.restyle();
2756
  this.lang || this.locale("en");
2757
  return c;
2758
  };
2759
  d.locale = function(a) {
2760
+ a = n.require("$36", "locale.js").cast(a);
2761
  return this._locale(String(a), a.isRTL());
2762
  };
2763
  d._locale = function(a, b, c) {
2826
  };
2827
  d.tabulate = function(a) {
2828
  var b = this.table;
2829
+ b ? b.clear() : b = n.require("$47", "wgtable.js").create(this);
2830
  b.init(a);
2831
  return this.table = b;
2832
  };
2851
  var b = h[a], c = f[a], d = k(b.el).show();
2852
  c.addClass("active");
2853
  q = a;
2854
+ m.data("idx", a);
2855
  b.fire("wgTabSelect", [ a ]);
2856
  return d;
2857
  }
2858
  var d = this, h = d.cells, g = d.nav, q, f = [];
2859
  g && d.el.removeChild(g);
2860
+ var g = d.nav = d.el.insertBefore(l.el("nav", "wg-tabs"), d.body), m = k(g).on("click", function(a) {
2861
  var c = k(a.target).data("idx");
2862
  if (null == c) return !0;
2863
  if (null != q) {
2869
  d.redraw();
2870
  return b(a);
2871
  });
2872
+ null == c && (c = m.data("idx") || 0);
2873
  d.each(function(b, c) {
2874
+ f[c] = k('<a href="#' + b.id + '"></a>').data("idx", c).text(a[c]).appendTo(m);
2875
  b.pos = 0;
2876
  k(b.el).hide();
2877
  });
2886
  };
2887
  d = null;
2888
  return f;
2889
+ }({}, z, x));
2890
  n.register("$24", function(f, d, D) {
2891
+ function p(a) {
2892
  var b = [];
2893
  a && (a.saved() || b.push("po-unsaved"), a.fuzzy() ? b.push("po-fuzzy") : a.flagged() && b.push("po-flagged"),
2894
  a.translation() || b.push("po-empty"), a.comment() && b.push("po-comment"));
2897
  function g(a, b, c) {
2898
  b = k(a.title(b).parentNode);
2899
  var e = b.find("span.lang");
2900
+ c ? (c = n.require("$36", "locale.js").cast(c), e.length || (e = k("<span></span>").prependTo(b)),
2901
  e.attr("lang", c.lang).attr("class", c.getIcon() || "lang region region-" + (c.region || "zz").toLowerCase())) : (e.remove(),
2902
  c = "en");
2903
  a.locale(c);
2914
  this.dirty = 0;
2915
  }
2916
  n.require("$3", "number.js");
2917
+ var a = "poUpdate", e = "changing", h = "changed", q = 0, l = 1, A = 2, w = 3, s = 4, m = 5, B, y, r = n.require("$35", "string.js").html, z = n.require("$6", "string.js").sprintf;
2918
  f.extend = function(a) {
2919
  return a.prototype = new b();
2920
  };
2921
  f.localise = function(a) {
2922
+ y = a;
2923
  return f;
2924
  };
2925
+ var x = function() {
2926
  var a = D.createElement("p");
2927
  return function(b) {
2928
  a.innerHTML = b.replace("src=", "x=");
2929
  return a.textContent.trim() || b.trim();
2930
  };
2931
+ }(), u = b.prototype = n.require("$37", "abstract.js").init([ "getListColumns", "getListHeadings", "getListEntry" ], [ "editable", "t" ]);
2932
  u.init = function() {
2933
  this.localise();
2934
  this.editable = {
2940
  return this;
2941
  };
2942
  u.localise = function(a) {
2943
+ a || (a = y || n.require("$1", "t.js").init());
2944
  var b = [];
2945
  b[q] = a._x("Source text", "Editor") + ":";
2946
+ b[w] = a._x("%s translation", "Editor") + ":";
2947
  b[s] = a._x("Context", "Editor") + ":";
2948
+ b[m] = a._x("Comments", "Editor") + ":";
2949
  b[l] = a._x("Single", "Editor") + ":";
2950
  b[A] = a._x("Plural", "Editor") + ":";
2951
  b[6] = a._x("Untranslated", "Editor");
2961
  c.redraw(!0, a);
2962
  return !0;
2963
  }
2964
+ var c = n.require("$38", "wingrid.js").init(a);
2965
  k(d).on("resize", b);
2966
  this.redraw = b;
2967
  k(a).on("wgFocus wgBlur", function(a, b) {
2996
  this.targetCell = a;
2997
  };
2998
  u.next = function(a, b, c) {
2999
+ for (var e = this.listTable, d = e.selected(), h = d, g, l = this.po; null != (d = e.next(a, c, d)); ) {
3000
  if (h === d) {
3001
  d = null;
3002
  break;
3003
  }
3004
+ if (b && (g = l.row(d), g.translated(0))) continue;
3005
  break;
3006
  }
3007
  null != d && e.select(d, !0);
3067
  var b = this.po.indexOf(a);
3068
  if ((b = this.listTable.tr(b)) && b.length) {
3069
  var c = b[0].className;
3070
+ a = c.replace(/(?:^| +)po-[a-z]+/g, "") + " " + p(a);
3071
  a !== c && k(b).attr("class", a);
3072
  }
3073
  };
3094
  return null;
3095
  };
3096
  u.reload = function() {
3097
+ var a = this, b, c = a.listCell, e = a.listTable, d = a.po, h = d && d.locale(), g = h && h.isRTL(), l = d && d.length || 0;
3098
  if (!d || !d.row) return c && c.clear().header("Error").contents("Invalid messages list"),
3099
  !1;
3100
  a.targetLocale = h;
3101
+ a.lastSearch && (a.lastSearch = "", a.lastFound = l, a.fire("poFilter", [ "", l ]));
3102
  e && (b = e.thead().distribution());
3103
  a.listTable = e = c.tabulate({
3104
  eachCol: function(b) {
3107
  },
3108
  eachRow: function(b) {
3109
  d.each(function(c, e) {
3110
+ b(e.idx, a.getListEntry(e), p(e));
3111
  });
3112
  },
3113
  sort: a.getSorter()
3114
  });
3115
+ var q, c = a.getListColumns();
3116
+ for (q in c) e.sortable(c[q]);
3117
  b && e.thead().distribute(b);
3118
  e.tbody().$(g ? "addClass" : "removeClass", [ "is-rtl" ]);
3119
  a.fire("poLoad");
3120
+ return !!l;
3121
  };
3122
  u.load = function(a, b) {
3123
  this.po = a;
3149
  return null;
3150
  };
3151
  u.setSrcMeta = function(a, b) {
3152
+ var e = [], d, h = !1, g = this.$smeta, l = this.labels, q = [], f = a.tags(), m = f && f.length;
3153
+ if (d = a.context()) q.push("<span>" + r(l[s]) + "</span>"), q.push("<mark>" + r(d) + "</mark>");
3154
+ if (m && this.getTag) for (q.push("<span>Tagged:</span>"); 0 <= --m; ) (d = this.getTag(f[m])) && q.push('<mark class="tag">' + r(d.mod_name) + "</mark>");
3155
+ q.length && e.push(q.join(" "));
3156
+ if (this.getMono() && (d = a.refs()) && (f = d.split(/\s/), m = f.length)) {
3157
+ for (q = []; 0 <= --m; ) d = f[m], q.push("<code>" + r(d) + "</code>");
3158
+ e.push('<p class="has-icon icon-file">' + q.join(" ") + "</p>");
3159
  }
3160
  (d = a.notes()) && e.push('<p class="has-icon icon-info">' + r(d, !0) + "</p>");
3161
  e.length ? (g || (g = b.find("div.meta"), g.length || (g = k('<div class="meta"></div>').insertAfter(b.header())),
3188
  k = !1;
3189
  r.setSrcMeta(b, a) && (k = !0);
3190
  if (b.plural()) {
3191
+ var k = -1, m = [], w = [], s = a.id + "-", p = b.sourceForms() || e && e.plurals || [ "One", "Other" ], n = p.length;
3192
+ if (2 !== n || "=" === p[0].charAt(0) && "=1" !== p[0]) for (;++k < n; ) m[k] = s + String(k),
3193
+ w[k] = c(p[k]) + ":"; else m = [ s + "-0", s + "-1" ], w = [ L[l], L[A] ];
3194
+ a.splity.apply(a, m);
3195
  a.each(function(a, c) {
3196
+ a.header(w[c]).textarea(b.source(null, c), h).setStrf(C).setMode(y).setInvs(x);
3197
  });
3198
  a.lock();
3199
  h && a.each(function(a, b) {
3200
  f(a, b);
3201
  });
3202
+ } else k && a.redraw(), a.textarea(b.source(), h).setStrf(C).setMode(y).setInvs(x),
3203
  h && f(a, 0);
3204
  }
3205
  function f(c, d) {
3218
  a.ping();
3219
  });
3220
  a.off();
3221
+ var h = e.isKnown() && e.label || "Target", h = z(L[w], h);
3222
  a.titled() !== h && g(a, h, e);
3223
  h = !1;
3224
  !this.sourceCell && r.setSrcMeta(b, a) && (h = !0);
3225
  r.setTrgMeta(b, d, a) && (h = !0);
3226
  r.setStatus(b, d);
3227
  if (1 !== e.nplurals && b.pluralized()) {
3228
+ var q = [], l = [], f = a.id + "-", m = b.targetForms() || e.plurals || [ "One", "Other" ], h = m.length, A = function(a) {
3229
+ var b = m[a];
3230
  l.push(b ? c(b, !0) : "Form " + a);
3231
  q.push(f + String(a));
3232
  };
3234
  a.splitx.apply(a, q);
3235
  a.each(function(a, c) {
3236
  var e = M && !b.disabled(c);
3237
+ a.textarea(b.translation(c), e).setStrf(C).setMode(y).setInvs(x);
3238
+ M && p(a, c);
3239
  });
3240
  a.navigize(l, d || null).on("wgTabSelect", function(c, e) {
3241
  var d = M && c.cell.editable();
3244
  r.setStatus(b, e);
3245
  r.fire("poTab", [ e ]);
3246
  });
3247
+ } else h && a.redraw(), a.textarea(b.translation(), M && !b.disabled(0)).setStrf(C).setMode(y).setInvs(x),
3248
+ M && p(a, 0);
3249
  }
3250
+ function p(c, d) {
3251
  c.on(e, function(a, c, e) {
3252
  b.translate(c, d);
3253
  0 === d && r.updateListCell(b, "target");
3263
  c.off();
3264
  var d = L[s];
3265
  c.titled() !== d && (g(c, d), r.setStatus(null));
3266
+ c.textarea(b.context(), !0).setMode(y).setInvs(x);
3267
  X && c.on(e, function(a, c) {
3268
  b.context(c);
3269
  r.updateListCell(b, "source");
3275
  });
3276
  }
3277
  function u(a) {
3278
+ var c = L[m];
3279
  a.titled() !== c && g(a, c);
3280
  a.off().on(e, function(a, c) {
3281
  b.comment(c);
3283
  r.unsave(b, O);
3284
  }).textarea(b.comment(), !0);
3285
  }
3286
+ var r = this, y = r.mode, D = b.isHTML(), x = r.inv || !1, E = this.fmt || null, C = b.format() || null, I = b.is(r.active), O = 0, T = r.sourceCell, S = r.targetCell, U = r.contextCell, V = r.commentCell, M = r.editable.target, J = r.editable.source, X = r.editable.context, P = B, Y = r.sourceLocale, W = r.targetLocale, L = r.labels;
3287
+ r.html !== D && (r.html = D, "code" !== r.mode && (y = D ? "html" : "", r.setMode(y)));
3288
  r.active = b;
3289
  T && d(T, Y);
3290
  U && n(U);
3325
  (e = this.listTable.row(e)) && e.rendered && e.update(c);
3326
  };
3327
  u.cellText = function(a) {
3328
+ return (a = -1 !== a.indexOf("<") || -1 !== a.indexOf("&") ? x(a) : a.trim()) || " ";
3329
  };
3330
  u.fuzzy = function(a, b, c) {
3331
  b = b || this.active;
3405
  };
3406
  u = null;
3407
  return f;
3408
+ }({}, z, x));
3409
  n.register("$13", function(f, d, D) {
3410
+ function p() {
3411
  this.init()._validate();
3412
  this.sourceLocale = {
3413
  lang: "en",
3434
  }
3435
  d = n.require("$24", "base.js");
3436
  f.init = function(a) {
3437
+ var b = new p();
3438
  a = b.setRootCell(a);
3439
  var c = a.splity("po-list", "po-edit"), d = c[0], g = c[1], c = g.splitx("po-trans", "po-comment"), f = c[0], k = c[1].header("Loading.."), c = f.splity("po-source", "po-target"), f = c[0].header("Loading.."), c = c[1].header("Loading..");
3440
  a.distribute([ .34 ]);
3446
  b.editable.source = !1;
3447
  return b;
3448
  };
3449
+ d = p.prototype = d.extend(p);
3450
  d.getListHeadings = function() {
3451
  var a = this.t || {
3452
  _x: function(a) {
3535
  };
3536
  };
3537
  return f;
3538
+ }({}, z, x));
3539
  n.register("$14", function(f, d, n) {
3540
+ var p = {
3541
  copy: 66,
3542
  clear: 75,
3543
  save: 83,
3595
  k(a || d).on("keydown", e);
3596
  return {
3597
  add: function(a, b) {
3598
+ c[p[a]] = b;
3599
  return this;
3600
  },
3601
  enable: function() {
3602
  var a, b;
3603
+ for (b in arguments) a = p[arguments[b]], h[a] = !0;
3604
  return this;
3605
  },
3606
  disable: function() {
3610
  };
3611
  };
3612
  return f;
3613
+ }({}, z, x));
3614
  n.register("$25", function(f, d, k) {
3615
+ function p() {
3616
  this.reIndex([]);
3617
  }
3618
  f.init = function() {
3619
+ return new p();
3620
  };
3621
+ d = p.prototype;
3622
  d.reIndex = function(d) {
3623
  for (var c = {}, b = -1, a = d.length; ++b < a; ) c[d[b]] = b;
3624
  this.keys = d;
3679
  };
3680
  d = null;
3681
  return f;
3682
+ }({}, z, x));
3683
  n.register("$26", function(f, d, k) {
3684
+ function p(d, c) {
3685
  var b = RegExp("^.{0," + (d - 1) + "}[" + c + "]"), a = RegExp("^[^" + c + "]+");
3686
  return function(c, h) {
3687
  for (var f = c.length, l; f > d; ) {
3709
  "\b": "\\b"
3710
  };
3711
  if (null == d || isNaN(d = Number(d))) d = 79;
3712
+ 0 < d && (b = p(d - 3, " "), a = p(d - 2, "-– \\.,:;\\?!\\)\\]\\}\\>"));
3713
  return {
3714
  pair: function(b, h) {
3715
  if (!h) return b + ' ""';
3720
  return "\\n\n";
3721
  });
3722
  if (!(l || d && d < h.length + b.length + 3)) return b + ' "' + h + '"';
3723
+ var k = [ b + ' "' ], p = h.split("\n");
3724
+ if (a) for (var n = -1, r = p.length; ++n < r; ) a(p[n], k); else k = k.concat(p);
3725
  return k.join('"\n"') + '"';
3726
  },
3727
  prefix: function(a, b) {
3736
  };
3737
  };
3738
  return f;
3739
+ }({}, z, x));
3740
+ n.register("$39", function(f, d, k) {
3741
+ function p() {
3742
  this.length = 0;
3743
  }
3744
  f.init = function() {
3745
+ return new p();
3746
  };
3747
+ d = p.prototype;
3748
  d.push = function(d) {
3749
  this[this.length++] = d;
3750
  return this;
3758
  return this;
3759
  };
3760
  return f;
3761
+ }({}, z, x));
3762
  n.register("$27", function(f, d, k) {
3763
+ function p() {}
3764
  f.extend = function(d) {
3765
+ return d.prototype = new p();
3766
  };
3767
+ d = p.prototype = n.require("$37", "abstract.js").init([ "add", "load" ]);
3768
  d.row = function(d) {
3769
  return this.rows[d];
3770
  };
3782
  return d;
3783
  };
3784
  d.locale = function(d) {
3785
+ null == d ? d = this.loc : this.loc = d = n.require("$36", "locale.js").cast(d);
3786
  return d;
3787
  };
3788
  d.each = function(d) {
3820
  return this;
3821
  };
3822
  d["export"] = function() {
3823
+ for (var d = -1, c = this.rows, b = c.length, a = n.require("$39", "list.js").init(); ++d < b; ) a.push(c[d]);
3824
  return a;
3825
  };
3826
  d = null;
3827
  return f;
3828
+ }({}, z, x));
3829
  n.register("$28", function(f, d, k) {
3830
+ function p(c, b, a) {
3831
  if (null == a) return c[b] || "";
3832
  c[b] = a || "";
3833
  return c;
3922
  return !0;
3923
  };
3924
  d.comment = function(c) {
3925
+ return p(this, "cmt", c);
3926
  };
3927
  d.notes = function(c) {
3928
+ return p(this, "xcmt", c);
3929
  };
3930
  d.refs = function(c) {
3931
+ return p(this, "rf", c);
3932
  };
3933
  d.format = function(c) {
3934
+ return p(this, "fmt", c);
3935
  };
3936
  d.context = function(c) {
3937
+ return p(this, "ctx", c);
3938
  };
3939
  d.tags = function() {
3940
  return this.tg;
3988
  };
3989
  d = null;
3990
  return f;
3991
+ }({}, z, x));
3992
  n.register("$15", function(f, d, k) {
3993
+ function p(a) {
3994
  return {
3995
  "Project-Id-Version": "PACKAGE VERSION",
3996
  "Report-Msgid-Bugs-To": "",
4020
  function a(a) {
4021
  this.locale(a);
4022
  this.clear();
4023
+ this.head = p(this.now());
4024
  }
4025
  function e(a, b) {
4026
  this.src = [ a || "" ];
4050
  return this;
4051
  };
4052
  k.headers = function(a) {
4053
+ var b, c = this.now(), d = this.head || (this.head = p(c));
4054
  if (null != a) {
4055
  for (b in a) d[b] = a[b];
4056
  return this;
4079
  return a;
4080
  };
4081
  k.load = function(a) {
4082
+ for (var b = -1, d, f, g, k, m, p, n = (g = this.locale()) && g.nplurals || 2, r = []; ++b < a.length; ) d = a[b],
4083
+ null == d.parent ? (f = d.source || d.id, g = d.target || "", k = d.context, f || k ? (m = new e(f, g),
4084
+ m._id = d._id, k && m.context(k), d.flag && m.flag(d.flag, 0), d.comment && m.comment(d.comment),
4085
+ d.notes && m.notes(d.notes), d.refs && m.refs(d.refs), m.format(d.format), d.message = m,
4086
+ this.add(m), d.prev && d.prev[0] && (m.prev(d.prev[0].source, d.prev[0].context),
4087
+ d.prev[1] && m._src.push(d.prev[1].source || ""))) : 0 === b && "object" === typeof g && (this.head = g,
4088
  this.headcmt = d.comment)) : r.push(d);
4089
  for (b = -1; ++b < r.length; ) try {
4090
  d = r[b];
4091
  f = d.source || d.id;
4092
+ m = a[d.parent] && a[d.parent].message;
4093
+ if (!m) throw Error("parent missing for plural " + f);
4094
+ p = d.plural;
4095
+ 1 === p && m.plural(f);
4096
+ p >= n || (d.flag && m.flag(d.flag, p), m.translate(d.target || "", p), d.format && !m.format() && m.format(d.format));
4097
+ } catch (x) {
4098
+ c(x);
4099
  }
4100
  return this;
4101
  };
4104
  return this;
4105
  };
4106
  k.toString = function() {
4107
+ var a, c = this.locale(), d = [], f = [], g = this.headers(), k = !c, m = c && c.nplurals || 2, p = this.fmtr || b();
4108
  g[c ? "PO-Revision-Date" : "POT-Creation-Date"] = this.now();
4109
  for (a in g) f.push(a + ": " + g[a]);
4110
  f = new e("", f.join("\n"));
4113
  d.push(f.toString());
4114
  d.push("");
4115
  this.rows.each(function(a, b) {
4116
+ a && (d.push(b.cat(p, k, m)), d.push(""));
4117
  });
4118
  return d.join("\n");
4119
  };
4165
  };
4166
  k = k = null;
4167
  return f;
4168
+ }({}, z, x));
4169
  n.register("$17", function(f, d, n) {
4170
  f.init = function(d, f) {
4171
  function c() {
4208
  };
4209
  };
4210
  return f;
4211
+ }({}, z, x));
4212
  n.register("$30", function(f, d, k) {
4213
+ function p(d) {
4214
  this.api = d;
4215
  this.chars = 0;
4216
  }
4217
  f.create = function(d) {
4218
+ return new p(d);
4219
  };
4220
+ d = p.prototype;
4221
  d.init = function(d, c) {
4222
  function b(a) {
4223
  var b = {
4226
  sources: []
4227
  };
4228
  B.push(b);
4229
+ return y[a.html ? 1 : 0] = b;
4230
  }
4231
  function a(a, d) {
4232
  var g = a.source(null, d);
4233
  if (g && (a.untranslated(d) || c)) {
4234
+ var u = m[g];
4235
  if (u) u.push(a); else {
4236
+ var u = g.length, v = e.isHtml(g), v = y[v ? 1 : 0], B = v.sources;
4237
  if (s && u > s) l++; else {
4238
+ if (v.length + u > n || B.length === p) v = b(v), B = v.sources;
4239
  B.push(g);
4240
+ m[g] = [ a ];
4241
  v.length += u;
4242
  f += u;
4243
  k += 1;
4245
  }
4246
  }
4247
  }
4248
+ var e = this.api, f = 0, k = 0, l = 0, p = 50, n = 1e4, s = e.maxChr(), m = {}, B = [], y = [];
4249
  s && (n = Math.min(n, s));
4250
  b({
4251
  html: !1
4257
  a(c, 0);
4258
  a(c, 1);
4259
  });
4260
+ delete y;
4261
+ this.map = m;
4262
  this.chars = f;
4263
  this.length = k;
4264
  this.batches = B;
4273
  function d(a, b) {
4274
  function e(c, d, h) {
4275
  b !== h && (a === d || 1 < c && f.source(null, 1) === a) && (f.translate(b, c),
4276
+ m++, r++);
4277
+ return m;
4278
  }
4279
  if (!c()) return !1;
4280
  if (!b) return !0;
4281
+ var f, h = n[a] || [], g = h.length, l = -1, m;
4282
+ for (B++; ++l < g; ) if (f = h[l]) m = 0, f.each(e), m && k("each", [ f ]);
4283
  return !0;
4284
  }
4285
  function c() {
4286
+ return "abort" === l.state ? (p && (p.abort(), f()), !1) : !0;
4287
  }
4288
  function b() {
4289
  var b = s.shift(), c;
4290
+ b ? (c = b.sources) && c.length ? p.batch(c, m, b.html, d).fail(a).always(e) : e() : f();
4291
  }
4292
  function a() {
4293
  l.abort();
4294
  f();
4295
  }
4296
  function e() {
4297
+ y++;
4298
+ k("prog", [ y, z ]);
4299
  c() && b();
4300
  }
4301
  function f() {
4302
+ p = s = null;
4303
  k("done");
4304
  }
4305
  function k(a, b) {
4306
  for (var c = u[a] || [], d = c.length; 0 <= --d; ) c[d].apply(null, b);
4307
  }
4308
+ var l = this, p = l.api, n = l.map, s = l.batches || [], m = l.locale, B = 0, y = 0, r = 0, x = l.length, z = s.length, u = {
4309
  done: [],
4310
  each: [],
4311
  prog: []
4328
  stat: function() {
4329
  return {
4330
  todo: function() {
4331
+ return Math.max(x - B, 0);
4332
  },
4333
  did: function() {
4334
  return B;
4338
  };
4339
  };
4340
  return f;
4341
+ }({}, z, x));
4342
+ n.register("$40", {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4343
  zh: [ "zh", "zh-CN", "zh-TW" ],
4344
  he: [ "iw" ],
4345
  jv: [ "jw" ]
4346
  });
4347
+ n.register("$31", function(f, d, k) {
4348
+ function p() {}
4349
  f.create = function(d) {
4350
+ d = p.prototype = new d();
4351
  d.toString = function() {
4352
  return "Google Translate";
4353
  };
4370
  }
4371
  var g = this, k = this.getSrc();
4372
  a = a ? "html" : "text";
4373
+ var p = g.mapLang(b, n.require("$40", "google.json"));
4374
  return g._call({
4375
+ url: "https://translation.googleapis.com/language/translate/v2?source=" + k + "&target=" + p + "&format=" + a,
4376
  method: "POST",
4377
  traditional: !0,
4378
  data: {
4386
  f([]);
4387
  });
4388
  };
4389
+ return new p();
4390
  };
4391
  return f;
4392
+ }({}, z, x));
4393
+ n.register("$41", {
4394
  nn: [ "no" ],
4395
  pt: [ "pt", "pt-pt" ],
4396
  sr: [ "sr-Cyrl", "sr-Latn" ],
4402
  zh_SG: [ "zh-Hans" ],
4403
  zh_TW: [ "zh-Hant" ]
4404
  });
4405
+ n.register("$32", function(f, d, k) {
4406
+ function p() {}
4407
  f.create = function(d) {
4408
+ d = p.prototype = new d();
4409
  d.toString = function() {
4410
  return "Microsoft Translator text API";
4411
  };
4423
  };
4424
  d.batch = function(c, b, a, d) {
4425
  function f(a) {
4426
+ for (var h = -1, g; ++h < w && (g = a[h] || {}, g = g.translations || [], g = g[0] || {},
4427
  !1 !== d(c[h], g.text || "", b)); ) ;
4428
  }
4429
+ var g = this, k = [], p = g.getSrc(), w = c.length, s = -1;
4430
  a = a ? "html" : "plain";
4431
+ for (var m = g.mapLang(b, n.require("$41", "ms.json")); ++s < w; ) k.push({
4432
  text: c[s]
4433
  });
4434
  return g._call({
4435
+ url: "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=" + p + "&to=" + m + "&textType=" + a,
4436
  method: "POST",
4437
  data: JSON.stringify(k),
4438
  headers: {
4446
  f([]);
4447
  });
4448
  };
4449
+ return new p();
4450
  };
4451
  return f;
4452
+ }({}, z, x));
4453
+ n.register("$42", {
4454
  pt: [ "pt-PT", "pt-BR" ]
4455
  });
4456
+ n.register("$33", function(f, d, k) {
4457
+ function p() {}
4458
  f.create = function(d) {
4459
+ d = p.prototype = new d();
4460
  d.toString = function() {
4461
  return "DeepL Translator";
4462
  };
4475
  }
4476
  var g = this;
4477
  a = this.getSrc();
4478
+ var k = g.param("url") || "https://api.deepl.com", p = g.mapLang(b, n.require("$42", "deepl.json")), w = b.tone, s = "default";
4479
+ null == w && (w = String(b.variant || "").toLowerCase());
4480
+ "formal" === w ? s = "more" : "informal" === w && (s = "less");
4481
  return g._call({
4482
  url: g.fixURL(k + "/v2/translate"),
4483
  method: "POST",
4484
  traditional: !0,
4485
  data: {
4486
  source_lang: a.toUpperCase(),
4487
+ target_lang: p.toUpperCase(),
4488
  formality: s,
4489
  preserve_formatting: "1",
4490
  auth_key: g.key(),
4497
  f([]);
4498
  });
4499
  };
4500
+ return new p();
4501
  };
4502
  return f;
4503
+ }({}, z, x));
4504
+ n.register("$43", {
4505
  zh: [ "zh", "zh-CN", "zh-TW" ],
4506
  pt: [ "pt", "pt-PT", "pt-BR" ]
4507
  });
4508
+ n.register("$34", function(f, d, k) {
4509
+ function p() {}
4510
  f.create = function(d) {
4511
+ d = p.prototype = new d();
4512
  d.getUrl = function() {
4513
  return "https://lecto.ai/?ref=loco";
4514
  };
4530
  }
4531
  var g = this;
4532
  a = this.getSrc();
4533
+ var k = g.param("url") || "https://api.lecto.ai", p = g.mapLang(b, n.require("$43", "lecto.json"));
4534
  return g._call({
4535
  url: g.fixURL(k + "/v1/translate/text"),
4536
  method: "POST",
4537
  data: JSON.stringify({
4538
+ to: [ p ],
4539
  from: a,
4540
  texts: c
4541
  }),
4550
  f([]);
4551
  });
4552
  };
4553
+ return new p();
4554
  };
4555
  return f;
4556
+ }({}, z, x));
4557
+ n.register("$18", function(f, d, x) {
4558
+ function p() {
4559
  this.inf = {};
4560
  }
4561
  function g() {
4562
+ var a = x.createElement("p"), b = /&(#\d+|#x[0-9a-f]|[a-z]+);/i, c = /<[a-z]+\s/i, d, f;
4563
  return {
4564
  sniff: function(g) {
4565
  if (g === d) return f;
4569
  }
4570
  };
4571
  }
4572
+ var c = p.prototype;
4573
  c.init = function(a) {
4574
  this.inf = a || {};
4575
  };
4656
  function g(c) {
4657
  for (var d = a.length, h = -1; ++h < d && !1 !== f(a[h], c[h], b); ) ;
4658
  }
4659
+ var p = d.loco.ajax;
4660
  c = {
4661
  hook: this.getId(),
4662
  type: c ? "html" : "text",
4665
  sources: a
4666
  };
4667
  var n = k.Deferred();
4668
+ this.abortable(p.post("apis", c, function(a) {
4669
  g(a && a.targets || []);
4670
  n.resolve();
4671
  }, function() {
4677
  f.create = function(a) {
4678
  var b;
4679
  b = a.id;
4680
+ b = "google" === b ? n.require("$31", "google.js").create(p) : "microsoft" === b ? n.require("$32", "ms.js").create(p) : "deepl" === b ? n.require("$33", "deepl.js").create(p) : "lecto" === b ? n.require("$34", "lecto.js").create(p) : new p();
4681
  b.init(a);
4682
  return b;
4683
  };
4687
  };
4688
  var b;
4689
  return f;
4690
+ }({}, z, x));
4691
  n.register("$19", function(f, d, n) {
4692
  f.init = function(f) {
4693
  function g() {
4703
  return H;
4704
  }
4705
  function c() {
4706
+ R && (b(k(y)), R = !1);
4707
  if (E && J) {
4708
  var a = J, c = k(Q);
4709
  c.find("span.loco-msg").text(a);
4717
  }
4718
  function a() {
4719
  if (E) return H && H.dialog("close"), c(), k(f).find('button[type="submit"]').attr("disabled", !1),
4720
+ k(d).triggerHandler("resize"), z && z(!0), !0;
4721
+ v && H ? (R || (k(y).removeClass("jshide").hide().fadeIn(500), R = !0), K && (b(k(Q)),
4722
  K = !1)) : c();
4723
  k(f).find('input[type="submit"]').attr("disabled", !0);
4724
+ z && z(!1);
4725
  return !1;
4726
  }
4727
  function e(a) {
4728
+ var b, c, d = m || {};
4729
  for (b in d) d.hasOwnProperty(b) && (c = d[b], a[b] ? a[b].value = c : k('<input type="hidden" />').attr("name", b).appendTo(a).val(c));
4730
  }
4731
  function h(a) {
4745
  H.dialog("open").find('input[name="connection_type"]').change();
4746
  return !1;
4747
  }
4748
+ function x(b) {
4749
  E = b.authed;
4750
  r = b.method;
4751
+ k(y).find("span.loco-msg").text(b.message || "Something went wrong.");
4752
  J = b.warning || "";
4753
  b.notice && u.notices.info(b.notice);
4754
+ if (E) "direct" !== r && (m = b.creds, e(f), C && b.success && u.notices.success(b.success)),
4755
  a(); else if (b.reason) u.notices.info(b.reason); else if (b = b.prompt) {
4756
  var c = g();
4757
  c.html(b).find("form").on("submit", h);
4762
  k(d).triggerHandler("resize");
4763
  } else u.notices.error("Server didn't return credentials, nor a prompt for credentials");
4764
  }
4765
+ function w() {
4766
  a();
4767
  }
4768
  function s(a) {
4769
  C = !1;
4770
+ u.ajax.setNonce("fsConnect", N).post("fsConnect", a, x, w);
4771
  return a;
4772
  }
4773
+ var m, z, y = f, r = null, C = !1, E = !1, u = d.loco, v = f.path.value, F = f.auth.value, N = f["loco-nonce"].value, I = k(y).find("button.button-primary"), Q = n.getElementById(y.id + "-warn"), R = !1, K = !1, J = "", H;
4774
  u.notices.convert(Q).stick();
4775
+ f.connection_type ? (m = {}, m.connection_type = f.connection_type.value, E = !0) : v && F && s({
4776
  path: v,
4777
  auth: F
4778
  });
4780
  return {
4781
  applyCreds: function(a) {
4782
  if (a.nodeType) e(a); else {
4783
+ var b, c = m || {};
4784
  for (b in c) c.hasOwnProperty(b) && (a[b] = c[b]);
4785
  }
4786
  return this;
4798
  return this;
4799
  },
4800
  listen: function(a) {
4801
+ z = a;
4802
  E && a(!0);
4803
  return this;
4804
  },
4808
  };
4809
  };
4810
  return f;
4811
+ }({}, z, x));
4812
+ n.register("$20", function(f, d, x) {
4813
+ function p(d, f, k, l) {
4814
  f = "n" === k ? c(f) : b(f);
4815
  l && (f = a(f));
4816
  return g([].sort, [ f ])(d);
4840
  f.init = function(a) {
4841
  function b(a) {
4842
  var c = -1, d = a.length;
4843
+ for (k("tr", y).remove(); ++c < d; ) y.appendChild(a[c].$);
4844
  }
4845
  function c(a) {
4846
+ s = a ? z.find(a, d) : d.slice(0);
4847
+ x && (a = f[x], s = p(s, x, a.type, a.desc));
4848
  b(s);
4849
  }
4850
+ var d = [], f = [], g = 0, s, m, x, y = a.getElementsByTagName("tbody")[0], r = a.getElementsByTagName("thead")[0], z = n.require("$10", "fulltext.js").init();
4851
+ r && y && (k("th", r).each(function(a, c) {
4852
  var e = c.getAttribute("data-sort-type");
4853
  e && (a = g, k(c).addClass("loco-sort").on("click", function(c) {
4854
  c.preventDefault();
4855
  c = a;
4856
  var e = f[c], g = e.type, n = !(e.desc = !e.desc);
4857
+ s = p(s || d.slice(0), c, g, n);
4858
  b(s);
4859
+ m && m.removeClass("loco-desc loco-asc");
4860
+ m = k(e.$).addClass(n ? "loco-desc" : "loco-asc").removeClass(n ? "loco-asc" : "loco-desc");
4861
+ x = c;
4862
  return !1;
4863
  }), f[g] = {
4864
  $: c,
4865
  type: e
4866
  });
4867
  c.hasAttribute("colspan") ? g += Number(c.getAttribute("colspan")) : g++;
4868
+ }), k("tr", y).each(function(a, b) {
4869
  var c, e, g, h = [], k = {
4870
  _: a,
4871
  $: b
4881
  k[e] = g;
4882
  }
4883
  d[a] = k;
4884
+ z.index(a, h);
4885
  }), a = k('form.loco-filter input[type="text"]', a.parentNode), a.length && (a = a[0],
4886
  r = k(a.form), 1 < d.length ? n.require("$11", "LocoTextListener.js").listen(a, c) : r.hide(),
4887
  r.on("submit", function(a) {
4890
  })));
4891
  };
4892
  return f;
4893
+ }({}, z, x));
4894
+ var C = z.loco || {}, I = C.conf || {
4895
  $v: [ 0, 0 ]
4896
  };
4897
+ z = n.require("$1", "t.js").init();
4898
+ x = I.wplang;
4899
  C.version = function(f) {
4900
  return I.$v[f || 0];
4901
  };
4903
  n.require("$3", "number.js");
4904
  n.require("$4", "array.js");
4905
  n.require("$5", "json.js");
4906
+ C.l10n = z;
4907
+ z.load(I.wpl10n);
4908
+ x && z.pluraleq(x.pluraleq);
4909
  C.string = n.require("$6", "string.js");
4910
+ C.notices = n.require("$7", "notices.js").init(z);
4911
+ C.ajax = n.require("$8", "ajax.js").init(I).localise(z);
4912
  C.locale = n.require("$9", "wplocale.js");
4913
  C.fulltext = n.require("$10", "fulltext.js");
4914
  C.watchtext = n.require("$11", "LocoTextListener.js").listen;
4926
  n.require("$20", "tables.js").init(d);
4927
  });
4928
  C.validate = function(f) {
4929
+ return "2.6.0" !== (/^\d+\.\d+\.\d+/.exec(f && f[0] || "") && RegExp.lastMatch) ? (C.notices.warn("admin.js is the wrong version (2.6.0). Please empty all relevant caches and reload this page."),
4930
  !1) : !0;
4931
  };
4932
  })(window, document, window.jQuery);
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Loco Translate ===
2
  Contributors: timwhitlock
3
  Tags: translation, translators, localization, localisation, l10n, i18n, Gettext, PO, MO, productivity, multilingual, internationalization
4
- Requires at least: 4.1
5
- Requires PHP: 5.2.4
6
- Tested up to: 5.9
7
- Stable tag: 2.5.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -100,6 +100,14 @@ We don't collect your data or snoop on you. See the [plugin privacy notice](http
100
 
101
  == Changelog ==
102
 
 
 
 
 
 
 
 
 
103
  = 2.5.8 =
104
  * Compatible with PHP 8.1
105
  * Bumped WordPress version to 5.9
@@ -449,7 +457,7 @@ We don't collect your data or snoop on you. See the [plugin privacy notice](http
449
 
450
  == Upgrade Notice ==
451
 
452
- = 2.5.8 =
453
  * Various improvements and bug fixes
454
 
455
 
1
  === Loco Translate ===
2
  Contributors: timwhitlock
3
  Tags: translation, translators, localization, localisation, l10n, i18n, Gettext, PO, MO, productivity, multilingual, internationalization
4
+ Requires at least: 5.2
5
+ Requires PHP: 5.6.20
6
+ Tested up to: 5.9.1
7
+ Stable tag: 2.6.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
100
 
101
  == Changelog ==
102
 
103
+ = 2.6.0 =
104
+ * Dropped support for WordPress < 5.2
105
+ * Code upgrades for >= PHP 5.6.20
106
+ * Bumped WordPress version to 5.9.1
107
+ * Removed Yandex API integration
108
+ * Added loco_compile_script_reference filter
109
+ * Plural-Forms retained when copying PO to same language
110
+
111
  = 2.5.8 =
112
  * Compatible with PHP 8.1
113
  * Bumped WordPress version to 5.9
457
 
458
  == Upgrade Notice ==
459
 
460
+ = 2.6.0 =
461
  * Various improvements and bug fixes
462
 
463
 
src/Locale.php CHANGED
@@ -116,7 +116,7 @@ class Loco_Locale implements JsonSerializable {
116
  */
117
  public function setSubtags( array $tag ){
118
  $this->valid = false;
119
- $default = array( 'lang' => '', 'region' => '', 'variant' => '' );
120
  // disallow setting of unsupported tags
121
  if( $bad = array_diff_key($tag, $default) ){
122
  throw new Loco_error_LocaleException('Unsupported subtags: '.implode(',',$bad) );
@@ -222,7 +222,7 @@ class Loco_Locale implements JsonSerializable {
222
  public function getIcon(){
223
  $icon = $this->icon;
224
  if( is_null($icon) ){
225
- $tag = array();
226
  if( ! $this->tag['lang'] ){
227
  $tag[] = 'lang lang-zxx';
228
  }
@@ -394,13 +394,13 @@ class Loco_Locale implements JsonSerializable {
394
  // handle languages with no plural forms, where n is always 0
395
  if( ! isset($raw[1][1]) ){
396
  // Translators: Plural category for languages that have no plurals
397
- $raw[1] = array( _x('All forms','Plural category','loco-translate') );
398
  $raw[0] = '0';
399
  }
400
  // else translate all implemented plural forms
401
  // for meaning of categories, see http://cldr.unicode.org/index/cldr-spec/plural-rules
402
  else {
403
- $forms = array(
404
  // Translators: Plural category for zero quantity
405
  'zero' => _x('Zero','Plural category','loco-translate'),
406
  // Translators: Plural category for singular quantity
@@ -413,7 +413,7 @@ class Loco_Locale implements JsonSerializable {
413
  'many' => _x('Many','Plural category','loco-translate'),
414
  // Translators: General plural category not covered by other forms
415
  'other' => _x('Other','Plural category','loco-translate'),
416
- );
417
  foreach( $raw[1] as $k => $v ){
418
  if( isset($forms[$v]) ){
419
  $raw[1][$k] = $forms[$v];
@@ -438,7 +438,7 @@ class Loco_Locale implements JsonSerializable {
438
  /**
439
  * Apply PO style Plural-Forms header.
440
  * @param string e.g. "nplurals=2; plural=n != 1;"
441
- * @return Loco_Locale
442
  */
443
  public function setPluralFormsHeader( $str ){
444
  if( ! preg_match('/^nplurals=(\\d);\s*plural=([ +\\-\\/*%!=<>|&?:()n0-9]+);?$/', $str, $match ) ){
@@ -459,7 +459,7 @@ class Loco_Locale implements JsonSerializable {
459
  $forms[] = $name;
460
  }
461
  $forms[] = 'other';
462
- $this->setPlurals( array($exprn,$forms) );
463
  }
464
  }
465
  return $this;
116
  */
117
  public function setSubtags( array $tag ){
118
  $this->valid = false;
119
+ $default = [ 'lang' => '', 'region' => '', 'variant' => '' ];
120
  // disallow setting of unsupported tags
121
  if( $bad = array_diff_key($tag, $default) ){
122
  throw new Loco_error_LocaleException('Unsupported subtags: '.implode(',',$bad) );
222
  public function getIcon(){
223
  $icon = $this->icon;
224
  if( is_null($icon) ){
225
+ $tag = [];
226
  if( ! $this->tag['lang'] ){
227
  $tag[] = 'lang lang-zxx';
228
  }
394
  // handle languages with no plural forms, where n is always 0
395
  if( ! isset($raw[1][1]) ){
396
  // Translators: Plural category for languages that have no plurals
397
+ $raw[1] = [ _x('All forms','Plural category','loco-translate') ];
398
  $raw[0] = '0';
399
  }
400
  // else translate all implemented plural forms
401
  // for meaning of categories, see http://cldr.unicode.org/index/cldr-spec/plural-rules
402
  else {
403
+ $forms = [
404
  // Translators: Plural category for zero quantity
405
  'zero' => _x('Zero','Plural category','loco-translate'),
406
  // Translators: Plural category for singular quantity
413
  'many' => _x('Many','Plural category','loco-translate'),
414
  // Translators: General plural category not covered by other forms
415
  'other' => _x('Other','Plural category','loco-translate'),
416
+ ];
417
  foreach( $raw[1] as $k => $v ){
418
  if( isset($forms[$v]) ){
419
  $raw[1][$k] = $forms[$v];
438
  /**
439
  * Apply PO style Plural-Forms header.
440
  * @param string e.g. "nplurals=2; plural=n != 1;"
441
+ * @return self
442
  */
443
  public function setPluralFormsHeader( $str ){
444
  if( ! preg_match('/^nplurals=(\\d);\s*plural=([ +\\-\\/*%!=<>|&?:()n0-9]+);?$/', $str, $match ) ){
459
  $forms[] = $name;
460
  }
461
  $forms[] = 'other';
462
+ $this->setPlurals( [$exprn,$forms] );
463
  }
464
  }
465
  return $this;
src/admin/DebugController.php CHANGED
@@ -19,27 +19,27 @@ class Loco_admin_DebugController extends Loco_mvc_AdminController {
19
  public function render(){
20
 
21
  // debug package listener
22
- $themes = array();
23
  /* @var $bundle Loco_package_Bundle */
24
  foreach( Loco_package_Listener::singleton()->getThemes() as $bundle ){
25
- $themes[] = array (
26
  'id' => $bundle->getId(),
27
  'name' => $bundle->getName(),
28
  'default' => $bundle->getDefaultProject()->getSlug(),
29
  'count' => count($bundle),
30
- );
31
  }
32
  $this->set('themes', $themes );
33
 
34
- $plugins = array();
35
  /* @var $bundle Loco_package_Bundle */
36
  foreach( Loco_package_Listener::singleton()->getPlugins() as $bundle ){
37
- $plugins[] = array (
38
  'id' => $bundle->getId(),
39
  'name' => $bundle->getName(),
40
  'default' => $bundle->getDefaultProject()->getSlug(),
41
  'count' => count($bundle),
42
- );
43
  }
44
 
45
 
19
  public function render(){
20
 
21
  // debug package listener
22
+ $themes = [];
23
  /* @var $bundle Loco_package_Bundle */
24
  foreach( Loco_package_Listener::singleton()->getThemes() as $bundle ){
25
+ $themes[] = [
26
  'id' => $bundle->getId(),
27
  'name' => $bundle->getName(),
28
  'default' => $bundle->getDefaultProject()->getSlug(),
29
  'count' => count($bundle),
30
+ ];
31
  }
32
  $this->set('themes', $themes );
33
 
34
+ $plugins = [];
35
  /* @var $bundle Loco_package_Bundle */
36
  foreach( Loco_package_Listener::singleton()->getPlugins() as $bundle ){
37
+ $plugins[] = [
38
  'id' => $bundle->getId(),
39
  'name' => $bundle->getName(),
40
  'default' => $bundle->getDefaultProject()->getSlug(),
41
  'count' => count($bundle),
42
+ ];
43
  }
44
 
45
 
src/admin/ErrorController.php CHANGED
@@ -19,7 +19,7 @@ class Loco_admin_ErrorController extends Loco_mvc_AdminController {
19
  $file['line'] = $e->getRealLine();
20
  $this->set('file', $file );
21
  if( loco_debugging() ){
22
- $trace = array();
23
  foreach( $e->getRealTrace() as $raw ) {
24
  $frame = new Loco_mvc_ViewParams($raw);
25
  if( $frame->has('file') ){
19
  $file['line'] = $e->getRealLine();
20
  $this->set('file', $file );
21
  if( loco_debugging() ){
22
+ $trace = [];
23
  foreach( $e->getRealTrace() as $raw ) {
24
  $frame = new Loco_mvc_ViewParams($raw);
25
  if( $frame->has('file') ){
src/admin/Navigation.php CHANGED
@@ -34,9 +34,9 @@ class Loco_admin_Navigation extends ArrayIterator {
34
  // root link depends on bundle type
35
  $type = strtolower( $bundle->getType() );
36
  if( 'core' !== $type ){
37
- $link = new Loco_mvc_ViewParams( array(
38
  'href' => Loco_mvc_AdminRouter::generate($type),
39
- ) );
40
  if( 'theme' === $type ){
41
  $link['name'] = __('Themes','loco-translate');
42
  }
@@ -49,7 +49,7 @@ class Loco_admin_Navigation extends ArrayIterator {
49
  // Add actual bundle page, href may be unset to show as current page if needed
50
  $nav->add (
51
  $bundle->getName(),
52
- Loco_mvc_AdminRouter::generate( $type.'-view', array( 'bundle' => $bundle->getHandle() ) )
53
  );
54
 
55
  // client code will add current page
34
  // root link depends on bundle type
35
  $type = strtolower( $bundle->getType() );
36
  if( 'core' !== $type ){
37
+ $link = new Loco_mvc_ViewParams( [
38
  'href' => Loco_mvc_AdminRouter::generate($type),
39
+ ] );
40
  if( 'theme' === $type ){
41
  $link['name'] = __('Themes','loco-translate');
42
  }
49
  // Add actual bundle page, href may be unset to show as current page if needed
50
  $nav->add (
51
  $bundle->getName(),
52
+ Loco_mvc_AdminRouter::generate( $type.'-view', [ 'bundle' => $bundle->getHandle() ] )
53
  );
54
 
55
  // client code will add current page
src/admin/RootController.php CHANGED
@@ -8,9 +8,9 @@ class Loco_admin_RootController extends Loco_admin_list_BaseController {
8
  * {@inheritdoc}
9
  */
10
  public function getHelpTabs(){
11
- return array (
12
  __('Overview','default') => $this->viewSnippet('tab-home'),
13
- );
14
  }
15
 
16
 
@@ -27,7 +27,7 @@ class Loco_admin_RootController extends Loco_admin_list_BaseController {
27
  $this->set('theme', $this->bundleParam($theme) );
28
 
29
  // Show plugins that have currently loaded translations
30
- $bundles = array();
31
  foreach( Loco_package_Listener::singleton()->getPlugins() as $bundle ){
32
  try {
33
  $bundles[] = $this->bundleParam($bundle);
@@ -41,7 +41,7 @@ class Loco_admin_RootController extends Loco_admin_list_BaseController {
41
 
42
 
43
  // Show recently "used' bundles
44
- $bundles = array();
45
  $recent = Loco_data_RecentItems::get();
46
  // filter in lieu of plugin setting
47
  $maxlen = apply_filters('loco_num_recent_bundles', 10 );
@@ -61,23 +61,23 @@ class Loco_admin_RootController extends Loco_admin_list_BaseController {
61
  $locale = Loco_Locale::parse( get_locale() );
62
  $api = new Loco_api_WordPressTranslations;
63
  $tag = (string) $locale;
64
- $this->set( 'siteLocale', new Loco_mvc_ViewParams( array(
65
  'code' => $tag,
66
  'name' => ( $name = $locale->ensureName($api) ),
67
  'attr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"',
68
- 'link' => '<a href="'.esc_url(Loco_mvc_AdminRouter::generate('lang-view', array('locale'=>$tag) )).'">'.esc_html($name).'</a>',
69
  //'opts' => admin_url('options-general.php').'#WPLANG',
70
- ) ) );
71
 
72
  // user's "admin" language may differ and is worth showing
73
  if( function_exists('get_user_locale') ){
74
  $locale = Loco_Locale::parse( get_user_locale() );
75
  $alt = (string) $locale;
76
  if( $tag !== $alt ){
77
- $this->set( 'adminLocale', new Loco_mvc_ViewParams( array(
78
  'name' => ( $name = $locale->ensureName($api) ),
79
- 'link' => '<a href="'.esc_url(Loco_mvc_AdminRouter::generate('lang-view', array('locale'=>$tag) )).'">'.esc_html($name).'</a>',
80
- ) ) );
81
  }
82
  }
83
 
8
  * {@inheritdoc}
9
  */
10
  public function getHelpTabs(){
11
+ return [
12
  __('Overview','default') => $this->viewSnippet('tab-home'),
13
+ ];
14
  }
15
 
16
 
27
  $this->set('theme', $this->bundleParam($theme) );
28
 
29
  // Show plugins that have currently loaded translations
30
+ $bundles = [];
31
  foreach( Loco_package_Listener::singleton()->getPlugins() as $bundle ){
32
  try {
33
  $bundles[] = $this->bundleParam($bundle);
41
 
42
 
43
  // Show recently "used' bundles
44
+ $bundles = [];
45
  $recent = Loco_data_RecentItems::get();
46
  // filter in lieu of plugin setting
47
  $maxlen = apply_filters('loco_num_recent_bundles', 10 );
61
  $locale = Loco_Locale::parse( get_locale() );
62
  $api = new Loco_api_WordPressTranslations;
63
  $tag = (string) $locale;
64
+ $this->set( 'siteLocale', new Loco_mvc_ViewParams( [
65
  'code' => $tag,
66
  'name' => ( $name = $locale->ensureName($api) ),
67
  'attr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"',
68
+ 'link' => '<a href="'.esc_url(Loco_mvc_AdminRouter::generate('lang-view', ['locale'=>$tag] )).'">'.esc_html($name).'</a>',
69
  //'opts' => admin_url('options-general.php').'#WPLANG',
70
+ ] ) );
71
 
72
  // user's "admin" language may differ and is worth showing
73
  if( function_exists('get_user_locale') ){
74
  $locale = Loco_Locale::parse( get_user_locale() );
75
  $alt = (string) $locale;
76
  if( $tag !== $alt ){
77
+ $this->set( 'adminLocale', new Loco_mvc_ViewParams( [
78
  'name' => ( $name = $locale->ensureName($api) ),
79
+ 'link' => '<a href="'.esc_url(Loco_mvc_AdminRouter::generate('lang-view', ['locale'=>$tag] )).'">'.esc_html($name).'</a>',
80
+ ] ) );
81
  }
82
  }
83
 
src/admin/bundle/BaseController.php CHANGED
@@ -104,17 +104,17 @@ abstract class Loco_admin_bundle_BaseController extends Loco_mvc_AdminController
104
  // navigate between bundle view siblings
105
  $tabs = new Loco_admin_Navigation;
106
  $this->set( 'tabs', $tabs );
107
- $actions = array (
108
  'view' => __('Overview','loco-translate'),
109
  'setup' => __('Setup','loco-translate'),
110
  'conf' => __('Advanced','loco-translate'),
111
- );
112
  if( loco_debugging() ){
113
  $actions['debug'] = __('Debug','loco-translate');
114
  }
115
  $suffix = $this->get('action');
116
  $prefix = strtolower( $this->get('type') );
117
- $getarg = array_intersect_key( $_GET, array('bundle'=>'') );
118
  foreach( $actions as $action => $name ){
119
  $href = Loco_mvc_AdminRouter::generate( $prefix.'-'.$action, $getarg );
120
  $tabs->add( $name, $href, $action === $suffix );
@@ -133,12 +133,12 @@ abstract class Loco_admin_bundle_BaseController extends Loco_mvc_AdminController
133
  */
134
  protected function prepareFsConnect( $type, $relpath ){
135
 
136
- $fields = new Loco_mvc_HiddenFields( array(
137
  'auth' => $type,
138
  'path' => $relpath,
139
  'loco-nonce' => wp_create_nonce('fsConnect'),
140
  '_fs_nonce' => wp_create_nonce('filesystem-credentials'), // <- WP 4.7.5 added security fix
141
- ) ) ;
142
  $this->set('fsFields', $fields );
143
 
144
  // may have fs credentials saved in session
104
  // navigate between bundle view siblings
105
  $tabs = new Loco_admin_Navigation;
106
  $this->set( 'tabs', $tabs );
107
+ $actions = [
108
  'view' => __('Overview','loco-translate'),
109
  'setup' => __('Setup','loco-translate'),
110
  'conf' => __('Advanced','loco-translate'),
111
+ ];
112
  if( loco_debugging() ){
113
  $actions['debug'] = __('Debug','loco-translate');
114
  }
115
  $suffix = $this->get('action');
116
  $prefix = strtolower( $this->get('type') );
117
+ $getarg = array_intersect_key( $_GET, ['bundle'=>''] );
118
  foreach( $actions as $action => $name ){
119
  $href = Loco_mvc_AdminRouter::generate( $prefix.'-'.$action, $getarg );
120
  $tabs->add( $name, $href, $action === $suffix );
133
  */
134
  protected function prepareFsConnect( $type, $relpath ){
135
 
136
+ $fields = new Loco_mvc_HiddenFields( [
137
  'auth' => $type,
138
  'path' => $relpath,
139
  'loco-nonce' => wp_create_nonce('fsConnect'),
140
  '_fs_nonce' => wp_create_nonce('filesystem-credentials'), // <- WP 4.7.5 added security fix
141
+ ] ) ;
142
  $this->set('fsFields', $fields );
143
 
144
  // may have fs credentials saved in session
src/admin/bundle/ConfController.php CHANGED
@@ -51,9 +51,9 @@ class Loco_admin_bundle_ConfController extends Loco_admin_bundle_BaseController
51
  * {@inheritdoc}
52
  */
53
  public function getHelpTabs(){
54
- return array (
55
  __('Advanced tab','loco-translate') => $this->viewSnippet('tab-bundle-conf'),
56
- );
57
  }
58
 
59
 
@@ -70,10 +70,10 @@ class Loco_admin_bundle_ConfController extends Loco_admin_bundle_BaseController
70
 
71
  // parent themes are inherited into bundle, we don't want them in the child theme config
72
  if( $bundle->isTheme() && ( $parent = $bundle->getParent() ) ){
73
- $this->set( 'parent', new Loco_mvc_ViewParams( array(
74
  'name' => $parent->getName(),
75
- 'href' => Loco_mvc_AdminRouter::generate('theme-conf', array( 'bundle' => $parent->getSlug() ) + $_GET ),
76
- ) ) );
77
  }
78
 
79
  // render postdata straight back to form if sent
@@ -104,7 +104,7 @@ class Loco_admin_bundle_ConfController extends Loco_admin_bundle_BaseController
104
 
105
  // build config blocks for form
106
  $i = 0;
107
- $conf = array();
108
  foreach( $data['conf'] as $raw ){
109
  if( empty($raw['removed']) ){
110
  $slug = $raw['slug'];
@@ -128,12 +128,12 @@ class Loco_admin_bundle_ConfController extends Loco_admin_bundle_BaseController
128
  $this->set('author', $info->getAuthorLink() );
129
 
130
  // link for downloading current configuration XML file
131
- $args = array (
132
  'path' => 'loco.xml',
133
  'action' => 'loco_download',
134
  'bundle' => $bundle->getHandle(),
135
  'type' => $bundle->getType()
136
- );
137
  $this->set( 'xmlUrl', Loco_mvc_AjaxRouter::generate( 'DownloadConf', $args ) );
138
  $this->set( 'manUrl', apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/bundle-config') );
139
 
51
  * {@inheritdoc}
52
  */
53
  public function getHelpTabs(){
54
+ return [
55
  __('Advanced tab','loco-translate') => $this->viewSnippet('tab-bundle-conf'),
56
+ ];
57
  }
58
 
59
 
70
 
71
  // parent themes are inherited into bundle, we don't want them in the child theme config
72
  if( $bundle->isTheme() && ( $parent = $bundle->getParent() ) ){
73
+ $this->set( 'parent', new Loco_mvc_ViewParams( [
74
  'name' => $parent->getName(),
75
+ 'href' => Loco_mvc_AdminRouter::generate('theme-conf', [ 'bundle' => $parent->getSlug() ] + $_GET ),
76
+ ] ) );
77
  }
78
 
79
  // render postdata straight back to form if sent
104
 
105
  // build config blocks for form
106
  $i = 0;
107
+ $conf = [];
108
  foreach( $data['conf'] as $raw ){
109
  if( empty($raw['removed']) ){
110
  $slug = $raw['slug'];
128
  $this->set('author', $info->getAuthorLink() );
129
 
130
  // link for downloading current configuration XML file
131
+ $args = [
132
  'path' => 'loco.xml',
133
  'action' => 'loco_download',
134
  'bundle' => $bundle->getHandle(),
135
  'type' => $bundle->getType()
136
+ ];
137
  $this->set( 'xmlUrl', Loco_mvc_AjaxRouter::generate( 'DownloadConf', $args ) );
138
  $this->set( 'manUrl', apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/bundle-config') );
139
 
src/admin/bundle/DebugController.php CHANGED
@@ -28,18 +28,18 @@ class Loco_admin_bundle_DebugController extends Loco_admin_bundle_BaseController
28
  $this->set('notices', $notices = new Loco_mvc_ViewParams );
29
  /* @var $notice Loco_error_Exception */
30
  foreach( $debugger as $notice ){
31
- $notices[] = new Loco_mvc_ViewParams( array(
32
  'style' => 'notice inline notice-'.$notice->getType(),
33
  'title' => $notice->getTitle(),
34
  'body' => $notice->getMessage(),
35
- ) );
36
  }
37
 
38
  $meta = $bundle->getHeaderInfo();
39
- $this->set('meta', new Loco_mvc_ViewParams( array(
40
  'vendor' => $meta->getVendorHost(),
41
  'author' => $meta->getAuthorCredit(),
42
- ) ) );
43
 
44
  if( count($bundle) ){
45
  $writer = new Loco_config_BundleWriter( $bundle );
28
  $this->set('notices', $notices = new Loco_mvc_ViewParams );
29
  /* @var $notice Loco_error_Exception */
30
  foreach( $debugger as $notice ){
31
+ $notices[] = new Loco_mvc_ViewParams( [
32
  'style' => 'notice inline notice-'.$notice->getType(),
33
  'title' => $notice->getTitle(),
34
  'body' => $notice->getMessage(),
35
+ ] );
36
  }
37
 
38
  $meta = $bundle->getHeaderInfo();
39
+ $this->set('meta', new Loco_mvc_ViewParams( [
40
  'vendor' => $meta->getVendorHost(),
41
  'author' => $meta->getAuthorCredit(),
42
+ ] ) );
43
 
44
  if( count($bundle) ){
45
  $writer = new Loco_config_BundleWriter( $bundle );
src/admin/bundle/LocaleController.php CHANGED
@@ -30,9 +30,9 @@ class Loco_admin_bundle_LocaleController extends Loco_mvc_AdminController {
30
  * {@inheritdoc}
31
  */
32
  public function getHelpTabs(){
33
- return array (
34
  __('Overview','default') => $this->viewSnippet('tab-locale-view'),
35
- );
36
  }
37
 
38
 
@@ -56,7 +56,7 @@ class Loco_admin_bundle_LocaleController extends Loco_mvc_AdminController {
56
 
57
  // Get PO files for this locale
58
  $files = $package->findLocaleFiles();
59
- $translations = array();
60
  $modified = 0;
61
  $npofiles = 0;
62
  $nfiles = 0;
@@ -82,14 +82,14 @@ class Loco_admin_bundle_LocaleController extends Loco_mvc_AdminController {
82
  $domain = $project->getDomain()->getName();
83
  $bundle = $project->getBundle();
84
  $type = strtolower( $bundle->getType() );
85
- $args = array(
86
  // 'locale' => $tag,
87
  'bundle' => $bundle->getHandle(),
88
  'domain' => $project->getId(),
89
  'path' => $meta->getPath(false),
90
- );
91
  // append data required for PO table row, except use bundle data instead of locale data
92
- $translations[$type][] = new Loco_mvc_ViewParams( array (
93
  // bundle info
94
  'title' => $project->getName(),
95
  'domain' => $domain,
@@ -110,7 +110,7 @@ class Loco_admin_bundle_LocaleController extends Loco_mvc_AdminController {
110
  'move' => Loco_mvc_AdminRouter::generate( $type.'-file-move', $args ),
111
  'delete' => Loco_mvc_AdminRouter::generate( $type.'-file-delete', $args ),
112
  'copy' => Loco_mvc_AdminRouter::generate( $type.'-msginit', $args ),
113
- ) );
114
  }
115
 
116
  $title = __( 'Installed languages', 'loco-translate' );
@@ -131,29 +131,29 @@ class Loco_admin_bundle_LocaleController extends Loco_mvc_AdminController {
131
  }
132
 
133
  // Translated type labels and "See all <type>" links
134
- $types = array(
135
- 'core' => new Loco_mvc_ViewParams( array(
136
  'name' => __('WordPress Core','loco-translate'),
137
  'text' => __('See all core translations','loco-translate'),
138
  'href' => Loco_mvc_AdminRouter::generate('core')
139
- ) ),
140
- 'theme' => new Loco_mvc_ViewParams( array(
141
  'name' => __('Themes','loco-translate'),
142
  'text' => __('See all themes','loco-translate'),
143
  'href' => Loco_mvc_AdminRouter::generate('theme')
144
- ) ),
145
- 'plugin' => new Loco_mvc_ViewParams( array(
146
  'name' => __('Plugins','loco-translate'),
147
  'text' => __('See all plugins','loco-translate'),
148
  'href' => Loco_mvc_AdminRouter::generate('plugin')
149
- ) ),
150
- );
151
 
152
- $this->set( 'locale', new Loco_mvc_ViewParams( array(
153
  'code' => $tag,
154
  'name' => $locale->getName(),
155
  'attr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"',
156
- ) ) );
157
 
158
  return $this->view( 'admin/bundle/locale', compact('breadcrumb','translations','types','npofiles','modified') );
159
  }
30
  * {@inheritdoc}
31
  */
32
  public function getHelpTabs(){
33
+ return [
34
  __('Overview','default') => $this->viewSnippet('tab-locale-view'),
35
+ ];
36
  }
37
 
38
 
56
 
57
  // Get PO files for this locale
58
  $files = $package->findLocaleFiles();
59
+ $translations = [];
60
  $modified = 0;
61
  $npofiles = 0;
62
  $nfiles = 0;
82
  $domain = $project->getDomain()->getName();
83
  $bundle = $project->getBundle();
84
  $type = strtolower( $bundle->getType() );
85
+ $args = [
86
  // 'locale' => $tag,
87
  'bundle' => $bundle->getHandle(),
88
  'domain' => $project->getId(),
89
  'path' => $meta->getPath(false),
90
+ ];
91
  // append data required for PO table row, except use bundle data instead of locale data
92
+ $translations[$type][] = new Loco_mvc_ViewParams( [
93
  // bundle info
94
  'title' => $project->getName(),
95
  'domain' => $domain,
110
  'move' => Loco_mvc_AdminRouter::generate( $type.'-file-move', $args ),
111
  'delete' => Loco_mvc_AdminRouter::generate( $type.'-file-delete', $args ),
112
  'copy' => Loco_mvc_AdminRouter::generate( $type.'-msginit', $args ),
113
+ ] );
114
  }
115
 
116
  $title = __( 'Installed languages', 'loco-translate' );
131
  }
132
 
133
  // Translated type labels and "See all <type>" links
134
+ $types = [
135
+ 'core' => new Loco_mvc_ViewParams( [
136
  'name' => __('WordPress Core','loco-translate'),
137
  'text' => __('See all core translations','loco-translate'),
138
  'href' => Loco_mvc_AdminRouter::generate('core')
139
+ ] ),
140
+ 'theme' => new Loco_mvc_ViewParams( [
141
  'name' => __('Themes','loco-translate'),
142
  'text' => __('See all themes','loco-translate'),
143
  'href' => Loco_mvc_AdminRouter::generate('theme')
144
+ ] ),
145
+ 'plugin' => new Loco_mvc_ViewParams( [
146
  'name' => __('Plugins','loco-translate'),
147
  'text' => __('See all plugins','loco-translate'),
148
  'href' => Loco_mvc_AdminRouter::generate('plugin')
149
+ ] ),
150
+ ];
151
 
152
+ $this->set( 'locale', new Loco_mvc_ViewParams( [
153
  'code' => $tag,
154
  'name' => $locale->getName(),
155
  'attr' => 'class="'.$locale->getIcon().'" lang="'.$locale->lang.'"',
156
+ ] ) );
157
 
158
  return $this->view( 'admin/bundle/locale', compact('breadcrumb','translations','types','npofiles','modified') );
159
  }
src/admin/bundle/SetupController.php CHANGED
@@ -21,9 +21,9 @@ class Loco_admin_bundle_SetupController extends Loco_admin_bundle_BaseController
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
- return array (
25
  __('Setup tab','loco-translate') => $this->viewSnippet('tab-bundle-setup'),
26
- );
27
  }
28
 
29
 
@@ -136,10 +136,10 @@ class Loco_admin_bundle_SetupController extends Loco_admin_bundle_BaseController
136
 
137
  // enable form to paste JSON config (via remote lookup)
138
  if( $this->get('json') ){
139
- $fields = new Loco_mvc_HiddenFields( array(
140
  'json-content' => '',
141
  'version' => $info->Version,
142
- ) );
143
  $fields->setNonce( 'json-'.$action );
144
  $this->set('jsonFields', $fields );
145
 
@@ -149,9 +149,9 @@ class Loco_admin_bundle_SetupController extends Loco_admin_bundle_BaseController
149
  // remote config is done via JavaScript
150
  $this->enqueueScript('setup');
151
  $apiBase = apply_filters( 'loco_api_url', 'https://localise.biz/api' );
152
- $this->set('js', new Loco_mvc_ViewParams( array(
153
  'apiUrl' => $apiBase.'/wp/'.strtolower( $bundle->getType() ),
154
- ) ) );
155
  $doconf = true;
156
  }
157
 
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
+ return [
25
  __('Setup tab','loco-translate') => $this->viewSnippet('tab-bundle-setup'),
26
+ ];
27
  }
28
 
29
 
136
 
137
  // enable form to paste JSON config (via remote lookup)
138
  if( $this->get('json') ){
139
+ $fields = new Loco_mvc_HiddenFields( [
140
  'json-content' => '',
141
  'version' => $info->Version,
142
+ ] );
143
  $fields->setNonce( 'json-'.$action );
144
  $this->set('jsonFields', $fields );
145
 
149
  // remote config is done via JavaScript
150
  $this->enqueueScript('setup');
151
  $apiBase = apply_filters( 'loco_api_url', 'https://localise.biz/api' );
152
+ $this->set('js', new Loco_mvc_ViewParams( [
153
  'apiUrl' => $apiBase.'/wp/'.strtolower( $bundle->getType() ),
154
+ ] ) );
155
  $doconf = true;
156
  }
157
 
src/admin/bundle/ViewController.php CHANGED
@@ -21,9 +21,9 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
- return array (
25
  __('Overview','default') => $this->viewSnippet('tab-bundle-view'),
26
- );
27
  }
28
 
29
 
@@ -31,7 +31,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
31
  * Generate a link for a specific file resource within a project
32
  * @return string
33
  */
34
- private function getResourceLink( $page, Loco_package_Project $project, Loco_gettext_Metadata $meta, array $args = array() ){
35
  $args['path'] = $meta->getPath(false);
36
  return $this->getProjectLink( $page, $project, $args );
37
  }
@@ -41,7 +41,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
41
  * Generate a link for a project, but without being for a specific file
42
  * @return string
43
  */
44
- private function getProjectLink( $page, Loco_package_Project $project, array $args = array() ){
45
  $args['bundle'] = $this->get('bundle');
46
  $args['domain'] = $project->getId();
47
  $route = strtolower( $this->get('type') ).'-'.$page;
@@ -58,27 +58,27 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
58
  $name = $project->getName();
59
  $domain = $project->getDomain()->getName();
60
  $slug = $project->getSlug();
61
- $p = new Loco_mvc_ViewParams( array (
62
  'id' => $project->getId(),
63
  'name' => $name,
64
  'slug' => $slug,
65
  'domain' => $domain,
66
  'short' => ! $slug || $project->isDomainDefault() ? $domain : $domain.'→'.$slug,
67
- ) );
68
 
69
  // POT template file
70
  $pot = null;
71
  $file = $project->getPot();
72
  if( $file && $file->exists() ){
73
  $pot = Loco_gettext_Metadata::load($file);
74
- $p['pot'] = new Loco_mvc_ViewParams( array(
75
  // POT info
76
  'name' => $file->basename(),
77
  'time' => $file->modified(),
78
  // POT links
79
  'info' => $this->getResourceLink('file-info', $project, $pot ),
80
  'edit' => $this->getResourceLink('file-edit', $project, $pot ),
81
- ) );
82
  }
83
 
84
  // PO/MO files
@@ -93,45 +93,45 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
93
 
94
  // offer msginit unless plugin settings disallows optional POT
95
  if( $pot || 2 > Loco_data_Settings::get()->pot_expected ){
96
- $p['nav'][] = new Loco_mvc_ViewParams( array(
97
  'href' => $this->getProjectLink('msginit', $project ),
98
  'name' => __('New language','loco-translate'),
99
  'icon' => 'add',
100
- ) );
101
  }
102
 
103
  // Always offer PO file upload
104
- $p['nav'][] = new Loco_mvc_ViewParams( array(
105
  'href' => $this->getProjectLink('upload', $project ),
106
  'name' => __('Upload PO','loco-translate'),
107
  'icon' => 'upload',
108
- ) );
109
 
110
  // prevent editing of POT when config prohibits
111
  if( $pot ){
112
  if( $project->isPotLocked() || 1 < Loco_data_Settings::get()->pot_protect ) {
113
- $p['nav'][] = new Loco_mvc_ViewParams( array(
114
  'href' => $this->getResourceLink('file-view', $project, $pot ),
115
  'name' => __('View template','loco-translate'),
116
  'icon' => 'file',
117
- ) );
118
  }
119
  // offer template editing if permitted
120
  else {
121
- $p['nav'][] = new Loco_mvc_ViewParams( array(
122
  'href' => $this->getResourceLink('file-edit', $project, $pot ),
123
  'name' => __('Edit template','loco-translate'),
124
  'icon' => 'pencil',
125
- ) );
126
  }
127
  }
128
  // else offer creation of new Template
129
  else {
130
- $p['nav'][] = new Loco_mvc_ViewParams( array(
131
  'href' => $this->getProjectLink('xgettext', $project ),
132
  'name' => __('Create template','loco-translate'),
133
  'icon' => 'add',
134
- ) );
135
  }
136
 
137
  return $p;
@@ -146,13 +146,13 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
146
  * @return array[]
147
  */
148
  private function createPairs( Loco_fs_FileList $po, Loco_fs_FileList $mo, Loco_fs_File $pot = null ){
149
- $pairs = array();
150
  /* @var $pofile Loco_fs_LocaleFile */
151
  foreach( $po as $pofile ){
152
  if( $pot && $pofile->equal($pot) ){
153
  continue;
154
  }
155
- $pair = array( $pofile, null );
156
  $mofile = $pofile->cloneExtension('mo');
157
  if( $mofile->exists() ){
158
  $pair[1] = $mofile;
@@ -166,7 +166,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
166
  continue;
167
  }
168
  if( ! $pofile->exists() ){
169
- $pairs[] = array( null, $mofile );
170
  }
171
  }
172
  return $pairs;
@@ -191,7 +191,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
191
  }
192
  // collate as unique [PO,MO] pairs ensuring canonical template excluded
193
  $pairs = $this->createPairs( $po, $mo, $project->getPot() );
194
- $rows = array();
195
  foreach( $pairs as $pair ){
196
  // favour PO file if it exists
197
  list( $pofile, $mofile ) = $pair;
@@ -223,11 +223,11 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
223
  $meta = Loco_gettext_Metadata::load($file);
224
  $dir = new Loco_fs_LocaleDirectory( $file->dirname() );
225
  // routing arguments
226
- $args = array (
227
  'path' => $meta->getPath(false),
228
- );
229
  // Return data required for PO table row
230
- return new Loco_mvc_ViewParams( array (
231
  // locale info
232
  'lcode' => $locale ? (string) $locale : '',
233
  'lname' => $locale ? $locale->getName() : '',
@@ -248,7 +248,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
248
  'move' => $this->getProjectLink('file-move', $project, $args ),
249
  'delete' => $this->getProjectLink('file-delete', $project, $args ),
250
  'copy' => $this->getProjectLink('msginit', $project, $args ),
251
- ) );
252
  }
253
 
254
 
@@ -258,7 +258,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
258
  * @return array<Loco_mvc_ViewParams>
259
  */
260
  private function createBundleListing( Loco_package_Bundle $bundle ){
261
- $projects = array();
262
  /* @var $project Loco_package_Project */
263
  foreach( $bundle as $project ){
264
  $projects[] = $this->createProjectParams($project);
@@ -290,7 +290,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
290
 
291
  // Collect all configured projects
292
  $projects = $this->createBundleListing( $bundle );
293
- $unknown = array();
294
 
295
  // sniff additional unknown files if bundle is a theme or directory-based plugin that's been auto-detected
296
  if( 'file' === $configured || 'internal' === $configured ){
@@ -298,7 +298,7 @@ class Loco_admin_bundle_ViewController extends Loco_admin_bundle_BaseController
298
  }
299
  else if( $bundle->isTheme() || ( $bundle->isPlugin() && ! $bundle->isSingleFile() ) ){
300
  // TODO This needs abstracting into the Loco_package_Inverter class
301
- $prefixes = array();
302
  $po = new Loco_fs_LocaleFileList;
303
  $mo = new Loco_fs_LocaleFileList;
304
  $prefs = Loco_data_Preferences::get();
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
+ return [
25
  __('Overview','default') => $this->viewSnippet('tab-bundle-view'),
26
+ ];
27
  }
28
 
29
 
31
  * Generate a link for a specific file resource within a project
32
  * @return string
33
  */
34
+ private function getResourceLink( $page, Loco_package_Project $project, Loco_gettext_Metadata $meta, array $args = [] ){
35
  $args['path'] = $meta->getPath(false);
36
  return $this->getProjectLink( $page, $project, $args );
37
  }
41
  * Generate a link for a project, but without being for a specific file
42
  * @return string
43
  */
44
+ private function getProjectLink( $page, Loco_package_Project $project, array $args = [] ){
45
  $args['bundle'] = $this->get('bundle');
46
  $args['domain'] = $project->getId();
47
  $route = strtolower( $this->get('type') ).'-'.$page;
58
  $name = $project->getName();
59
  $domain = $project->getDomain()->getName();
60
  $slug = $project->getSlug();
61
+ $p = new Loco_mvc_ViewParams( [
62
  'id' => $project->getId(),
63
  'name' => $name,
64
  'slug' => $slug,
65
  'domain' => $domain,
66
  'short' => ! $slug || $project->isDomainDefault() ? $domain : $domain.'→'.$slug,
67
+ ] );
68
 
69
  // POT template file
70
  $pot = null;
71
  $file = $project->getPot();
72
  if( $file && $file->exists() ){
73
  $pot = Loco_gettext_Metadata::load($file);
74
+ $p['pot'] = new Loco_mvc_ViewParams( [
75
  // POT info
76
  'name' => $file->basename(),
77
  'time' => $file->modified(),
78
  // POT links
79
  'info' => $this->getResourceLink('file-info', $project, $pot ),
80
  'edit' => $this->getResourceLink('file-edit', $project, $pot ),
81
+ ] );
82
  }
83
 
84
  // PO/MO files
93
 
94
  // offer msginit unless plugin settings disallows optional POT
95
  if( $pot || 2 > Loco_data_Settings::get()->pot_expected ){
96
+ $p['nav'][] = new Loco_mvc_ViewParams( [
97
  'href' => $this->getProjectLink('msginit', $project ),
98
  'name' => __('New language','loco-translate'),
99
  'icon' => 'add',
100
+ ] );
101
  }
102
 
103
  // Always offer PO file upload
104
+ $p['nav'][] = new Loco_mvc_ViewParams( [
105
  'href' => $this->getProjectLink('upload', $project ),
106
  'name' => __('Upload PO','loco-translate'),
107
  'icon' => 'upload',
108
+ ] );
109
 
110
  // prevent editing of POT when config prohibits
111
  if( $pot ){
112
  if( $project->isPotLocked() || 1 < Loco_data_Settings::get()->pot_protect ) {
113
+ $p['nav'][] = new Loco_mvc_ViewParams( [
114
  'href' => $this->getResourceLink('file-view', $project, $pot ),
115
  'name' => __('View template','loco-translate'),
116
  'icon' => 'file',
117
+ ] );
118
  }
119
  // offer template editing if permitted
120
  else {
121
+ $p['nav'][] = new Loco_mvc_ViewParams( [
122
  'href' => $this->getResourceLink('file-edit', $project, $pot ),
123
  'name' => __('Edit template','loco-translate'),
124
  'icon' => 'pencil',
125
+ ] );
126
  }
127
  }
128
  // else offer creation of new Template
129
  else {
130
+ $p['nav'][] = new Loco_mvc_ViewParams( [
131
  'href' => $this->getProjectLink('xgettext', $project ),
132
  'name' => __('Create template','loco-translate'),
133
  'icon' => 'add',
134
+ ] );
135
  }
136
 
137
  return $p;
146
  * @return array[]
147
  */
148
  private function createPairs( Loco_fs_FileList $po, Loco_fs_FileList $mo, Loco_fs_File $pot = null ){
149
+ $pairs = [];
150
  /* @var $pofile Loco_fs_LocaleFile */
151
  foreach( $po as $pofile ){
152
  if( $pot && $pofile->equal($pot) ){
153
  continue;
154
  }
155
+ $pair = [ $pofile, null ];
156
  $mofile = $pofile->cloneExtension('mo');
157
  if( $mofile->exists() ){
158
  $pair[1] = $mofile;
166
  continue;
167
  }
168
  if( ! $pofile->exists() ){
169
+ $pairs[] = [ null, $mofile ];
170
  }
171
  }
172
  return $pairs;
191
  }
192
  // collate as unique [PO,MO] pairs ensuring canonical template excluded
193
  $pairs = $this->createPairs( $po, $mo, $project->getPot() );
194
+ $rows = [];
195
  foreach( $pairs as $pair ){
196
  // favour PO file if it exists
197
  list( $pofile, $mofile ) = $pair;
223
  $meta = Loco_gettext_Metadata::load($file);
224
  $dir = new Loco_fs_LocaleDirectory( $file->dirname() );
225
  // routing arguments
226
+ $args = [
227
  'path' => $meta->getPath(false),
228
+ ];
229
  // Return data required for PO table row
230
+ return new Loco_mvc_ViewParams( [
231
  // locale info
232
  'lcode' => $locale ? (string) $locale : '',
233
  'lname' => $locale ? $locale->getName() : '',
248
  'move' => $this->getProjectLink('file-move', $project, $args ),
249
  'delete' => $this->getProjectLink('file-delete', $project, $args ),
250
  'copy' => $this->getProjectLink('msginit', $project, $args ),
251
+ ] );
252
  }
253
 
254
 
258
  * @return array<Loco_mvc_ViewParams>
259
  */
260
  private function createBundleListing( Loco_package_Bundle $bundle ){
261
+ $projects = [];
262
  /* @var $project Loco_package_Project */
263
  foreach( $bundle as $project ){
264
  $projects[] = $this->createProjectParams($project);
290
 
291
  // Collect all configured projects
292
  $projects = $this->createBundleListing( $bundle );
293
+ $unknown = [];
294
 
295
  // sniff additional unknown files if bundle is a theme or directory-based plugin that's been auto-detected
296
  if( 'file' === $configured || 'internal' === $configured ){
298
  }
299
  else if( $bundle->isTheme() || ( $bundle->isPlugin() && ! $bundle->isSingleFile() ) ){
300
  // TODO This needs abstracting into the Loco_package_Inverter class
301
+ $prefixes = [];
302
  $po = new Loco_fs_LocaleFileList;
303
  $mo = new Loco_fs_LocaleFileList;
304
  $prefs = Loco_data_Preferences::get();
src/admin/config/ApisController.php CHANGED
@@ -12,7 +12,7 @@ class Loco_admin_config_ApisController extends Loco_admin_config_BaseController
12
  $this->set( 'title', __('API keys','loco-translate') );
13
 
14
  // collect support API keys
15
- $apis = array();
16
  foreach( Loco_api_Providers::builtin() as $api ){
17
  $apis[ $api['id'] ] = new Loco_mvc_ViewParams($api);
18
  }
@@ -25,8 +25,8 @@ class Loco_admin_config_ApisController extends Loco_admin_config_BaseController
25
  $post = Loco_mvc_PostParams::get();
26
  if( $post->has('api') ){
27
  // Save only options in post. Avoids overwrite of missing site options
28
- $data = array();
29
- $filter = array();
30
  foreach( $apis as $id => $api ){
31
  $fields = $post->api[$id];
32
  if( is_array($fields) ){
@@ -61,11 +61,11 @@ class Loco_admin_config_ApisController extends Loco_admin_config_BaseController
61
  $breadcrumb->add( $title );
62
 
63
  // common ui elements / labels
64
- $this->set( 'ui', new Loco_mvc_ViewParams( array(
65
  'api_key' => __('API key','loco-translate'),
66
  'api_url' => __('API URL','loco-translate'),
67
  'api_region' => __('API region','loco-translate'),
68
- ) ) );
69
 
70
  return $this->view('admin/config/apis', compact('breadcrumb') );
71
  }
12
  $this->set( 'title', __('API keys','loco-translate') );
13
 
14
  // collect support API keys
15
+ $apis = [];
16
  foreach( Loco_api_Providers::builtin() as $api ){
17
  $apis[ $api['id'] ] = new Loco_mvc_ViewParams($api);
18
  }
25
  $post = Loco_mvc_PostParams::get();
26
  if( $post->has('api') ){
27
  // Save only options in post. Avoids overwrite of missing site options
28
+ $data = [];
29
+ $filter = [];
30
  foreach( $apis as $id => $api ){
31
  $fields = $post->api[$id];
32
  if( is_array($fields) ){
61
  $breadcrumb->add( $title );
62
 
63
  // common ui elements / labels
64
+ $this->set( 'ui', new Loco_mvc_ViewParams( [
65
  'api_key' => __('API key','loco-translate'),
66
  'api_url' => __('API URL','loco-translate'),
67
  'api_region' => __('API region','loco-translate'),
68
+ ] ) );
69
 
70
  return $this->view('admin/config/apis', compact('breadcrumb') );
71
  }
src/admin/config/BaseController.php CHANGED
@@ -14,12 +14,12 @@ abstract class Loco_admin_config_BaseController extends Loco_mvc_AdminController
14
  if( current_user_can('manage_options') ){
15
  $tabs = new Loco_admin_Navigation;
16
  $this->set( 'tabs', $tabs );
17
- $actions = array (
18
  '' => __('Site options','loco-translate'),
19
  'user' => __('User options','loco-translate'),
20
  'apis' => __('API keys','loco-translate'),
21
  'version' => __('Version','loco-translate'),
22
- );
23
  if( loco_debugging() ){
24
  $actions['debug'] = __('Debug','loco-translate');
25
  }
@@ -37,10 +37,10 @@ abstract class Loco_admin_config_BaseController extends Loco_mvc_AdminController
37
  * {@inheritdoc}
38
  */
39
  public function getHelpTabs(){
40
- return array (
41
  __('Overview','default') => $this->viewSnippet('tab-config'),
42
  __('API keys','loco-translate') => $this->viewSnippet('tab-config-apis'),
43
- );
44
  }
45
 
46
 
14
  if( current_user_can('manage_options') ){
15
  $tabs = new Loco_admin_Navigation;
16
  $this->set( 'tabs', $tabs );
17
+ $actions = [
18
  '' => __('Site options','loco-translate'),
19
  'user' => __('User options','loco-translate'),
20
  'apis' => __('API keys','loco-translate'),
21
  'version' => __('Version','loco-translate'),
22
+ ];
23
  if( loco_debugging() ){
24
  $actions['debug'] = __('Debug','loco-translate');
25
  }
37
  * {@inheritdoc}
38
  */
39
  public function getHelpTabs(){
40
+ return [
41
  __('Overview','default') => $this->viewSnippet('tab-config'),
42
  __('API keys','loco-translate') => $this->viewSnippet('tab-config-apis'),
43
+ ];
44
  }
45
 
46
 
src/admin/config/DebugController.php CHANGED
@@ -53,13 +53,13 @@ class Loco_admin_config_DebugController extends Loco_admin_config_BaseController
53
  loco_check_extension('ctype');
54
 
55
  // product versions:
56
- $versions = new Loco_mvc_ViewParams( array (
57
  'Loco Translate' => loco_plugin_version(),
58
  'WordPress' => $GLOBALS['wp_version'],
59
  'PHP' => phpversion().' ('.PHP_SAPI.')',
60
  'Server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ( function_exists('apache_get_version') ? apache_get_version() : '' ),
61
  'jQuery' => '...',
62
- ) );
63
  // we want to know about modules in case there are security mods installed known to break functionality
64
  if( function_exists('apache_get_modules') && ( $mods = preg_grep('/^mod_/',apache_get_modules() ) ) ){
65
  $versions['Server'] .= ' + '.implode(', ',$mods);
@@ -78,27 +78,27 @@ class Loco_admin_config_DebugController extends Loco_admin_config_BaseController
78
 
79
  // utf8 / encoding:
80
  $cs = get_option('blog_charset');
81
- $encoding = new Loco_mvc_ViewParams( array (
82
  'OK' => "\xCE\x9F\xCE\x9A",
83
  'tick' => "\xE2\x9C\x93",
84
  'json' => json_decode('"\\u039f\\u039a \\u2713"'),
85
  'charset' => $cs.' '.( preg_match('/^utf-?8$/i',$cs) ? "\xE2\x9C\x93" : '(not recommended)' ),
86
  'mbstring' => loco_check_extension('mbstring') ? "\xCE\x9F\xCE\x9A \xE2\x9C\x93" : 'No',
87
- ) );
88
  // Sanity check mbstring.func_overload
89
  if( 2 !== strlen("\xC2\xA3") ){
90
  $encoding->mbstring = 'Error, disable mbstring.func_overload';
91
  }
92
 
93
  // PHP / env memory settings:
94
- $memory = new Loco_mvc_PostParams( array(
95
  'WP_MEMORY_LIMIT' => $this->memory_size( loco_constant('WP_MEMORY_LIMIT') ),
96
  'WP_MAX_MEMORY_LIMIT' => $this->memory_size( loco_constant('WP_MAX_MEMORY_LIMIT') ),
97
  'PHP memory_limit' => $this->memory_size( ini_get('memory_limit') ),
98
  'PHP post_max_size' => $this->memory_size( ini_get('post_max_size') ),
99
  //'PHP upload_max_filesize' => $this->memory_size( ini_get('upload_max_filesize') ),
100
  'PHP max_execution_time' => (string) ini_get('max_execution_time'),
101
- ) );
102
 
103
  // Check if raising memory limit works (wp>=4.6)
104
  if( function_exists('wp_is_ini_value_changeable') && wp_is_ini_value_changeable('memory_limit') ){
@@ -107,13 +107,13 @@ class Loco_admin_config_DebugController extends Loco_admin_config_BaseController
107
 
108
  // Ajaxing:
109
  $this->enqueueScript('debug');
110
- $this->set( 'js', new Loco_mvc_ViewParams( array (
111
- 'nonces' => array( 'ping' => wp_create_nonce('ping'), 'apis' => wp_create_nonce('apis') ),
112
- ) ) );
113
 
114
  // Third party API integrations:
115
- $apis = array();
116
- $jsapis = array();
117
  foreach( Loco_api_Providers::sort( Loco_api_Providers::export() ) as $api ){
118
  $apis[] = new Loco_mvc_ViewParams($api);
119
  $jsapis[] = $api;
@@ -128,22 +128,22 @@ class Loco_admin_config_DebugController extends Loco_admin_config_BaseController
128
  $dir = new Loco_fs_Directory( loco_constant('LOCO_LANG_DIR') ) ;
129
  $ctx = new Loco_fs_FileWriter( $dir );
130
  $fsp = Loco_data_Settings::get()->fs_protect;
131
- $fs = new Loco_mvc_PostParams( array(
132
  'langdir' => $this->rel_path( $dir->getPath() ),
133
  'writable' => $ctx->writable(),
134
  'disabled' => $ctx->disabled(),
135
  'fs_protect' => 1 === $fsp ? 'Warn' : ( $fsp ? 'Block' : 'Off' ),
136
- ) );
137
 
138
  // Debug and error log settings
139
- $debug = new Loco_mvc_ViewParams( array(
140
  'WP_DEBUG' => loco_constant('WP_DEBUG') ? 'On' : 'Off',
141
  'WP_DEBUG_LOG' => loco_constant('WP_DEBUG_LOG') ? 'On' : 'Off',
142
  'WP_DEBUG_DISPLAY' => loco_constant('WP_DEBUG_DISPLAY') ? 'On' : 'Off',
143
  'PHP display_errors' => ini_get('display_errors') ? 'On' : 'Off',
144
  'PHP log_errors' => ini_get('log_errors') ? 'On' : 'Off',
145
  'PHP error_log' => $this->rel_path( ini_get('error_log') ),
146
- ) );
147
 
148
  /* Output buffering settings
149
  $this->set('ob', new Loco_mvc_ViewParams( array(
53
  loco_check_extension('ctype');
54
 
55
  // product versions:
56
+ $versions = new Loco_mvc_ViewParams( [
57
  'Loco Translate' => loco_plugin_version(),
58
  'WordPress' => $GLOBALS['wp_version'],
59
  'PHP' => phpversion().' ('.PHP_SAPI.')',
60
  'Server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ( function_exists('apache_get_version') ? apache_get_version() : '' ),
61
  'jQuery' => '...',
62
+ ] );
63
  // we want to know about modules in case there are security mods installed known to break functionality
64
  if( function_exists('apache_get_modules') && ( $mods = preg_grep('/^mod_/',apache_get_modules() ) ) ){
65
  $versions['Server'] .= ' + '.implode(', ',$mods);
78
 
79
  // utf8 / encoding:
80
  $cs = get_option('blog_charset');
81
+ $encoding = new Loco_mvc_ViewParams( [
82
  'OK' => "\xCE\x9F\xCE\x9A",
83
  'tick' => "\xE2\x9C\x93",
84
  'json' => json_decode('"\\u039f\\u039a \\u2713"'),
85
  'charset' => $cs.' '.( preg_match('/^utf-?8$/i',$cs) ? "\xE2\x9C\x93" : '(not recommended)' ),
86
  'mbstring' => loco_check_extension('mbstring') ? "\xCE\x9F\xCE\x9A \xE2\x9C\x93" : 'No',
87
+ ] );
88
  // Sanity check mbstring.func_overload
89
  if( 2 !== strlen("\xC2\xA3") ){
90
  $encoding->mbstring = 'Error, disable mbstring.func_overload';
91
  }
92
 
93
  // PHP / env memory settings:
94
+ $memory = new Loco_mvc_PostParams( [
95
  'WP_MEMORY_LIMIT' => $this->memory_size( loco_constant('WP_MEMORY_LIMIT') ),
96
  'WP_MAX_MEMORY_LIMIT' => $this->memory_size( loco_constant('WP_MAX_MEMORY_LIMIT') ),
97
  'PHP memory_limit' => $this->memory_size( ini_get('memory_limit') ),
98
  'PHP post_max_size' => $this->memory_size( ini_get('post_max_size') ),
99
  //'PHP upload_max_filesize' => $this->memory_size( ini_get('upload_max_filesize') ),
100
  'PHP max_execution_time' => (string) ini_get('max_execution_time'),
101
+ ] );
102
 
103
  // Check if raising memory limit works (wp>=4.6)
104
  if( function_exists('wp_is_ini_value_changeable') && wp_is_ini_value_changeable('memory_limit') ){
107
 
108
  // Ajaxing:
109
  $this->enqueueScript('debug');
110
+ $this->set( 'js', new Loco_mvc_ViewParams( [
111
+ 'nonces' => [ 'ping' => wp_create_nonce('ping'), 'apis' => wp_create_nonce('apis') ],
112
+ ] ) );
113
 
114
  // Third party API integrations:
115
+ $apis = [];
116
+ $jsapis = [];
117
  foreach( Loco_api_Providers::sort( Loco_api_Providers::export() ) as $api ){
118
  $apis[] = new Loco_mvc_ViewParams($api);
119
  $jsapis[] = $api;
128
  $dir = new Loco_fs_Directory( loco_constant('LOCO_LANG_DIR') ) ;
129
  $ctx = new Loco_fs_FileWriter( $dir );
130
  $fsp = Loco_data_Settings::get()->fs_protect;
131
+ $fs = new Loco_mvc_PostParams( [
132
  'langdir' => $this->rel_path( $dir->getPath() ),
133
  'writable' => $ctx->writable(),
134
  'disabled' => $ctx->disabled(),
135
  'fs_protect' => 1 === $fsp ? 'Warn' : ( $fsp ? 'Block' : 'Off' ),
136
+ ] );
137
 
138
  // Debug and error log settings
139
+ $debug = new Loco_mvc_ViewParams( [
140
  'WP_DEBUG' => loco_constant('WP_DEBUG') ? 'On' : 'Off',
141
  'WP_DEBUG_LOG' => loco_constant('WP_DEBUG_LOG') ? 'On' : 'Off',
142
  'WP_DEBUG_DISPLAY' => loco_constant('WP_DEBUG_DISPLAY') ? 'On' : 'Off',
143
  'PHP display_errors' => ini_get('display_errors') ? 'On' : 'Off',
144
  'PHP log_errors' => ini_get('log_errors') ? 'On' : 'Off',
145
  'PHP error_log' => $this->rel_path( ini_get('error_log') ),
146
+ ] );
147
 
148
  /* Output buffering settings
149
  $this->set('ob', new Loco_mvc_ViewParams( array(
src/admin/config/SettingsController.php CHANGED
@@ -26,7 +26,7 @@ class Loco_admin_config_SettingsController extends Loco_admin_config_BaseControl
26
  $post = Loco_mvc_PostParams::get();
27
  if( $post->has('opts') ){
28
  $opts->populate( $post->opts )->persist();
29
- $perms->populate( $post->has('caps') ? $post->caps : array() );
30
  // done update
31
  Loco_error_AdminNotices::success( __('Settings saved','loco-translate') );
32
  // remove saved params from session if persistent options unset
@@ -47,26 +47,26 @@ class Loco_admin_config_SettingsController extends Loco_admin_config_BaseControl
47
  $this->set('caps', $caps = new Loco_mvc_ViewParams );
48
  // there is no distinct role for network admin, so we'll fake it for UI
49
  if( is_multisite() ){
50
- $caps[''] = new Loco_mvc_ViewParams( array(
51
  'label' => __('Super Admin','default'),
52
  'name' => 'dummy-admin-cap',
53
  'attrs' => 'checked disabled'
54
- ) );
55
  }
56
  foreach( $perms->getRoles() as $id => $role ){
57
- $caps[$id] = new Loco_mvc_ViewParams( array(
58
  'value' => '1',
59
  'label' => $perms->getRoleName($id),
60
  'name' => 'caps['.$id.'][loco_admin]',
61
  'attrs' => $perms->isProtectedRole($role) ? 'checked disabled ' : ( $role->has_cap('loco_admin') ? 'checked ' : '' ),
62
- ) );
63
  }
64
  // allow/deny warning levels
65
- $this->set('verbose', new Loco_mvc_ViewParams( array(
66
  0 => __('Allow','loco-translate'),
67
  1 => __('Allow (with warning)','loco-translate'),
68
  2 => __('Disallow','loco-translate'),
69
- ) ) );
70
  }
71
 
72
 
26
  $post = Loco_mvc_PostParams::get();
27
  if( $post->has('opts') ){
28
  $opts->populate( $post->opts )->persist();
29
+ $perms->populate( $post->has('caps') ? $post->caps : [] );
30
  // done update
31
  Loco_error_AdminNotices::success( __('Settings saved','loco-translate') );
32
  // remove saved params from session if persistent options unset
47
  $this->set('caps', $caps = new Loco_mvc_ViewParams );
48
  // there is no distinct role for network admin, so we'll fake it for UI
49
  if( is_multisite() ){
50
+ $caps[''] = new Loco_mvc_ViewParams( [
51
  'label' => __('Super Admin','default'),
52
  'name' => 'dummy-admin-cap',
53
  'attrs' => 'checked disabled'
54
+ ] );
55
  }
56
  foreach( $perms->getRoles() as $id => $role ){
57
+ $caps[$id] = new Loco_mvc_ViewParams( [
58
  'value' => '1',
59
  'label' => $perms->getRoleName($id),
60
  'name' => 'caps['.$id.'][loco_admin]',
61
  'attrs' => $perms->isProtectedRole($role) ? 'checked disabled ' : ( $role->has_cap('loco_admin') ? 'checked ' : '' ),
62
+ ] );
63
  }
64
  // allow/deny warning levels
65
+ $this->set('verbose', new Loco_mvc_ViewParams( [
66
  0 => __('Allow','loco-translate'),
67
  1 => __('Allow (with warning)','loco-translate'),
68
  2 => __('Disallow','loco-translate'),
69
+ ] ) );
70
  }
71
 
72
 
src/admin/config/VersionController.php CHANGED
@@ -43,16 +43,16 @@ class Loco_admin_config_VersionController extends Loco_admin_config_BaseControll
43
 
44
  // check PHP version, noting that we want to move to minimum version 5.6 as per latest WordPress
45
  $phpversion = PHP_VERSION;
46
- if( version_compare($phpversion,'5.6.20','<') ){
47
- $this->setPhpUpdate('5.6.20');
48
  }
49
 
50
 
51
- // check WordPress version, noting that v5.2 bumped PHP min version to 5.6.20, as above
52
  $wpversion = $GLOBALS['wp_version'];
53
- if( version_compare($wpversion,'5.2','<') ){
54
  $this->setWpUpdate('5.2');
55
- }
56
 
57
  return $this->view('admin/config/version', compact('breadcrumb','version','phpversion','wpversion') );
58
  }
@@ -71,19 +71,11 @@ class Loco_admin_config_VersionController extends Loco_admin_config_BaseControll
71
 
72
  /**
73
  * @param string minimum recommended version
74
- */
75
- private function setPhpUpdate( $version ){
76
- $this->set('phpupdate',$version);
77
- }
78
-
79
-
80
- /**
81
- * @param string minimum recommended version
82
- */
83
  private function setWpUpdate( $version ){
84
  $this->set('wpupdate',$version);
85
  $this->set('wpupdate_href', admin_url('update-core.php') );
86
- }
87
 
88
 
89
  }
43
 
44
  // check PHP version, noting that we want to move to minimum version 5.6 as per latest WordPress
45
  $phpversion = PHP_VERSION;
46
+ if( version_compare($phpversion,'7.4.0','<') ){
47
+ $this->set('phpupdate','7.4');
48
  }
49
 
50
 
51
+ // check WordPress version, No plans to increase this until WP bumps their min PHP requirement.
52
  $wpversion = $GLOBALS['wp_version'];
53
+ /*if( version_compare($wpversion,'5.2','<') ){
54
  $this->setWpUpdate('5.2');
55
+ }*/
56
 
57
  return $this->view('admin/config/version', compact('breadcrumb','version','phpversion','wpversion') );
58
  }
71
 
72
  /**
73
  * @param string minimum recommended version
74
+ *
 
 
 
 
 
 
 
 
75
  private function setWpUpdate( $version ){
76
  $this->set('wpupdate',$version);
77
  $this->set('wpupdate_href', admin_url('update-core.php') );
78
+ }*/
79
 
80
 
81
  }
src/admin/file/BaseController.php CHANGED
@@ -27,18 +27,18 @@ abstract class Loco_admin_file_BaseController extends Loco_admin_bundle_BaseCont
27
  protected function getFileError( Loco_fs_File $file = null ){
28
  // file must exist for editing
29
  if( is_null($file) || ! $file->exists() ){
30
- return $this->view( 'admin/errors/file-missing', array() );
31
  }
32
  if( $file->isDirectory() ){
33
  $this->set('info', Loco_mvc_FileParams::create($file) );
34
- return $this->view( 'admin/errors/file-isdir', array() );
35
  }
36
  // security validations
37
  try {
38
  Loco_gettext_Data::ext( $file );
39
  }
40
  catch( Exception $e ){
41
- return $this->view( 'admin/errors/file-sec', array( 'reason' => $e->getMessage() ) );
42
  }
43
 
44
  return '';
@@ -75,13 +75,13 @@ abstract class Loco_admin_file_BaseController extends Loco_admin_bundle_BaseCont
75
  if( $localised ){
76
  $this->locale = $locale;
77
  $code = (string) $locale;
78
- $this->set( 'locale', new Loco_mvc_ViewParams( array(
79
  'code' => $code,
80
  'lang' => $locale->lang,
81
  'icon' => $locale->getIcon(),
82
  'name' => $locale->ensureName( new Loco_api_WordPressTranslations ),
83
- 'href' => Loco_mvc_AdminRouter::generate('lang-view', array('locale'=>$code) ),
84
- ) ) );
85
  }
86
  else {
87
  $this->set( 'locale', null );
@@ -99,18 +99,18 @@ abstract class Loco_admin_file_BaseController extends Loco_admin_bundle_BaseCont
99
  // navigate between sub view siblings for this resource
100
  $tabs = new Loco_admin_Navigation;
101
  $this->set( 'tabs', $tabs );
102
- $actions = array (
103
  'file-edit' => __('Editor','loco-translate'),
104
  'file-view' => __('Source','loco-translate'),
105
  'file-info' => __('File info','loco-translate'),
106
  'file-diff' => __('Restore','loco-translate'),
107
  'file-move' => $localised ? __('Relocate','loco-translate') : null,
108
  'file-delete' => __('Delete','loco-translate'),
109
- );
110
 
111
  $suffix = $this->get('action');
112
  $prefix = $this->get('type');
113
- $args = array_intersect_key($_GET,array('path'=>1,'bundle'=>1,'domain'=>1));
114
  foreach( $actions as $action => $name ){
115
  if( is_string($name) ){
116
  $href = Loco_mvc_AdminRouter::generate( $prefix.'-'.$action, $args );
@@ -121,11 +121,11 @@ abstract class Loco_admin_file_BaseController extends Loco_admin_bundle_BaseCont
121
  // Provide common language creation link if project scope is valid
122
  $project = $this->getOptionalProject();
123
  if( $project ){
124
- $args = array( 'bundle' => $bundle->getHandle(), 'domain' => $project->getId() );
125
- $this->set( 'msginit', new Loco_mvc_ViewParams( array (
126
  'href' => Loco_mvc_AdminRouter::generate( $prefix.'-msginit', $args ),
127
  'text' => __('New language','loco-translate'),
128
- ) ) );
129
  }
130
  }
131
 
@@ -134,7 +134,7 @@ abstract class Loco_admin_file_BaseController extends Loco_admin_bundle_BaseCont
134
  /**
135
  * {@inheritdoc}
136
  */
137
- public function view( $tpl, array $args = array() ){
138
 
139
  if( $breadcrumb = $this->get('breadcrumb') ){
140
 
27
  protected function getFileError( Loco_fs_File $file = null ){
28
  // file must exist for editing
29
  if( is_null($file) || ! $file->exists() ){
30
+ return $this->view( 'admin/errors/file-missing', [] );
31
  }
32
  if( $file->isDirectory() ){
33
  $this->set('info', Loco_mvc_FileParams::create($file) );
34
+ return $this->view( 'admin/errors/file-isdir', [] );
35
  }
36
  // security validations
37
  try {
38
  Loco_gettext_Data::ext( $file );
39
  }
40
  catch( Exception $e ){
41
+ return $this->view( 'admin/errors/file-sec', [ 'reason' => $e->getMessage() ] );
42
  }
43
 
44
  return '';
75
  if( $localised ){
76
  $this->locale = $locale;
77
  $code = (string) $locale;
78
+ $this->set( 'locale', new Loco_mvc_ViewParams( [
79
  'code' => $code,
80
  'lang' => $locale->lang,
81
  'icon' => $locale->getIcon(),
82
  'name' => $locale->ensureName( new Loco_api_WordPressTranslations ),
83
+ 'href' => Loco_mvc_AdminRouter::generate('lang-view', ['locale'=>$code] ),
84
+ ] ) );
85
  }
86
  else {
87
  $this->set( 'locale', null );
99
  // navigate between sub view siblings for this resource
100
  $tabs = new Loco_admin_Navigation;
101
  $this->set( 'tabs', $tabs );
102
+ $actions = [
103
  'file-edit' => __('Editor','loco-translate'),
104
  'file-view' => __('Source','loco-translate'),
105
  'file-info' => __('File info','loco-translate'),
106
  'file-diff' => __('Restore','loco-translate'),
107
  'file-move' => $localised ? __('Relocate','loco-translate') : null,
108
  'file-delete' => __('Delete','loco-translate'),
109
+ ];
110
 
111
  $suffix = $this->get('action');
112
  $prefix = $this->get('type');
113
+ $args = array_intersect_key($_GET,['path'=>1,'bundle'=>1,'domain'=>1]);
114
  foreach( $actions as $action => $name ){
115
  if( is_string($name) ){
116
  $href = Loco_mvc_AdminRouter::generate( $prefix.'-'.$action, $args );
121
  // Provide common language creation link if project scope is valid
122
  $project = $this->getOptionalProject();
123
  if( $project ){
124
+ $args = [ 'bundle' => $bundle->getHandle(), 'domain' => $project->getId() ];
125
+ $this->set( 'msginit', new Loco_mvc_ViewParams( [
126
  'href' => Loco_mvc_AdminRouter::generate( $prefix.'-msginit', $args ),
127
  'text' => __('New language','loco-translate'),
128
+ ] ) );
129
  }
130
  }
131
 
134
  /**
135
  * {@inheritdoc}
136
  */
137
+ public function view( $tpl, array $args = [] ){
138
 
139
  if( $breadcrumb = $this->get('breadcrumb') ){
140
 
src/admin/file/DeleteController.php CHANGED
@@ -37,7 +37,7 @@ class Loco_admin_file_DeleteController extends Loco_admin_file_BaseController {
37
  $path = $file->getPath();
38
  $action = 'delete:'.$path;
39
  // set up view now in case of late failure
40
- $fields = new Loco_mvc_HiddenFields( array() );
41
  $fields->setNonce( $action );
42
  $this->set( 'hidden', $fields );
43
  // attempt delete if valid nonce posted back
@@ -61,7 +61,7 @@ class Loco_admin_file_DeleteController extends Loco_admin_file_BaseController {
61
  // tolerate session failure
62
  }
63
  // redirect to bundle overview
64
- $href = Loco_mvc_AdminRouter::generate( $this->get('type').'-view', array( 'bundle' => $this->get('bundle') ) );
65
  if( wp_redirect($href) ){
66
  exit;
67
  }
@@ -97,7 +97,7 @@ class Loco_admin_file_DeleteController extends Loco_admin_file_BaseController {
97
  if( $deps = array_slice($files,1) ){
98
  $count = count($deps);
99
  $this->set('warn', sprintf( _n( '%s dependent file will also be deleted', '%s dependent files will also be deleted', $count, 'loco-translate' ), $count ) );
100
- $infos = array();
101
  foreach( $deps as $depfile ){
102
  $infos[] = Loco_mvc_FileParams::create( $depfile );
103
  }
37
  $path = $file->getPath();
38
  $action = 'delete:'.$path;
39
  // set up view now in case of late failure
40
+ $fields = new Loco_mvc_HiddenFields( [] );
41
  $fields->setNonce( $action );
42
  $this->set( 'hidden', $fields );
43
  // attempt delete if valid nonce posted back
61
  // tolerate session failure
62
  }
63
  // redirect to bundle overview
64
+ $href = Loco_mvc_AdminRouter::generate( $this->get('type').'-view', [ 'bundle' => $this->get('bundle') ] );
65
  if( wp_redirect($href) ){
66
  exit;
67
  }
97
  if( $deps = array_slice($files,1) ){
98
  $count = count($deps);
99
  $this->set('warn', sprintf( _n( '%s dependent file will also be deleted', '%s dependent files will also be deleted', $count, 'loco-translate' ), $count ) );
100
+ $infos = [];
101
  foreach( $deps as $depfile ){
102
  $infos[] = Loco_mvc_FileParams::create( $depfile );
103
  }
src/admin/file/DiffController.php CHANGED
@@ -16,7 +16,7 @@ class Loco_admin_file_DiffController extends Loco_admin_file_BaseController {
16
  $path = $pofile->getPath();
17
  $action = 'restore:'.$path;
18
  // set up view now in case of late failure
19
- $fields = new Loco_mvc_HiddenFields( array() );
20
  $fields->setNonce($action);
21
  $this->set( 'hidden', $fields );
22
  // attempt rollback if valid nonce posted back with backup path
@@ -78,9 +78,9 @@ class Loco_admin_file_DiffController extends Loco_admin_file_BaseController {
78
  $enabled = Loco_data_Settings::get()->num_backups;
79
  $this->set( 'enabled', $enabled );
80
 
81
- $files = array();
82
  $wp_content = loco_constant('WP_CONTENT_DIR');
83
- $paths = array( $file->getRelativePath($wp_content) );
84
 
85
  $podate = 'pot' === $file->extension() ? 'POT-Creation-Date' : 'PO-Revision-Date';
86
  $backups = new Loco_fs_Revisions($file);
@@ -126,12 +126,12 @@ class Loco_admin_file_DiffController extends Loco_admin_file_BaseController {
126
  $this->prepareFsConnect( 'update', $this->get('path') );
127
 
128
  // prepare revision arguments for JavaScript
129
- $this->set( 'js', new Loco_mvc_ViewParams( array(
130
  'paths' => $paths,
131
- 'nonces' => array (
132
  'diff' => wp_create_nonce('diff'),
133
- )
134
- ) ) );
135
 
136
  $this->enqueueScript('podiff');
137
  return $this->view('admin/file/diff', compact('files','backups') );
16
  $path = $pofile->getPath();
17
  $action = 'restore:'.$path;
18
  // set up view now in case of late failure
19
+ $fields = new Loco_mvc_HiddenFields( [] );
20
  $fields->setNonce($action);
21
  $this->set( 'hidden', $fields );
22
  // attempt rollback if valid nonce posted back with backup path
78
  $enabled = Loco_data_Settings::get()->num_backups;
79
  $this->set( 'enabled', $enabled );
80
 
81
+ $files = [];
82
  $wp_content = loco_constant('WP_CONTENT_DIR');
83
+ $paths = [ $file->getRelativePath($wp_content) ];
84
 
85
  $podate = 'pot' === $file->extension() ? 'POT-Creation-Date' : 'PO-Revision-Date';
86
  $backups = new Loco_fs_Revisions($file);
126
  $this->prepareFsConnect( 'update', $this->get('path') );
127
 
128
  // prepare revision arguments for JavaScript
129
+ $this->set( 'js', new Loco_mvc_ViewParams( [
130
  'paths' => $paths,
131
+ 'nonces' => [
132
  'diff' => wp_create_nonce('diff'),
133
+ ]
134
+ ] ) );
135
 
136
  $this->enqueueScript('podiff');
137
  return $this->view('admin/file/diff', compact('files','backups') );
src/admin/file/EditController.php CHANGED
@@ -23,9 +23,9 @@ class Loco_admin_file_EditController extends Loco_admin_file_BaseController {
23
  * {@inheritdoc}
24
  */
25
  public function getHelpTabs(){
26
- return array (
27
  __('Overview','default') => $this->viewSnippet('tab-file-edit'),
28
- );
29
  }
30
 
31
 
@@ -34,8 +34,8 @@ class Loco_admin_file_EditController extends Loco_admin_file_BaseController {
34
  * @return array
35
  */
36
  private function getNonces( $readonly ){
37
- $nonces = array();
38
- foreach( $readonly ? array('fsReference') : array('sync','save','fsReference','apis') as $name ){
39
  $nonces[$name] = wp_create_nonce($name);
40
  }
41
  return $nonces;
@@ -171,7 +171,7 @@ class Loco_admin_file_EditController extends Loco_admin_file_BaseController {
171
  // back end expects paths relative to wp-content
172
  $wp_content = loco_constant('WP_CONTENT_DIR');
173
 
174
- $this->set( 'js', new Loco_mvc_ViewParams( array(
175
  'podata' => $data->jsonSerialize(),
176
  'powrap' => (int) $settings->po_width,
177
  'multipart' => (bool) $settings->ajax_files,
@@ -181,13 +181,13 @@ class Loco_admin_file_EditController extends Loco_admin_file_BaseController {
181
  'syncmode' => $syncmode,
182
  'popath' => $this->get('path'),
183
  'readonly' => $readonly,
184
- 'project' => $project ? array (
185
  'bundle' => $bundle->getId(),
186
  'domain' => $project->getId(),
187
- ) : null,
188
  'nonces' => $this->getNonces($readonly),
189
- ) ) );
190
- $this->set( 'ui', new Loco_mvc_ViewParams( array(
191
  // Translators: button for adding a new string when manually editing a POT file
192
  'add' => _x('Add','Editor','loco-translate'),
193
  // Translators: button for removing a string when manually editing a POT file
@@ -209,15 +209,15 @@ class Loco_admin_file_EditController extends Loco_admin_file_BaseController {
209
  'invs' => _x('Toggle invisibles','Editor','loco-translate'),
210
  // Translators: Button that toggles between "code" and regular text editing modes
211
  'code' => _x('Toggle code view','Editor','loco-translate'),
212
- ) ) );
213
 
214
  // Download form params
215
- $hidden = new Loco_mvc_HiddenFields( array(
216
  'path' => '',
217
  'source' => '',
218
  'route' => 'download',
219
  'action' => 'loco_download',
220
- ) );
221
  $this->set( 'dlFields', $hidden->setNonce('download') );
222
  $this->set( 'dlAction', admin_url('admin-ajax.php','relative') );
223
 
@@ -229,7 +229,7 @@ class Loco_admin_file_EditController extends Loco_admin_file_BaseController {
229
 
230
  // ok to render editor as either po or pot
231
  $tpl = $locale ? 'po' : 'pot';
232
- return $this->view( 'admin/file/edit-'.$tpl, array() );
233
  }
234
 
235
 
23
  * {@inheritdoc}
24
  */
25
  public function getHelpTabs(){
26
+ return [
27
  __('Overview','default') => $this->viewSnippet('tab-file-edit'),
28
+ ];
29
  }
30
 
31
 
34
  * @return array
35
  */
36
  private function getNonces( $readonly ){
37
+ $nonces = [];
38
+ foreach( $readonly ? ['fsReference'] : ['sync','save','fsReference','apis'] as $name ){
39
  $nonces[$name] = wp_create_nonce($name);
40
  }
41
  return $nonces;
171
  // back end expects paths relative to wp-content
172
  $wp_content = loco_constant('WP_CONTENT_DIR');
173
 
174
+ $this->set( 'js', new Loco_mvc_ViewParams( [
175
  'podata' => $data->jsonSerialize(),
176
  'powrap' => (int) $settings->po_width,
177
  'multipart' => (bool) $settings->ajax_files,
181
  'syncmode' => $syncmode,
182
  'popath' => $this->get('path'),
183
  'readonly' => $readonly,
184
+ 'project' => $project ? [
185
  'bundle' => $bundle->getId(),
186
  'domain' => $project->getId(),
187
+ ] : null,
188
  'nonces' => $this->getNonces($readonly),
189
+ ] ) );
190
+ $this->set( 'ui', new Loco_mvc_ViewParams( [
191
  // Translators: button for adding a new string when manually editing a POT file
192
  'add' => _x('Add','Editor','loco-translate'),
193
  // Translators: button for removing a string when manually editing a POT file
209
  'invs' => _x('Toggle invisibles','Editor','loco-translate'),
210
  // Translators: Button that toggles between "code" and regular text editing modes
211
  'code' => _x('Toggle code view','Editor','loco-translate'),
212
+ ] ) );
213
 
214
  // Download form params
215
+ $hidden = new Loco_mvc_HiddenFields( [
216
  'path' => '',
217
  'source' => '',
218
  'route' => 'download',
219
  'action' => 'loco_download',
220
+ ] );
221
  $this->set( 'dlFields', $hidden->setNonce('download') );
222
  $this->set( 'dlAction', admin_url('admin-ajax.php','relative') );
223
 
229
 
230
  // ok to render editor as either po or pot
231
  $tpl = $locale ? 'po' : 'pot';
232
+ return $this->view( 'admin/file/edit-'.$tpl, [] );
233
  }
234
 
235
 
src/admin/file/HeadController.php CHANGED
@@ -17,7 +17,7 @@ class Loco_admin_file_HeadController extends Loco_admin_file_BaseController {
17
  $path = $file->getPath();
18
  $action = 'head:'.$path;
19
  // set up view now in case of late failure
20
- $fields = new Loco_mvc_HiddenFields( array() );
21
  $fields->setNonce( $action );
22
  $fields['auth'] = 'update';
23
  $fields['path'] = $this->get('path');
@@ -162,7 +162,7 @@ class Loco_admin_file_HeadController extends Loco_admin_file_BaseController {
162
  else if( '' === $conf->getSyncMode() ){
163
  $conf->setSyncMode('pot');
164
  }
165
-
166
  return $this->view('admin/file/conf');
167
  }
168
 
17
  $path = $file->getPath();
18
  $action = 'head:'.$path;
19
  // set up view now in case of late failure
20
+ $fields = new Loco_mvc_HiddenFields( [] );
21
  $fields->setNonce( $action );
22
  $fields['auth'] = 'update';
23
  $fields['path'] = $this->get('path');
162
  else if( '' === $conf->getSyncMode() ){
163
  $conf->setSyncMode('pot');
164
  }
165
+
166
  return $this->view('admin/file/conf');
167
  }
168
 
src/admin/file/InfoController.php CHANGED
@@ -22,9 +22,9 @@ class Loco_admin_file_InfoController extends Loco_admin_file_BaseController {
22
  * {@inheritdoc}
23
  */
24
  public function getHelpTabs(){
25
- return array (
26
  __('Overview','default') => $this->viewSnippet('tab-file-info'),
27
- );
28
  }
29
 
30
 
@@ -69,11 +69,11 @@ class Loco_admin_file_InfoController extends Loco_admin_file_BaseController {
69
  }
70
 
71
  // secure download link
72
- $args = new Loco_mvc_HiddenFields( array (
73
  'route' => 'download',
74
  'action' => 'loco_download',
75
  'path' => $file->getRelativePath(loco_constant('WP_CONTENT_DIR')),
76
- ) );
77
  $args->setNonce('download');
78
  $finfo['download'] = $args->getHref( admin_url('admin-ajax.php','relative') );
79
 
@@ -82,7 +82,7 @@ class Loco_admin_file_InfoController extends Loco_admin_file_BaseController {
82
 
83
  // collect note worthy problems with file headers
84
  $debugging = loco_debugging();
85
- $debug = array();
86
 
87
  // get the name of the web server for information purposes
88
  $this->set('httpd', Loco_compat_PosixExtension::getHttpdUser() );
@@ -156,9 +156,9 @@ class Loco_admin_file_InfoController extends Loco_admin_file_BaseController {
156
  // establish whether PO is in sync with POT
157
  if( $template && ! $isTemplate && 'po' === $ext && $template->exists() ){
158
  try {
159
- $this->set('potfile', new Loco_mvc_FileParams( array(
160
  'synced' => Loco_gettext_Data::load($template)->equalSource($data),
161
- ), $template ) );
162
  }
163
  catch( Exception $e ){
164
  // ignore invalid template in this context
22
  * {@inheritdoc}
23
  */
24
  public function getHelpTabs(){
25
+ return [
26
  __('Overview','default') => $this->viewSnippet('tab-file-info'),
27
+ ];
28
  }
29
 
30
 
69
  }
70
 
71
  // secure download link
72
+ $args = new Loco_mvc_HiddenFields( [
73
  'route' => 'download',
74
  'action' => 'loco_download',
75
  'path' => $file->getRelativePath(loco_constant('WP_CONTENT_DIR')),
76
+ ] );
77
  $args->setNonce('download');
78
  $finfo['download'] = $args->getHref( admin_url('admin-ajax.php','relative') );
79
 
82
 
83
  // collect note worthy problems with file headers
84
  $debugging = loco_debugging();
85
+ $debug = [];
86
 
87
  // get the name of the web server for information purposes
88
  $this->set('httpd', Loco_compat_PosixExtension::getHttpdUser() );
156
  // establish whether PO is in sync with POT
157
  if( $template && ! $isTemplate && 'po' === $ext && $template->exists() ){
158
  try {
159
+ $this->set('potfile', new Loco_mvc_FileParams( [
160
  'synced' => Loco_gettext_Data::load($template)->equalSource($data),
161
+ ], $template ) );
162
  }
163
  catch( Exception $e ){
164
  // ignore invalid template in this context
src/admin/file/MoveController.php CHANGED
@@ -19,7 +19,7 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
19
  $path = $file->getPath();
20
  $action = 'move:'.$path;
21
  // set up view now in case of late failure
22
- $fields = new Loco_mvc_HiddenFields( array() );
23
  $fields->setNonce( $action );
24
  $fields['auth'] = 'move';
25
  $fields['path'] = $this->get('path');
@@ -52,7 +52,7 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
52
  $target_base = $target->filename();
53
  $source_snip = strlen( $file->filename() );
54
  // buffer all files to move to preempt write failures
55
- $movable = array();
56
  $api = new Loco_api_WordPressFileSystem;
57
  foreach( $files->expand() as $source ){
58
  $suffix = substr( $source->basename(), $source_snip ); // <- e.g. "-backup.po~"
@@ -65,7 +65,7 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
65
  Loco_error_AdminNotices::err('Failed to authorize relocation of '.$source->basename() );
66
  break 2;
67
  }
68
- $movable[] = array($source,$target);
69
  }
70
  // commit moves. If any fail we'll have separated the files, which is bad
71
  $count = 0;
@@ -94,7 +94,7 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
94
  // tolerate session failure
95
  }
96
  // redirect to bundle overview
97
- $href = Loco_mvc_AdminRouter::generate( $this->get('type').'-view', array( 'bundle' => $this->get('bundle') ) );
98
  if( wp_redirect($href) ){
99
  exit;
100
  }
@@ -137,10 +137,10 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
137
  $current = $file->getRelativePath($content_dir);
138
  $parent = new Loco_fs_LocaleDirectory( $file->dirname() );
139
  $typeId = $parent->getTypeId();
140
- $this->set('current', new Loco_mvc_ViewParams(array(
141
  'path' => $parent->getRelativePath($content_dir),
142
  'type' => $parent->getTypeLabel($typeId),
143
- )) );
144
  // moving files will require deletion permission on current file location
145
  // plus write permission on target location, but we don't know what that is yet.
146
  $fields = $this->prepareFsConnect('move',$current);
@@ -155,14 +155,14 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
155
  // establish valid locations for translation set, which may include current:
156
  $filechoice = $project->initLocaleFiles($locale);
157
  // start with current location so always first in list
158
- $locations = array();
159
- $locations[$typeId] = new Loco_mvc_ViewParams( array(
160
  'label' => $parent->getTypeLabel($typeId),
161
- 'paths' => array( new Loco_mvc_ViewParams( array(
162
  'path' => $current,
163
  'active' => true,
164
- ) ) )
165
- ) );
166
  /* @var Loco_fs_File $pofile */
167
  foreach( $filechoice as $pofile ){
168
  $relpath = $pofile->getRelativePath($content_dir);
@@ -173,14 +173,14 @@ class Loco_admin_file_MoveController extends Loco_admin_file_BaseController {
173
  $parent = new Loco_fs_LocaleDirectory( $pofile->dirname() );
174
  $typeId = $parent->getTypeId();
175
  if( ! isset($locations[$typeId]) ){
176
- $locations[$typeId] = new Loco_mvc_ViewParams( array(
177
  'label' => $parent->getTypeLabel($typeId),
178
- 'paths' => array(),
179
- ) );
180
  }
181
- $choice = new Loco_mvc_ViewParams( array(
182
  'path' => $relpath,
183
- ) );
184
  $locations[$typeId]['paths'][] = $choice;
185
  }
186
  $this->set('locations', $locations );
19
  $path = $file->getPath();
20
  $action = 'move:'.$path;
21
  // set up view now in case of late failure
22
+ $fields = new Loco_mvc_HiddenFields( [] );
23
  $fields->setNonce( $action );
24
  $fields['auth'] = 'move';
25
  $fields['path'] = $this->get('path');
52
  $target_base = $target->filename();
53
  $source_snip = strlen( $file->filename() );
54
  // buffer all files to move to preempt write failures
55
+ $movable = [];
56
  $api = new Loco_api_WordPressFileSystem;
57
  foreach( $files->expand() as $source ){
58
  $suffix = substr( $source->basename(), $source_snip ); // <- e.g. "-backup.po~"
65
  Loco_error_AdminNotices::err('Failed to authorize relocation of '.$source->basename() );
66
  break 2;
67
  }
68
+ $movable[] = [$source,$target];
69
  }
70
  // commit moves. If any fail we'll have separated the files, which is bad
71
  $count = 0;
94
  // tolerate session failure
95
  }
96
  // redirect to bundle overview
97
+ $href = Loco_mvc_AdminRouter::generate( $this->get('type').'-view', [ 'bundle' => $this->get('bundle') ] );
98
  if( wp_redirect($href) ){
99
  exit;
100
  }
137
  $current = $file->getRelativePath($content_dir);
138
  $parent = new Loco_fs_LocaleDirectory( $file->dirname() );
139
  $typeId = $parent->getTypeId();
140
+ $this->set('current', new Loco_mvc_ViewParams([
141
  'path' => $parent->getRelativePath($content_dir),
142
  'type' => $parent->getTypeLabel($typeId),
143
+ ]) );
144
  // moving files will require deletion permission on current file location
145
  // plus write permission on target location, but we don't know what that is yet.
146
  $fields = $this->prepareFsConnect('move',$current);
155
  // establish valid locations for translation set, which may include current:
156
  $filechoice = $project->initLocaleFiles($locale);
157
  // start with current location so always first in list
158
+ $locations = [];
159
+ $locations[$typeId] = new Loco_mvc_ViewParams( [
160
  'label' => $parent->getTypeLabel($typeId),
161
+ 'paths' => [ new Loco_mvc_ViewParams( [
162
  'path' => $current,
163
  'active' => true,
164
+ ] ) ]
165
+ ] );
166
  /* @var Loco_fs_File $pofile */
167
  foreach( $filechoice as $pofile ){
168
  $relpath = $pofile->getRelativePath($content_dir);
173
  $parent = new Loco_fs_LocaleDirectory( $pofile->dirname() );
174
  $typeId = $parent->getTypeId();
175
  if( ! isset($locations[$typeId]) ){
176
+ $locations[$typeId] = new Loco_mvc_ViewParams( [
177
  'label' => $parent->getTypeLabel($typeId),
178
+ 'paths' => [],
179
+ ] );
180
  }
181
+ $choice = new Loco_mvc_ViewParams( [
182
  'path' => $relpath,
183
+ ] );
184
  $locations[$typeId]['paths'][] = $choice;
185
  }
186
  $this->set('locations', $locations );
src/admin/file/ViewController.php CHANGED
@@ -22,9 +22,9 @@ class Loco_admin_file_ViewController extends Loco_admin_file_BaseController {
22
  * {@inheritdoc}
23
  */
24
  public function getHelpTabs(){
25
- return array (
26
  __('Overview','default') => $this->viewSnippet('tab-file-view'),
27
- );
28
  }
29
 
30
 
@@ -77,16 +77,16 @@ class Loco_admin_file_ViewController extends Loco_admin_file_BaseController {
77
  $this->set( 'lines', $lines );
78
 
79
  // ajax parameters required for pulling reference sources
80
- $this->set('js', new Loco_mvc_ViewParams( array (
81
  'popath' => $this->get('path'),
82
- 'nonces' => array(
83
  'fsReference' => wp_create_nonce('fsReference'),
84
- ),
85
- 'project' => $bundle ? array (
86
  'bundle' => $bundle->getId(),
87
  'domain' => $project ? $project->getId() : '',
88
- ) : null,
89
- ) ) );
90
 
91
 
92
  // treat as PO if file name has locale
22
  * {@inheritdoc}
23
  */
24
  public function getHelpTabs(){
25
+ return [
26
  __('Overview','default') => $this->viewSnippet('tab-file-view'),
27
+ ];
28
  }
29
 
30
 
77
  $this->set( 'lines', $lines );
78
 
79
  // ajax parameters required for pulling reference sources
80
+ $this->set('js', new Loco_mvc_ViewParams( [
81
  'popath' => $this->get('path'),
82
+ 'nonces' => [
83
  'fsReference' => wp_create_nonce('fsReference'),
84
+ ],
85
+ 'project' => $bundle ? [
86
  'bundle' => $bundle->getId(),
87
  'domain' => $project ? $project->getId() : '',
88
+ ] : null,
89
+ ] ) );
90
 
91
 
92
  // treat as PO if file name has locale
src/admin/init/InitPoController.php CHANGED
@@ -21,9 +21,9 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
- return array (
25
  __('Overview','default') => $this->viewSnippet('tab-init-po'),
26
- );
27
  }
28
 
29
 
@@ -33,7 +33,7 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
33
  * @return Loco_mvc_ViewParams|null
34
  */
35
  private function sortPreferred( array $choices ){
36
- usort( $choices, array(__CLASS__,'_onSortPreferred') );
37
  $best = current( $choices );
38
  if( $best && ! $best['disabled'] ){
39
  return $best;
@@ -82,7 +82,7 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
82
  * @return int
83
  */
84
  private static function compareLocationKeys( $a, $b ){
85
- static $order = array('custom' => 4, 'wplang' => 3, 'theme' => 2, 'plugin' => 2, 'other' => 1 );
86
  $x = $order[$a];
87
  $y = $order[$b];
88
  return $x === $y ? 0 : ( $x > $y ? -1 : 1 );
@@ -148,8 +148,8 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
148
  }
149
 
150
 
151
- $locales = array();
152
- $installed = array();
153
  $api = new Loco_api_WordPressTranslations;
154
  $prefs = Loco_data_Preferences::get();
155
  // pull installed list first, this will include en_US and any non-standard languages installed
@@ -158,21 +158,21 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
158
  if( $locale->isValid() && $prefs->has_locale($locale) ){
159
  $tag = (string) $tag;
160
  // We may not have names for these, so just the language tag will show
161
- $installed[$tag] = new Loco_mvc_ViewParams( array(
162
  'value' => $tag,
163
  'icon' => $locale->getIcon(),
164
  'label' => $locale->ensureName($api),
165
- ) );
166
  }
167
  }
168
  // pull the same list of "available" languages as used in WordPress settings
169
  foreach( $api->getAvailableCore() as $tag => $locale ){
170
  if( ! array_key_exists($tag,$installed) && $prefs->has_locale($locale) ){
171
- $locales[$tag] = new Loco_mvc_ViewParams( array(
172
  'value' => $tag,
173
  'icon' => $locale->getIcon(),
174
  'label' => $locale->ensureName($api),
175
- ) );
176
  }
177
  }
178
 
@@ -196,10 +196,10 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
196
  $total = $meta->getTotal();
197
  // translators: 1: Number of strings; 2: Name of POT file; e.g. "100 strings found in file.pot"
198
  $summary = sprintf( _n('%1$s string found in %2$s','%1$s strings found in %2$s',$total,'loco-translate'), number_format($total), $potfile->basename() );
199
- $this->set( 'pot', new Loco_mvc_ViewParams( array(
200
  'name' => $potfile->basename(),
201
  'path' => $meta->getPath(false),
202
- ) ) );
203
  // if copying an existing PO file, we can fairly safely establish the correct prefixing
204
  if( $copying ){
205
  $poname = ( $prefix = $potfile->getPrefix() ) ? sprintf('%s-%s.po',$prefix,$locale) : sprintf('%s.po',$locale);
@@ -212,10 +212,10 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
212
  }
213
  // else no template exists, so we prompt to extract from source
214
  else if( 2 > Loco_data_Settings::get()->pot_expected ){
215
- $this->set( 'ext', new Loco_mvc_ViewParams( array(
216
  'link' => Loco_mvc_AdminRouter::generate( $this->get('type').'-xgettext', $_GET ),
217
  'text' => __('Create template','loco-translate'),
218
- ) ) );
219
  // if allowing source extraction without warning show brief description of source files
220
  if( $this->get('extract') || 0 === Loco_data_Settings::get()->pot_expected ){
221
  // Tokenizer required for string extraction
@@ -228,20 +228,20 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
228
  }
229
  // else prompt for template creation before continuing
230
  else {
231
- $this->set( 'skip', new Loco_mvc_ViewParams( array(
232
- 'link' => Loco_mvc_AdminRouter::generate( $this->get('_route'), $_GET + array( 'extract' => '1' ) ),
233
  'text' => __('Skip template','loco-translate'),
234
- ) ) );
235
  // POT could still be defined, it might just not exist yet
236
  if( $potfile ){
237
  $this->set('pot', Loco_mvc_FileParams::create($potfile) );
238
  }
239
  // else offer assignment of a new file
240
  else {
241
- $this->set( 'conf', new Loco_mvc_ViewParams( array(
242
- 'link' => Loco_mvc_AdminRouter::generate( $this->get('type').'-conf', array_intersect_key($_GET,array('bundle'=>'')) ),
243
  'text' => __('Assign template','loco-translate'),
244
- ) ) );
245
  }
246
  return $this->view('admin/init/init-prompt');
247
  }
@@ -253,8 +253,8 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
253
 
254
  // group established locations into types (official, etc..)
255
  // there is no point checking whether any of these file exist, because we don't know what language will be chosen yet.
256
- $sortable = array();
257
- $locations = array();
258
  $fs_failure = null;
259
  /* @var Loco_fs_LocaleFile $pofile */
260
  foreach( $filechoice as $pofile ){
@@ -262,10 +262,10 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
262
  $systype = $parent->getUpdateType();
263
  $typeId = $parent->getTypeId();
264
  if( ! isset($locations[$typeId]) ){
265
- $locations[$typeId] = new Loco_mvc_ViewParams( array(
266
  'label' => $parent->getTypeLabel( $typeId ),
267
- 'paths' => array(),
268
- ) );
269
  }
270
  // folder may be unwritable (requiring connect to create file) or may be denied under security settings
271
  try {
@@ -279,7 +279,7 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
279
  $disabled = true;
280
  }
281
  $suffix = $pofile->getSuffix().'.po';
282
- $choice = new Loco_mvc_ViewParams( array (
283
  'checked' => '',
284
  'writable' => $writable,
285
  'disabled' => $disabled,
@@ -287,13 +287,13 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
287
  'parent' => Loco_mvc_FileParams::create( $parent ),
288
  'hidden' => $pofile->getRelativePath($content_dir),
289
  'holder' => str_replace( $suffix, '<span>{locale}</span>.po', $pofile->basename() ),
290
- ) );
291
  $sortable[] = $choice;
292
  $locations[$typeId]['paths'][] = $choice;
293
  }
294
 
295
  // display locations in runtime preference order
296
- uksort( $locations, array(__CLASS__,'compareLocationKeys') );
297
  $this->set( 'locations', $locations );
298
 
299
  // pre-select best (safest/writable) option
@@ -306,7 +306,7 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
306
  }
307
 
308
  // hidden fields to pass through to Ajax endpoint
309
- $this->set('hidden', new Loco_mvc_HiddenFields( array(
310
  'action' => 'loco_json',
311
  'route' => 'msginit',
312
  'loco-nonce' => $this->setNonce('msginit')->value,
@@ -314,18 +314,18 @@ class Loco_admin_init_InitPoController extends Loco_admin_bundle_BaseController
314
  'bundle' => $bundle->getHandle(),
315
  'domain' => $project ? $project->getId() : '',
316
  'source' => $potpath,
317
- ) ) );
318
 
319
- $this->set('help', new Loco_mvc_ViewParams( array(
320
  'href' => apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/msginit'),
321
  'text' => __("What's this?",'loco-translate'),
322
- ) ) );
323
 
324
  // file system prompts will be handled when paths are selected (i.e. we don't have one yet)
325
  $this->prepareFsConnect( 'create', '' );
326
 
327
  $this->enqueueScript('poinit');
328
- return $this->view( 'admin/init/init-po', array() );
329
  }
330
 
331
  }
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
+ return [
25
  __('Overview','default') => $this->viewSnippet('tab-init-po'),
26
+ ];
27
  }
28
 
29
 
33
  * @return Loco_mvc_ViewParams|null
34
  */
35
  private function sortPreferred( array $choices ){
36
+ usort( $choices, [__CLASS__,'_onSortPreferred'] );
37
  $best = current( $choices );
38
  if( $best && ! $best['disabled'] ){
39
  return $best;
82
  * @return int
83
  */
84
  private static function compareLocationKeys( $a, $b ){
85
+ static $order = ['custom' => 4, 'wplang' => 3, 'theme' => 2, 'plugin' => 2, 'other' => 1 ];
86
  $x = $order[$a];
87
  $y = $order[$b];
88
  return $x === $y ? 0 : ( $x > $y ? -1 : 1 );
148
  }
149
 
150
 
151
+ $locales = [];
152
+ $installed = [];
153
  $api = new Loco_api_WordPressTranslations;
154
  $prefs = Loco_data_Preferences::get();
155
  // pull installed list first, this will include en_US and any non-standard languages installed
158
  if( $locale->isValid() && $prefs->has_locale($locale) ){
159
  $tag = (string) $tag;
160
  // We may not have names for these, so just the language tag will show
161
+ $installed[$tag] = new Loco_mvc_ViewParams( [
162
  'value' => $tag,
163
  'icon' => $locale->getIcon(),
164
  'label' => $locale->ensureName($api),
165
+ ] );
166
  }
167
  }
168
  // pull the same list of "available" languages as used in WordPress settings
169
  foreach( $api->getAvailableCore() as $tag => $locale ){
170
  if( ! array_key_exists($tag,$installed) && $prefs->has_locale($locale) ){
171
+ $locales[$tag] = new Loco_mvc_ViewParams( [
172
  'value' => $tag,
173
  'icon' => $locale->getIcon(),
174
  'label' => $locale->ensureName($api),
175
+ ] );
176
  }
177
  }
178
 
196
  $total = $meta->getTotal();
197
  // translators: 1: Number of strings; 2: Name of POT file; e.g. "100 strings found in file.pot"
198
  $summary = sprintf( _n('%1$s string found in %2$s','%1$s strings found in %2$s',$total,'loco-translate'), number_format($total), $potfile->basename() );
199
+ $this->set( 'pot', new Loco_mvc_ViewParams( [
200
  'name' => $potfile->basename(),
201
  'path' => $meta->getPath(false),
202
+ ] ) );
203
  // if copying an existing PO file, we can fairly safely establish the correct prefixing
204
  if( $copying ){
205
  $poname = ( $prefix = $potfile->getPrefix() ) ? sprintf('%s-%s.po',$prefix,$locale) : sprintf('%s.po',$locale);
212
  }
213
  // else no template exists, so we prompt to extract from source
214
  else if( 2 > Loco_data_Settings::get()->pot_expected ){
215
+ $this->set( 'ext', new Loco_mvc_ViewParams( [
216
  'link' => Loco_mvc_AdminRouter::generate( $this->get('type').'-xgettext', $_GET ),
217
  'text' => __('Create template','loco-translate'),
218
+ ] ) );
219
  // if allowing source extraction without warning show brief description of source files
220
  if( $this->get('extract') || 0 === Loco_data_Settings::get()->pot_expected ){
221
  // Tokenizer required for string extraction
228
  }
229
  // else prompt for template creation before continuing
230
  else {
231
+ $this->set( 'skip', new Loco_mvc_ViewParams( [
232
+ 'link' => Loco_mvc_AdminRouter::generate( $this->get('_route'), $_GET + [ 'extract' => '1' ] ),
233
  'text' => __('Skip template','loco-translate'),
234
+ ] ) );
235
  // POT could still be defined, it might just not exist yet
236
  if( $potfile ){
237
  $this->set('pot', Loco_mvc_FileParams::create($potfile) );
238
  }
239
  // else offer assignment of a new file
240
  else {
241
+ $this->set( 'conf', new Loco_mvc_ViewParams( [
242
+ 'link' => Loco_mvc_AdminRouter::generate( $this->get('type').'-conf', array_intersect_key($_GET,['bundle'=>'']) ),
243
  'text' => __('Assign template','loco-translate'),
244
+ ] ) );
245
  }
246
  return $this->view('admin/init/init-prompt');
247
  }
253
 
254
  // group established locations into types (official, etc..)
255
  // there is no point checking whether any of these file exist, because we don't know what language will be chosen yet.
256
+ $sortable = [];
257
+ $locations = [];
258
  $fs_failure = null;
259
  /* @var Loco_fs_LocaleFile $pofile */
260
  foreach( $filechoice as $pofile ){
262
  $systype = $parent->getUpdateType();
263
  $typeId = $parent->getTypeId();
264
  if( ! isset($locations[$typeId]) ){
265
+ $locations[$typeId] = new Loco_mvc_ViewParams( [
266
  'label' => $parent->getTypeLabel( $typeId ),
267
+ 'paths' => [],
268
+ ] );
269
  }
270
  // folder may be unwritable (requiring connect to create file) or may be denied under security settings
271
  try {
279
  $disabled = true;
280
  }
281
  $suffix = $pofile->getSuffix().'.po';
282
+ $choice = new Loco_mvc_ViewParams( [
283
  'checked' => '',
284
  'writable' => $writable,
285
  'disabled' => $disabled,
287
  'parent' => Loco_mvc_FileParams::create( $parent ),
288
  'hidden' => $pofile->getRelativePath($content_dir),
289
  'holder' => str_replace( $suffix, '<span>{locale}</span>.po', $pofile->basename() ),
290
+ ] );
291
  $sortable[] = $choice;
292
  $locations[$typeId]['paths'][] = $choice;
293
  }
294
 
295
  // display locations in runtime preference order
296
+ uksort( $locations, [__CLASS__,'compareLocationKeys'] );
297
  $this->set( 'locations', $locations );
298
 
299
  // pre-select best (safest/writable) option
306
  }
307
 
308
  // hidden fields to pass through to Ajax endpoint
309
+ $this->set('hidden', new Loco_mvc_HiddenFields( [
310
  'action' => 'loco_json',
311
  'route' => 'msginit',
312
  'loco-nonce' => $this->setNonce('msginit')->value,
314
  'bundle' => $bundle->getHandle(),
315
  'domain' => $project ? $project->getId() : '',
316
  'source' => $potpath,
317
+ ] ) );
318
 
319
+ $this->set('help', new Loco_mvc_ViewParams( [
320
  'href' => apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/msginit'),
321
  'text' => __("What's this?",'loco-translate'),
322
+ ] ) );
323
 
324
  // file system prompts will be handled when paths are selected (i.e. we don't have one yet)
325
  $this->prepareFsConnect( 'create', '' );
326
 
327
  $this->enqueueScript('poinit');
328
+ return $this->view( 'admin/init/init-po', [] );
329
  }
330
 
331
  }
src/admin/init/InitPotController.php CHANGED
@@ -21,9 +21,9 @@ class Loco_admin_init_InitPotController extends Loco_admin_bundle_BaseController
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
- return array (
25
  __('Overview','default') => $this->viewSnippet('tab-init-pot'),
26
- );
27
  }
28
 
29
 
@@ -89,14 +89,14 @@ class Loco_admin_init_InitPotController extends Loco_admin_bundle_BaseController
89
  $bytes += $fsize;
90
  }
91
  }
92
- $this->set( 'scan', new Loco_mvc_ViewParams( array (
93
  'bytes' => $bytes,
94
  'count' => $nfiles,
95
  'skip' => $nskip,
96
  'size' => Loco_mvc_FileParams::renderBytes($bytes),
97
  'large' => Loco_mvc_FileParams::renderBytes($max),
98
  'largest' => Loco_mvc_FileParams::renderBytes($largest),
99
- ) ) );
100
 
101
  // file metadata
102
  $this->set('pot', Loco_mvc_FileParams::create( $pot ) );
@@ -115,7 +115,7 @@ class Loco_admin_init_InitPotController extends Loco_admin_bundle_BaseController
115
  $target_path = $pot->getParent()->getRelativePath($content_dir);
116
 
117
  // hidden fields to pass through to Ajax endpoint
118
- $this->set( 'hidden', new Loco_mvc_ViewParams( array(
119
  'action' => 'loco_json',
120
  'route' => 'xgettext',
121
  'loco-nonce' => $this->setNonce('xgettext')->value,
@@ -124,7 +124,7 @@ class Loco_admin_init_InitPotController extends Loco_admin_bundle_BaseController
124
  'domain' => $project->getId(),
125
  'path' => $target_path,
126
  'name' => $pot->basename(),
127
- ) ) );
128
 
129
  // File system connect required if location not writable
130
  $relpath = $pot->getRelativePath($content_dir);
21
  * {@inheritdoc}
22
  */
23
  public function getHelpTabs(){
24
+ return [
25
  __('Overview','default') => $this->viewSnippet('tab-init-pot'),
26
+ ];
27
  }
28
 
29
 
89
  $bytes += $fsize;
90
  }
91
  }
92
+ $this->set( 'scan', new Loco_mvc_ViewParams( [
93
  'bytes' => $bytes,
94
  'count' => $nfiles,
95
  'skip' => $nskip,
96
  'size' => Loco_mvc_FileParams::renderBytes($bytes),
97
  'large' => Loco_mvc_FileParams::renderBytes($max),
98
  'largest' => Loco_mvc_FileParams::renderBytes($largest),
99
+ ] ) );
100
 
101
  // file metadata
102
  $this->set('pot', Loco_mvc_FileParams::create( $pot ) );
115
  $target_path = $pot->getParent()->getRelativePath($content_dir);
116
 
117
  // hidden fields to pass through to Ajax endpoint
118
+ $this->set( 'hidden', new Loco_mvc_ViewParams( [
119
  'action' => 'loco_json',
120
  'route' => 'xgettext',
121
  'loco-nonce' => $this->setNonce('xgettext')->value,
124
  'domain' => $project->getId(),
125
  'path' => $target_path,
126
  'name' => $pot->basename(),
127
+ ] ) );
128
 
129
  // File system connect required if location not writable
130
  $relpath = $pot->getRelativePath($content_dir);
src/admin/init/UploadController.php CHANGED
@@ -37,13 +37,13 @@ class Loco_admin_init_UploadController extends Loco_admin_bundle_BaseController
37
  // file upload requires a properly configured project
38
  $bundle = $this->getBundle();
39
  $project = $this->getProject();
40
- $fields = new Loco_mvc_HiddenFields( array(
41
  'path' => '',
42
  'auth' => 'upload',
43
  'type' => $bundle->getType(),
44
  'domain' => $project->getId(),
45
  'bundle' => $bundle->getHandle(),
46
- ) );
47
  $fields->setNonce('upload');
48
  $this->set('hidden',$fields);
49
  $this->prepareFsConnect('upload','');
@@ -55,32 +55,32 @@ class Loco_admin_init_UploadController extends Loco_admin_bundle_BaseController
55
  $locale = new Loco_Locale('zxx');
56
  $filechoice = $this->getProject()->initLocaleFiles($locale);
57
  //
58
- $locations = array();
59
  /* @var Loco_fs_LocaleFile $pofile */
60
  foreach( $filechoice as $pofile ){
61
  // initialize location type (system, etc..)
62
  $parent = new Loco_fs_LocaleDirectory( $pofile->dirname() );
63
  $typeId = $parent->getTypeId();
64
  if( ! isset($locations[$typeId]) ){
65
- $locations[$typeId] = new Loco_mvc_ViewParams( array(
66
  'label' => $parent->getTypeLabel($typeId),
67
- 'paths' => array(),
68
- ) );
69
  }
70
- $locations[$typeId]['paths'][] = new Loco_mvc_ViewParams( array(
71
  'parent' => Loco_mvc_FileParams::create($parent),
72
  'holder' => str_replace('zxx.po','{locale}</span>.po', $pofile->basename() ),
73
- ) );
74
  }
75
  // we don't know what the specifics will be until a location is chosen and a file is presented.
76
  $this->set('locale',get_locale());
77
  $this->set('locations', $locations );
78
  // file upload will be done via ajax if possible
79
  $settings = Loco_data_Settings::get();
80
- $this->set('js',new Loco_mvc_ViewParams( array (
81
  'multipart' => (bool) $settings->ajax_files,
82
- 'nonces' => array( 'upload' => $fields->getNonce() ),
83
- ) ) );
84
  $this->enqueueScript('upload');
85
  return $this->view('admin/init/upload');
86
  }
37
  // file upload requires a properly configured project
38
  $bundle = $this->getBundle();
39
  $project = $this->getProject();
40
+ $fields = new Loco_mvc_HiddenFields( [
41
  'path' => '',
42
  'auth' => 'upload',
43
  'type' => $bundle->getType(),
44
  'domain' => $project->getId(),
45
  'bundle' => $bundle->getHandle(),
46
+ ] );
47
  $fields->setNonce('upload');
48
  $this->set('hidden',$fields);
49
  $this->prepareFsConnect('upload','');
55
  $locale = new Loco_Locale('zxx');
56
  $filechoice = $this->getProject()->initLocaleFiles($locale);
57
  //
58
+ $locations = [];
59
  /* @var Loco_fs_LocaleFile $pofile */
60
  foreach( $filechoice as $pofile ){
61
  // initialize location type (system, etc..)
62
  $parent = new Loco_fs_LocaleDirectory( $pofile->dirname() );
63
  $typeId = $parent->getTypeId();
64
  if( ! isset($locations[$typeId]) ){
65
+ $locations[$typeId] = new Loco_mvc_ViewParams( [
66
  'label' => $parent->getTypeLabel($typeId),
67
+ 'paths' => [],
68
+ ] );
69
  }
70
+ $locations[$typeId]['paths'][] = new Loco_mvc_ViewParams( [
71
  'parent' => Loco_mvc_FileParams::create($parent),
72
  'holder' => str_replace('zxx.po','{locale}</span>.po', $pofile->basename() ),
73
+ ] );
74
  }
75
  // we don't know what the specifics will be until a location is chosen and a file is presented.
76
  $this->set('locale',get_locale());
77
  $this->set('locations', $locations );
78
  // file upload will be done via ajax if possible
79
  $settings = Loco_data_Settings::get();
80
+ $this->set('js',new Loco_mvc_ViewParams( [
81
  'multipart' => (bool) $settings->ajax_files,
82
+ 'nonces' => [ 'upload' => $fields->getNonce() ],
83
+ ] ) );
84
  $this->enqueueScript('upload');
85
  return $this->view('admin/init/upload');
86
  }
src/admin/list/BaseController.php CHANGED
@@ -4,7 +4,7 @@
4
  */
5
  abstract class Loco_admin_list_BaseController extends Loco_mvc_AdminController {
6
 
7
- private $bundles = array();
8
 
9
 
10
  /**
@@ -15,16 +15,16 @@ abstract class Loco_admin_list_BaseController extends Loco_mvc_AdminController {
15
  protected function bundleParam( Loco_package_Bundle $bundle ){
16
  $handle = $bundle->getHandle();
17
  $default = $bundle->getDefaultProject();
18
- return new Loco_mvc_ViewParams( array (
19
  'id' => $bundle->getId(),
20
  'name' => $bundle->getName(),
21
  'dflt' => $default ? $default->getDomain() : '--',
22
  'size' => count( $bundle ),
23
  'save' => $bundle->isConfigured(),
24
  'type' => $type = strtolower( $bundle->getType() ),
25
- 'view' => Loco_mvc_AdminRouter::generate( $type.'-view', array( 'bundle' => $handle ) ),
26
  'time' => $bundle->getLastUpdated(),
27
- ) );
28
  }
29
 
30
 
@@ -41,9 +41,9 @@ abstract class Loco_admin_list_BaseController extends Loco_mvc_AdminController {
41
  * {@inheritdoc}
42
  */
43
  public function getHelpTabs(){
44
- return array (
45
  __('Overview','default') => $this->viewSnippet('tab-list-bundles'),
46
- );
47
  }
48
 
49
 
@@ -53,9 +53,9 @@ abstract class Loco_admin_list_BaseController extends Loco_mvc_AdminController {
53
  public function render(){
54
 
55
  // breadcrumb is just the root
56
- $here = new Loco_admin_Navigation( array (
57
- new Loco_mvc_ViewParams( array( 'name' => $this->get('title') ) ),
58
- ) );
59
 
60
  /*/ tab between the types of bundles
61
  $types = array (
@@ -71,10 +71,10 @@ abstract class Loco_admin_list_BaseController extends Loco_mvc_AdminController {
71
  }
72
  */
73
 
74
- return $this->view( 'admin/list/bundles', array (
75
  'bundles' => $this->bundles,
76
  'breadcrumb' => $here,
77
- ) );
78
  }
79
 
80
 
4
  */
5
  abstract class Loco_admin_list_BaseController extends Loco_mvc_AdminController {
6
 
7
+ private $bundles = [];
8
 
9
 
10
  /**
15
  protected function bundleParam( Loco_package_Bundle $bundle ){
16
  $handle = $bundle->getHandle();
17
  $default = $bundle->getDefaultProject();
18
+ return new Loco_mvc_ViewParams( [
19
  'id' => $bundle->getId(),
20
  'name' => $bundle->getName(),
21
  'dflt' => $default ? $default->getDomain() : '--',
22
  'size' => count( $bundle ),
23
  'save' => $bundle->isConfigured(),
24
  'type' => $type = strtolower( $bundle->getType() ),
25
+ 'view' => Loco_mvc_AdminRouter::generate( $type.'-view', [ 'bundle' => $handle ] ),
26
  'time' => $bundle->getLastUpdated(),
27
+ ] );
28
  }
29
 
30
 
41
  * {@inheritdoc}
42
  */
43
  public function getHelpTabs(){
44
+ return [
45
  __('Overview','default') => $this->viewSnippet('tab-list-bundles'),
46
+ ];
47
  }
48
 
49
 
53
  public function render(){
54
 
55
  // breadcrumb is just the root
56
+ $here = new Loco_admin_Navigation( [
57
+ new Loco_mvc_ViewParams( [ 'name' => $this->get('title') ] ),
58
+ ] );
59
 
60
  /*/ tab between the types of bundles
61
  $types = array (
71
  }
72
  */
73
 
74
+ return $this->view( 'admin/list/bundles', [
75
  'bundles' => $this->bundles,
76
  'breadcrumb' => $here,
77
+ ] );
78
  }
79
 
80
 
src/admin/list/LocalesController.php CHANGED
@@ -20,9 +20,9 @@ class Loco_admin_list_LocalesController extends Loco_mvc_AdminController {
20
  * {@inheritdoc}
21
  */
22
  public function getHelpTabs(){
23
- return array (
24
  __('Overview','default') => $this->viewSnippet('tab-list-locales'),
25
- );
26
  }
27
 
28
 
@@ -34,8 +34,8 @@ class Loco_admin_list_LocalesController extends Loco_mvc_AdminController {
34
 
35
  $this->set( 'title', __( 'Installed languages', 'loco-translate' ) );
36
 
37
- $used = array();
38
- $locales = array();
39
  $api = new Loco_api_WordPressTranslations;
40
 
41
  $active = get_locale();
@@ -65,8 +65,8 @@ class Loco_admin_list_LocalesController extends Loco_mvc_AdminController {
65
  if( $locale->isValid() ){
66
  $tag = (string) $locale;
67
  $finder->addLocale($locale);
68
- $args = array( 'locale' => $tag );
69
- $locales[$tag] = new Loco_mvc_ViewParams( array(
70
  'nfiles' => 0,
71
  'time' => 0,
72
  'lcode' => $tag,
@@ -75,7 +75,7 @@ class Loco_admin_list_LocalesController extends Loco_mvc_AdminController {
75
  'href' => Loco_mvc_AdminRouter::generate('lang-view',$args),
76
  'used' => isset($used[$tag]) ? implode( ', ', $used[$tag] ) : ( $multisite ? '--' : '' ),
77
  'active' => $active === $tag,
78
- ) );
79
  }
80
  }
81
  $this->set('locales', $locales );
20
  * {@inheritdoc}
21
  */
22
  public function getHelpTabs(){
23
+ return [
24
  __('Overview','default') => $this->viewSnippet('tab-list-locales'),
25
+ ];
26
  }
27
 
28
 
34
 
35
  $this->set( 'title', __( 'Installed languages', 'loco-translate' ) );
36
 
37
+ $used = [];
38
+ $locales = [];
39
  $api = new Loco_api_WordPressTranslations;
40
 
41
  $active = get_locale();
65
  if( $locale->isValid() ){
66
  $tag = (string) $locale;
67
  $finder->addLocale($locale);
68
+ $args = [ 'locale' => $tag ];
69
+ $locales[$tag] = new Loco_mvc_ViewParams( [
70
  'nfiles' => 0,
71
  'time' => 0,
72
  'lcode' => $tag,
75
  'href' => Loco_mvc_AdminRouter::generate('lang-view',$args),
76
  'used' => isset($used[$tag]) ? implode( ', ', $used[$tag] ) : ( $multisite ? '--' : '' ),
77
  'active' => $active === $tag,
78
+ ] );
79
  }
80
  }
81
  $this->set('locales', $locales );
src/ajax/ApisController.php CHANGED
@@ -22,14 +22,14 @@ class Loco_ajax_ApisController extends Loco_mvc_AjaxController {
22
  $modal->set('apis',$apis);
23
  // help buttons
24
  $locale = $this->get('locale');
25
- $modal->set( 'help', new Loco_mvc_ViewParams( array (
26
  'text' => __('Help','loco-translate'),
27
  'href' => apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/providers'),
28
- ) ) );
29
- $modal->set('prof', new Loco_mvc_ViewParams( array (
30
  'text' => __('Need a human?','loco-translate'),
31
  'href' => apply_filters('loco_external','https://localise.biz/wordpress/translation?l='.$locale),
32
- ) ) );
33
  // render auto-translate modal or prompt for configuration
34
  if( $apis ){
35
  $html = $modal->render('ajax/modal-apis-batch');
@@ -90,20 +90,4 @@ class Loco_ajax_ApisController extends Loco_mvc_AjaxController {
90
  return parent::render();
91
  }
92
 
93
-
94
- /**
95
- * Built-in Yandex API v2 support.
96
- * https://cloud.yandex.com/docs/translate/api-ref/
97
- *
98
- * @param string[] input strings
99
- * @param Loco_Locale target locale for translations
100
- * @param array our own api configuration
101
- * @return string[] output strings
102
- * @throws Loco_error_Exception
103
- */
104
- public function filter_loco_api_translate_yandex( array $sources, Loco_Locale $locale, array $config ){
105
- $client = new Loco_api_YandexClient($config);
106
- return $client->translate($sources,$locale);
107
- }
108
-
109
  }
22
  $modal->set('apis',$apis);
23
  // help buttons
24
  $locale = $this->get('locale');
25
+ $modal->set( 'help', new Loco_mvc_ViewParams( [
26
  'text' => __('Help','loco-translate'),
27
  'href' => apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/providers'),
28
+ ] ) );
29
+ $modal->set('prof', new Loco_mvc_ViewParams( [
30
  'text' => __('Need a human?','loco-translate'),
31
  'href' => apply_filters('loco_external','https://localise.biz/wordpress/translation?l='.$locale),
32
+ ] ) );
33
  // render auto-translate modal or prompt for configuration
34
  if( $apis ){
35
  $html = $modal->render('ajax/modal-apis-batch');
90
  return parent::render();
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
src/ajax/DiffController.php CHANGED
@@ -21,10 +21,10 @@ class Loco_ajax_DiffController extends Loco_mvc_AjaxController {
21
  $rhs = new Loco_fs_File( $post->rhs ); $rhs->normalize($dir);
22
 
23
  // avoid diffing non Gettext source files
24
- $exts = array_flip( array( 'pot', 'pot~', 'po', 'po~' ) );
25
 
26
  /* @var $file Loco_fs_File */
27
- foreach( array($lhs,$rhs) as $file ){
28
  if( ! $file->exists() ){
29
  throw new InvalidArgumentException('File paths must exist');
30
  }
21
  $rhs = new Loco_fs_File( $post->rhs ); $rhs->normalize($dir);
22
 
23
  // avoid diffing non Gettext source files
24
+ $exts = array_flip( [ 'pot', 'pot~', 'po', 'po~' ] );
25
 
26
  /* @var $file Loco_fs_File */
27
+ foreach( [$lhs,$rhs] as $file ){
28
  if( ! $file->exists() ){
29
  throw new InvalidArgumentException('File paths must exist');
30
  }
src/ajax/FsConnectController.php CHANGED
@@ -91,7 +91,7 @@ class Loco_ajax_FsConnectController extends Loco_mvc_AjaxController {
91
  $post = $this->validate();
92
  $type = $post->auth;
93
  $func = 'authorize'.ucfirst($type);
94
- $auth = array( $this, $func );
95
  if( ! is_callable($auth) ){
96
  throw new Loco_error_Exception('Unexpected file operation');
97
  }
@@ -99,7 +99,7 @@ class Loco_ajax_FsConnectController extends Loco_mvc_AjaxController {
99
  $file = new Loco_fs_File( $post->path );
100
  $base = loco_constant('WP_CONTENT_DIR');
101
  $file->normalize($base);
102
- $args = array($file);
103
  // some auth methods also require a destination/target (move,copy,etc..)
104
  if( $dest = $post->dest ){
105
  $file = new Loco_fs_File($dest);
91
  $post = $this->validate();
92
  $type = $post->auth;
93
  $func = 'authorize'.ucfirst($type);
94
+ $auth = [ $this, $func ];
95
  if( ! is_callable($auth) ){
96
  throw new Loco_error_Exception('Unexpected file operation');
97
  }
99
  $file = new Loco_fs_File( $post->path );
100
  $base = loco_constant('WP_CONTENT_DIR');
101
  $file->normalize($base);
102
+ $args = [$file];
103
  // some auth methods also require a destination/target (move,copy,etc..)
104
  if( $dest = $post->dest ){
105
  $file = new Loco_fs_File($dest);
src/ajax/FsReferenceController.php CHANGED
@@ -109,7 +109,7 @@ class Loco_ajax_FsReferenceController extends Loco_ajax_common_BundleController
109
  // validate allowed source file types
110
  $conf = Loco_data_Settings::get();
111
  $ext = strtolower( $srcfile->extension() );
112
- $allow = array_merge( array('php','js'), $conf->php_alias, $conf->jsx_alias );
113
  if( ! in_array($ext,$allow,true) ){
114
  throw new InvalidArgumentException('File extension disallowed, '.$ext );
115
  }
@@ -122,7 +122,7 @@ class Loco_ajax_FsReferenceController extends Loco_ajax_common_BundleController
122
  $this->set('path', $srcfile->getRelativePath( loco_constant('WP_CONTENT_DIR') ) );
123
 
124
  // source code will be HTML-tokenized into multiple lines
125
- $code = array();
126
 
127
  // observe the same size limits for source highlighting as for string extraction as tokenizing will use the same amount of juice
128
  $maxbytes = wp_convert_hr_to_bytes( $conf->max_php_size );
@@ -157,7 +157,7 @@ class Loco_ajax_FsReferenceController extends Loco_ajax_common_BundleController
157
  else {
158
  // scalar symbol will always start on the line that the previous token ended on
159
  $clss = 'T_NONE';
160
- $lines = array( $tok );
161
  $startline = $thisline;
162
  }
163
  // token can span multiple lines, so include only bytes on required line[s]
109
  // validate allowed source file types
110
  $conf = Loco_data_Settings::get();
111
  $ext = strtolower( $srcfile->extension() );
112
+ $allow = array_merge( ['php','js'], $conf->php_alias, $conf->jsx_alias );
113
  if( ! in_array($ext,$allow,true) ){
114
  throw new InvalidArgumentException('File extension disallowed, '.$ext );
115
  }
122
  $this->set('path', $srcfile->getRelativePath( loco_constant('WP_CONTENT_DIR') ) );
123
 
124
  // source code will be HTML-tokenized into multiple lines
125
+ $code = [];
126
 
127
  // observe the same size limits for source highlighting as for string extraction as tokenizing will use the same amount of juice
128
  $maxbytes = wp_convert_hr_to_bytes( $conf->max_php_size );
157
  else {
158
  // scalar symbol will always start on the line that the previous token ended on
159
  $clss = 'T_NONE';
160
+ $lines = [ $tok ];
161
  $startline = $thisline;
162
  }
163
  // token can span multiple lines, so include only bytes on required line[s]
src/ajax/MsginitController.php CHANGED
@@ -109,7 +109,7 @@ class Loco_ajax_MsginitController extends Loco_ajax_common_BundleController {
109
  }
110
 
111
  // Let template define Project-Id-Version, else set header to current project name
112
- $headers = array();
113
  $vers = $data->getHeaders()->{'Project-Id-Version'};
114
  if( ! $vers || 'PACKAGE VERSION' === $vers ){
115
  $headers['Project-Id-Version'] = $project->getName();
@@ -152,21 +152,21 @@ class Loco_ajax_MsginitController extends Loco_ajax_common_BundleController {
152
  }
153
 
154
  // return debugging information, used in tests.
155
- $this->set('debug',new Loco_mvc_ViewParams( array(
156
  'poname' => $pofile->basename(),
157
  'source' => $potfile ? $potfile->basename() : '',
158
- ) ) );
159
 
160
  // push recent items on file creation
161
  Loco_data_RecentItems::get()->pushBundle($bundle)->persist();
162
 
163
  // front end will redirect to the editor
164
  $type = strtolower( $this->get('type') );
165
- $this->set( 'redirect', Loco_mvc_AdminRouter::generate( sprintf('%s-file-edit',$type), array (
166
  'path' => $pofile->getRelativePath($base),
167
  'bundle' => $bundle->getHandle(),
168
  'domain' => $project->getId(),
169
- ) ) );
170
 
171
  return parent::render();
172
  }
109
  }
110
 
111
  // Let template define Project-Id-Version, else set header to current project name
112
+ $headers = [];
113
  $vers = $data->getHeaders()->{'Project-Id-Version'};
114
  if( ! $vers || 'PACKAGE VERSION' === $vers ){
115
  $headers['Project-Id-Version'] = $project->getName();
152
  }
153
 
154
  // return debugging information, used in tests.
155
+ $this->set('debug',new Loco_mvc_ViewParams( [
156
  'poname' => $pofile->basename(),
157
  'source' => $potfile ? $potfile->basename() : '',
158
+ ] ) );
159
 
160
  // push recent items on file creation
161
  Loco_data_RecentItems::get()->pushBundle($bundle)->persist();
162
 
163
  // front end will redirect to the editor
164
  $type = strtolower( $this->get('type') );
165
+ $this->set( 'redirect', Loco_mvc_AdminRouter::generate( sprintf('%s-file-edit',$type), [
166
  'path' => $pofile->getRelativePath($base),
167
  'bundle' => $bundle->getHandle(),
168
  'domain' => $project->getId(),
169
+ ] ) );
170
 
171
  return parent::render();
172
  }
src/ajax/SyncController.php CHANGED
@@ -59,7 +59,7 @@ class Loco_ajax_SyncController extends Loco_mvc_AjaxController {
59
 
60
  // defaults: no msgstr and no json
61
  $translate = false;
62
- $syncjsons = array();
63
 
64
  // Parse existing POT for source
65
  if( $potfile ){
59
 
60
  // defaults: no msgstr and no json
61
  $translate = false;
62
+ $syncjsons = [];
63
 
64
  // Parse existing POT for source
65
  if( $potfile ){
src/ajax/UploadController.php CHANGED
@@ -78,10 +78,10 @@ class Loco_ajax_UploadController extends Loco_ajax_common_BundleController {
78
 
79
  // Redirect to edit this PO. Sync may be required and we're not doing automatically here.
80
  $type = strtolower( $this->get('type') );
81
- return Loco_mvc_AdminRouter::generate( sprintf('%s-file-edit',$type), array(
82
  'path' => $pofile->getRelativePath($base),
83
  'bundle' => $bundle->getHandle(),
84
  'domain' => $project->getId(),
85
- ) );
86
  }
87
  }
78
 
79
  // Redirect to edit this PO. Sync may be required and we're not doing automatically here.
80
  $type = strtolower( $this->get('type') );
81
+ return Loco_mvc_AdminRouter::generate( sprintf('%s-file-edit',$type), [
82
  'path' => $pofile->getRelativePath($base),
83
  'bundle' => $bundle->getHandle(),
84
  'domain' => $project->getId(),
85
+ ] );
86
  }
87
  }
src/ajax/XgettextController.php CHANGED
@@ -51,11 +51,11 @@ class Loco_ajax_XgettextController extends Loco_ajax_common_BundleController {
51
 
52
  // set response data for debugging
53
  if( loco_debugging() ){
54
- $this->set( 'debug', array (
55
  'potname' => $potfile->basename(),
56
  'potsize' => $potsize,
57
  'total' => $ext->getTotal(),
58
- ) );
59
  }
60
 
61
  // push recent items on file creation
@@ -73,9 +73,9 @@ class Loco_ajax_XgettextController extends Loco_ajax_common_BundleController {
73
 
74
  // redirect front end to bundle view. Discourages manual editing of template
75
  $type = strtolower( $bundle->getType() );
76
- $href = Loco_mvc_AdminRouter::generate( sprintf('%s-view',$type), array(
77
  'bundle' => $bundle->getHandle(),
78
- ) );
79
  $hash = '#loco-'.$project->getId();
80
  $this->set( 'redirect', $href.$hash );
81
 
51
 
52
  // set response data for debugging
53
  if( loco_debugging() ){
54
+ $this->set( 'debug', [
55
  'potname' => $potfile->basename(),
56
  'potsize' => $potsize,
57
  'total' => $ext->getTotal(),
58
+ ] );
59
  }
60
 
61
  // push recent items on file creation
73
 
74
  // redirect front end to bundle view. Discourages manual editing of template
75
  $type = strtolower( $bundle->getType() );
76
+ $href = Loco_mvc_AdminRouter::generate( sprintf('%s-view',$type), [
77
  'bundle' => $bundle->getHandle(),
78
+ ] );
79
  $hash = '#loco-'.$project->getId();
80
  $this->set( 'redirect', $href.$hash );
81
 
src/api/Providers.php CHANGED
@@ -19,35 +19,30 @@ abstract class Loco_api_Providers {
19
  */
20
  public static function builtin(){
21
  $settings = Loco_data_Settings::get();
22
- return array (
23
- array (
24
  'id' => 'deepl',
25
  'name' => 'DeepL Translator',
26
  'key' => $settings->offsetGet('deepl_api_key'),
27
  'url' => $settings->offsetGet('deepl_api_url'),
28
- ),
29
- array (
30
  'id' => 'google',
31
  'name' => 'Google Translate',
32
  'key' => $settings->offsetGet('google_api_key'),
33
- ),
34
- array (
35
  'id' => 'microsoft',
36
  'name' => 'Microsoft Translator',
37
  'key' => $settings->offsetGet('microsoft_api_key'),
38
  'region' => $settings->offsetGet('microsoft_api_region'),
39
- ),
40
- array (
41
- 'id' => 'yandex',
42
- 'name' => 'Yandex.Translate',
43
- 'key' => $settings->offsetGet('yandex_api_key'),
44
- ),
45
- array (
46
  'id' => 'lecto',
47
  'name' => 'Lecto AI',
48
  'key' => $settings->offsetGet('lecto_api_key'),
49
- ),
50
- );
51
  }
52
 
53
 
@@ -56,7 +51,7 @@ abstract class Loco_api_Providers {
56
  * @return array[]
57
  */
58
  public static function configured(){
59
- return self::sort( array_filter( self::export(), array(__CLASS__,'filterConfigured') ) );
60
  }
61
 
62
 
@@ -87,7 +82,7 @@ abstract class Loco_api_Providers {
87
  * @return array
88
  */
89
  public static function sort( array $apis ){
90
- usort( $apis, array(__CLASS__,'compareNames') );
91
  return $apis;
92
  }
93
 
19
  */
20
  public static function builtin(){
21
  $settings = Loco_data_Settings::get();
22
+ return [
23
+ [
24
  'id' => 'deepl',
25
  'name' => 'DeepL Translator',
26
  'key' => $settings->offsetGet('deepl_api_key'),
27
  'url' => $settings->offsetGet('deepl_api_url'),
28
+ ],
29
+ [
30
  'id' => 'google',
31
  'name' => 'Google Translate',
32
  'key' => $settings->offsetGet('google_api_key'),
33
+ ],
34
+ [
35
  'id' => 'microsoft',
36
  'name' => 'Microsoft Translator',
37
  'key' => $settings->offsetGet('microsoft_api_key'),
38
  'region' => $settings->offsetGet('microsoft_api_region'),
39
+ ],
40
+ [
 
 
 
 
 
41
  'id' => 'lecto',
42
  'name' => 'Lecto AI',
43
  'key' => $settings->offsetGet('lecto_api_key'),
44
+ ],
45
+ ];
46
  }
47
 
48
 
51
  * @return array[]
52
  */
53
  public static function configured(){
54
+ return self::sort( array_filter( self::export(), [__CLASS__,'filterConfigured'] ) );
55
  }
56
 
57
 
82
  * @return array
83
  */
84
  public static function sort( array $apis ){
85
+ usort( $apis, [__CLASS__,'compareNames'] );
86
  return $apis;
87
  }
88
 
src/api/WordPressFileSystem.php CHANGED
@@ -27,13 +27,13 @@ class Loco_api_WordPressFileSystem {
27
  * Credentials posted into the API
28
  * @var array
29
  */
30
- private $creds_in = array();
31
 
32
  /**
33
  * Credentials returned from the API
34
  * @var array
35
  */
36
- private $creds_out = array();
37
 
38
 
39
  /**
@@ -203,7 +203,7 @@ class Loco_api_WordPressFileSystem {
203
  // else begin new auth
204
  $this->fs = null;
205
  $this->form = '';
206
- $this->creds_out = array();
207
 
208
  // observe settings held temporarily in session
209
  try {
@@ -211,7 +211,7 @@ class Loco_api_WordPressFileSystem {
211
  if( isset($session['loco-fs']) ){
212
  $creds = $session['loco-fs'];
213
  if( is_array($creds) && $this->tryCredentials($creds,$file) ){
214
- $this->creds_in = array();
215
  return true;
216
  }
217
  }
@@ -221,7 +221,7 @@ class Loco_api_WordPressFileSystem {
221
  }
222
 
223
  $post = Loco_mvc_PostParams::get();
224
- $dflt = array( 'hostname' => '', 'username' => '', 'password' => '', 'public_key' => '', 'private_key' => '', 'connection_type' => '', '_fs_nonce' => '' );
225
  $this->creds_in = array_intersect_key( $post->getArrayCopy(), $dflt );
226
 
227
  // deliberately circumventing call to `get_filesystem_method`
@@ -261,7 +261,7 @@ class Loco_api_WordPressFileSystem {
261
  $type = apply_filters( 'filesystem_method', $type, $post->getArrayCopy(), $context, true );
262
 
263
  // the only params we'll pass into form will be those used by the ajax fsConnect end point
264
- $extra = array( 'loco-nonce', 'path', 'auth', 'dest' );
265
 
266
  // capture WordPress output during negotiation.
267
  $buffer = Loco_output_Buffer::start();
@@ -390,7 +390,7 @@ class Loco_api_WordPressFileSystem {
390
  $bundle = Loco_package_Bundle::fromFile($file);
391
  if( $bundle instanceof Loco_package_Bundle ){
392
  $handle = $bundle->getHandle();
393
- $option = (array) get_site_option( "auto_update_{$type}s", array() );
394
  // var_dump( compact('handle','option') );
395
  if( ! in_array($handle,$option,true) ){
396
  $enabled = false;
27
  * Credentials posted into the API
28
  * @var array
29
  */
30
+ private $creds_in = [];
31
 
32
  /**
33
  * Credentials returned from the API
34
  * @var array
35
  */
36
+ private $creds_out = [];
37
 
38
 
39
  /**
203
  // else begin new auth
204
  $this->fs = null;
205
  $this->form = '';
206
+ $this->creds_out = [];
207
 
208
  // observe settings held temporarily in session
209
  try {
211
  if( isset($session['loco-fs']) ){
212
  $creds = $session['loco-fs'];
213
  if( is_array($creds) && $this->tryCredentials($creds,$file) ){
214
+ $this->creds_in = [];
215
  return true;
216
  }
217
  }
221
  }
222
 
223
  $post = Loco_mvc_PostParams::get();
224
+ $dflt = [ 'hostname' => '', 'username' => '', 'password' => '', 'public_key' => '', 'private_key' => '', 'connection_type' => '', '_fs_nonce' => '' ];
225
  $this->creds_in = array_intersect_key( $post->getArrayCopy(), $dflt );
226
 
227
  // deliberately circumventing call to `get_filesystem_method`
261
  $type = apply_filters( 'filesystem_method', $type, $post->getArrayCopy(), $context, true );
262
 
263
  // the only params we'll pass into form will be those used by the ajax fsConnect end point
264
+ $extra = [ 'loco-nonce', 'path', 'auth', 'dest' ];
265
 
266
  // capture WordPress output during negotiation.
267
  $buffer = Loco_output_Buffer::start();
390
  $bundle = Loco_package_Bundle::fromFile($file);
391
  if( $bundle instanceof Loco_package_Bundle ){
392
  $handle = $bundle->getHandle();
393
+ $option = (array) get_site_option( "auto_update_{$type}s", [] );
394
  // var_dump( compact('handle','option') );
395
  if( ! in_array($handle,$option,true) ){
396
  $enabled = false;
src/api/WordPressTranslations.php CHANGED
@@ -49,7 +49,7 @@ class Loco_api_WordPressTranslations {
49
  public function getAvailableCore(){
50
  $locales = $this->locales;
51
  if( is_null($locales) ){
52
- $locales = array();
53
  // get official locales from API if we have network
54
  $cached = $this->wp_get_available_translations();
55
  if( is_array($cached) && $cached ){
49
  public function getAvailableCore(){
50
  $locales = $this->locales;
51
  if( is_null($locales) ){
52
+ $locales = [];
53
  // get official locales from API if we have network
54
  $cached = $this->wp_get_available_translations();
55
  if( is_array($cached) && $cached ){
src/api/YandexClient.php DELETED
@@ -1,85 +0,0 @@
1
- <?php
2
- /**
3
- * Yandex Translation API v2
4
- */
5
- class Loco_api_YandexClient {
6
-
7
- /**
8
- * @var string
9
- */
10
- private $auth;
11
-
12
- /**
13
- * @var string
14
- */
15
- private $format;
16
-
17
-
18
- public function __construct( array $config ){
19
- if( 'html'=== $config['type'] ){
20
- $this->format = 'HTML';
21
- }
22
- else {
23
- $this->format = 'PLAIN_TEXT';
24
- }
25
- $this->auth = 'Api-Key '.$config['key'];
26
- }
27
-
28
-
29
- /**
30
- * https://cloud.yandex.com/docs/translate/api-ref/Translation/translate
31
- * @param string[]
32
- * @param Loco_Locale already verified/mapped in front end
33
- * @return string[]
34
- */
35
- public function translate( array $sources, Loco_Locale $locale ){
36
- $json = json_encode( array (
37
- 'sourceLanguageCode' => 'en',
38
- 'targetLanguageCode' => (string) $locale,
39
- 'format' => $this->format,
40
- 'texts' => $sources,
41
- ) );
42
- $response = wp_remote_post('https://translate.api.cloud.yandex.net/translate/v2/translate',array(
43
- 'body' => $json,
44
- 'headers' => array (
45
- 'user-agent' => 'Loco Translate/'.loco_plugin_version().'; WordPress/'.$GLOBALS['wp_version'],
46
- 'content-type' => 'application/json',
47
- 'content-length' => strlen($json),
48
- 'authorization' => $this->auth,
49
- ),
50
- ));
51
- if( $response instanceof WP_Error ){
52
- $message = 'Unknown error';
53
- foreach( $response->get_error_messages() as $message ){
54
- Loco_error_AdminNotices::debug('Yandex error: '.$message);
55
- }
56
- throw new Loco_error_Exception( $message );
57
- }
58
- if( ! is_array($response) ){
59
- throw new Loco_error_Exception('Expected array response from WordPress HTTP API');
60
- }
61
- // parse response and error accordingly
62
- $json = $response['body'];
63
- $data = json_decode($json,true);
64
- if( 200 !== $response['response']['code'] ){
65
- Loco_error_AdminNotices::debug( 'Yandex error response: '.$json );
66
- if( is_array($data) && array_key_exists('message',$data) ){
67
- $message = $data['message'];
68
- }
69
- else {
70
- $message = $response['response']['message'];
71
- }
72
- throw new Loco_error_Exception('Yandex.Translate: Error '.$response['response']['code'].': '.$message);
73
- }
74
- // should have json response like {translations:[ {text:''},...]}
75
- $targets = array();
76
- foreach( $sources as $i => $text ){
77
- if( isset($data['translations'][$i]) ){
78
- $text = $data['translations'][$i]['text'];
79
- }
80
- $targets[$i] = $text;
81
- }
82
- return $targets;
83
- }
84
-
85
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/cli/Commands.php CHANGED
@@ -120,9 +120,9 @@ class Loco_cli_Commands {
120
  Loco_cli_FetchCommand::run (
121
  Loco_cli_Utils::collectProjects( isset($args[0]) ? $args[0] : '' ),
122
  Loco_cli_Utils::collectLocales( isset($opts['locale']) ? $opts['locale'] : '' ),
123
- array (
124
  'trunk' => Loco_cli_Utils::bool($opts,'trunk')
125
- )
126
  );
127
  }
128
  catch( Loco_error_Exception $e ){
120
  Loco_cli_FetchCommand::run (
121
  Loco_cli_Utils::collectProjects( isset($args[0]) ? $args[0] : '' ),
122
  Loco_cli_Utils::collectLocales( isset($opts['locale']) ? $opts['locale'] : '' ),
123
+ [
124
  'trunk' => Loco_cli_Utils::bool($opts,'trunk')
125
+ ]
126
  );
127
  }
128
  catch( Loco_error_Exception $e ){
src/cli/ExtractCommand.php CHANGED
@@ -45,7 +45,7 @@ abstract class Loco_cli_ExtractCommand {
45
  $suggest = ceil( $ext->getMaxPhpSize() / 1024 );
46
  WP_CLI::warning(sprintf('%u source files skipped over %s. Consider running with --maxsize=%uK',count($list),$current,$suggest) );
47
  foreach( $list as $file ) {
48
- $f = new Loco_mvc_FileParams(array(),$file);
49
  Loco_cli_Utils::debug('%s (%s)', $f->relpath, $f->size );
50
  }
51
  }
45
  $suggest = ceil( $ext->getMaxPhpSize() / 1024 );
46
  WP_CLI::warning(sprintf('%u source files skipped over %s. Consider running with --maxsize=%uK',count($list),$current,$suggest) );
47
  foreach( $list as $file ) {
48
+ $f = new Loco_mvc_FileParams([],$file);
49
  Loco_cli_Utils::debug('%s (%s)', $f->relpath, $f->size );
50
  }
51
  }
src/cli/FetchCommand.php CHANGED
@@ -37,7 +37,7 @@ abstract class Loco_cli_FetchCommand {
37
  $info = $project->getBundle()->getHeaderInfo();
38
  $version = $info->Version;
39
  // Currently only supporting WordPress community translation sources.
40
- $args = array( 'version' => $version );
41
  if( 'core' !== $type ){
42
  $type.= 's';
43
  if( $project->getSlug() !== $domain ){
@@ -51,7 +51,7 @@ abstract class Loco_cli_FetchCommand {
51
  $result = $wp->apiGet($type,$args);
52
 
53
  // pre-index installable language packs
54
- $packages = array();
55
  foreach( $result['translations'] as $data ){
56
  $packages[$data['language']] = $data['package'];
57
  }
@@ -104,12 +104,12 @@ abstract class Loco_cli_FetchCommand {
104
  $slug = sprintf('%u.%u.x',$major,$minor);
105
  }
106
  // Core projects are sub projects. plugins and themes don't have this
107
- $map = array (
108
  'default.' => '',
109
  'default.admin' => '/admin',
110
  'default.admin-network' => '/admin/network',
111
  'continents-cities' => '/cc',
112
- );
113
  $slug .= $map[ $project->getId() ];
114
  $url = 'https://translate.wordpress.org/projects/wp/'.$slug.'/'.$team.'/'.$variant.'/export-translations/?format=po';
115
  }
@@ -144,11 +144,11 @@ abstract class Loco_cli_FetchCommand {
144
 
145
  // keep translations if file already exists in this location.
146
  $pofile = $project->initLocaleFile($dir,$locale);
147
- $info = new Loco_mvc_FileParams( array(), $pofile );
148
  Loco_cli_Utils::debug('Saving %s..', $info->relpath );
149
  $compiler = new Loco_gettext_Compiler($pofile);
150
  if( $pofile->exists() ){
151
- $info = new Loco_mvc_FileParams( array(), $pofile );
152
  Loco_cli_Utils::debug('PO already exists at %s (%s), merging..',$info->relpath,$info->size);
153
  $original = Loco_gettext_Data::load($pofile);
154
  $matcher = new Loco_gettext_Matcher;
37
  $info = $project->getBundle()->getHeaderInfo();
38
  $version = $info->Version;
39
  // Currently only supporting WordPress community translation sources.
40
+ $args = [ 'version' => $version ];
41
  if( 'core' !== $type ){
42
  $type.= 's';
43
  if( $project->getSlug() !== $domain ){
51
  $result = $wp->apiGet($type,$args);
52
 
53
  // pre-index installable language packs
54
+ $packages = [];
55
  foreach( $result['translations'] as $data ){
56
  $packages[$data['language']] = $data['package'];
57
  }
104
  $slug = sprintf('%u.%u.x',$major,$minor);
105
  }
106
  // Core projects are sub projects. plugins and themes don't have this
107
+ $map = [
108
  'default.' => '',
109
  'default.admin' => '/admin',
110
  'default.admin-network' => '/admin/network',
111
  'continents-cities' => '/cc',
112
+ ];
113
  $slug .= $map[ $project->getId() ];
114
  $url = 'https://translate.wordpress.org/projects/wp/'.$slug.'/'.$team.'/'.$variant.'/export-translations/?format=po';
115
  }
144
 
145
  // keep translations if file already exists in this location.
146
  $pofile = $project->initLocaleFile($dir,$locale);
147
+ $info = new Loco_mvc_FileParams( [], $pofile );
148
  Loco_cli_Utils::debug('Saving %s..', $info->relpath );
149
  $compiler = new Loco_gettext_Compiler($pofile);
150
  if( $pofile->exists() ){
151
+ $info = new Loco_mvc_FileParams( [], $pofile );
152
  Loco_cli_Utils::debug('PO already exists at %s (%s), merging..',$info->relpath,$info->size);
153
  $original = Loco_gettext_Data::load($pofile);
154
  $matcher = new Loco_gettext_Matcher;
src/cli/SyncCommand.php CHANGED
@@ -148,7 +148,7 @@ abstract class Loco_cli_SyncCommand {
148
  $jsons = $compiler->writeJson($project,$po);
149
  foreach( $jsons as $file ){
150
  $compiled++;
151
- $param = new Loco_mvc_FileParams(array(),$file);
152
  Loco_cli_Utils::debug('+ %u bytes written to %s',$param->size,$param->name);
153
  }
154
  // Done compile of this set
148
  $jsons = $compiler->writeJson($project,$po);
149
  foreach( $jsons as $file ){
150
  $compiled++;
151
+ $param = new Loco_mvc_FileParams([],$file);
152
  Loco_cli_Utils::debug('+ %u bytes written to %s',$param->size,$param->name);
153
  }
154
  // Done compile of this set
src/cli/Utils.php CHANGED
@@ -11,7 +11,7 @@ abstract class Loco_cli_Utils {
11
  * @return Loco_package_Project[]
12
  */
13
  public static function collectProjects( $filter ){
14
- $projects = array();
15
  $filter = strtolower($filter);
16
  // bundle type filter
17
  if( 'plugins' === $filter ){
@@ -23,11 +23,11 @@ abstract class Loco_cli_Utils {
23
  $filter = null;
24
  }
25
  else if( 'core' === $filter ) {
26
- $bundles = array( Loco_package_Core::create() );
27
  $filter = null;
28
  }
29
  else {
30
- $bundles = array( Loco_package_Core::create() );
31
  $bundles = array_merge( $bundles, Loco_package_Plugin::getAll() );
32
  $bundles = array_merge( $bundles, Loco_package_Theme::getAll() );
33
  }
@@ -53,7 +53,7 @@ abstract class Loco_cli_Utils {
53
  * @return Loco_Locale[]
54
  */
55
  public static function collectLocales( $tags ){
56
- $locales = array();
57
  if( '' !== $tags ){
58
  $api = new Loco_api_WordPressTranslations;
59
  foreach( preg_split('/[\\s,;]+/i',$tags,-1,PREG_SPLIT_NO_EMPTY) as $tag ){
@@ -79,7 +79,7 @@ abstract class Loco_cli_Utils {
79
  * @param string[][] data rows to print
80
  */
81
  public static function tabulate( array $t ){
82
- $w = array();
83
  foreach( $t as $y => $row ){
84
  foreach( $row as $x => $value ){
85
  $width = mb_strlen($value,'UTF-8');
@@ -87,7 +87,7 @@ abstract class Loco_cli_Utils {
87
  }
88
  }
89
  foreach( $t as $y => $row ){
90
- $line = array();
91
  foreach( $w as $x => $width ){
92
  $value = isset($row[$x]) ? $row[$x] : '';
93
  $value = str_pad($value,$width,' ',STR_PAD_RIGHT);
@@ -102,12 +102,12 @@ abstract class Loco_cli_Utils {
102
  * Prints file listing to stdout
103
  */
104
  public static function tabulateFiles(){
105
- $t = array();
106
  /* @var Loco_fs_File $file */
107
  foreach( func_get_args() as $file ){
108
  if( $file instanceof Loco_fs_File && $file->exists() ){
109
- $f = new Loco_mvc_FileParams(array(),$file);
110
- $t[] = array( $f->owner, $f->group, $f->smode, $f->relpath );
111
  }
112
  }
113
  self::tabulate($t);
11
  * @return Loco_package_Project[]
12
  */
13
  public static function collectProjects( $filter ){
14
+ $projects = [];
15
  $filter = strtolower($filter);
16
  // bundle type filter
17
  if( 'plugins' === $filter ){
23
  $filter = null;
24
  }
25
  else if( 'core' === $filter ) {
26
+ $bundles = [ Loco_package_Core::create() ];
27
  $filter = null;
28
  }
29
  else {
30
+ $bundles = [ Loco_package_Core::create() ];
31
  $bundles = array_merge( $bundles, Loco_package_Plugin::getAll() );
32
  $bundles = array_merge( $bundles, Loco_package_Theme::getAll() );
33
  }
53
  * @return Loco_Locale[]
54
  */
55
  public static function collectLocales( $tags ){
56
+ $locales = [];
57
  if( '' !== $tags ){
58
  $api = new Loco_api_WordPressTranslations;
59
  foreach( preg_split('/[\\s,;]+/i',$tags,-1,PREG_SPLIT_NO_EMPTY) as $tag ){
79
  * @param string[][] data rows to print
80
  */
81
  public static function tabulate( array $t ){
82
+ $w = [];
83
  foreach( $t as $y => $row ){
84
  foreach( $row as $x => $value ){
85
  $width = mb_strlen($value,'UTF-8');
87
  }
88
  }
89
  foreach( $t as $y => $row ){
90
+ $line = [];
91
  foreach( $w as $x => $width ){
92
  $value = isset($row[$x]) ? $row[$x] : '';
93
  $value = str_pad($value,$width,' ',STR_PAD_RIGHT);
102
  * Prints file listing to stdout
103
  */
104
  public static function tabulateFiles(){
105
+ $t = [];
106
  /* @var Loco_fs_File $file */
107
  foreach( func_get_args() as $file ){
108
  if( $file instanceof Loco_fs_File && $file->exists() ){
109
+ $f = new Loco_mvc_FileParams([],$file);
110
+ $t[] = [ $f->owner, $f->group, $f->smode, $f->relpath ];
111
  }
112
  }
113
  self::tabulate($t);
src/compat/Failure.php CHANGED
@@ -12,7 +12,7 @@ abstract class Loco_compat_Failure {
12
  * If this is hooked and not unhooked then auto-hooks using annotations have failed.
13
  */
14
  public static function print_hook_failure(){
15
- $texts = array( 'Loco Translate failed to start up' );
16
  /*/ Hooks currently not using annotations (would be if we enabled @priority tag)
17
  if( ini_get('opcache.enable') && ( ! ini_get('opcache.save_comments') || ! ini_get('opcache.load_comments') ) ){
18
  $texts[] = 'Try configuring opcache to preserve comments';
12
  * If this is hooked and not unhooked then auto-hooks using annotations have failed.
13
  */
14
  public static function print_hook_failure(){
15
+ $texts = [ 'Loco Translate failed to start up' ];
16
  /*/ Hooks currently not using annotations (would be if we enabled @priority tag)
17
  if( ini_get('opcache.enable') && ( ! ini_get('opcache.save_comments') || ! ini_get('opcache.load_comments') ) ){
18
  $texts[] = 'Try configuring opcache to preserve comments';
src/compat/MbstringExtension.php CHANGED
@@ -15,7 +15,7 @@ abstract class Loco_compat_MbstringExtension {
15
  }
16
 
17
  public static function mb_list_encodings(){
18
- return array('UTF-8','ISO-8859-1');
19
  }
20
 
21
  public static function mb_strlen( $str, $encoding = null ){
@@ -47,7 +47,7 @@ abstract class Loco_compat_MbstringExtension {
47
  // @codeCoverageIgnoreStart
48
 
49
  if( ! function_exists('mb_detect_encoding') ){
50
- function mb_detect_encoding( $str = '', array $encoding_list = array(), $strict = false ){
51
  return Loco_compat_MbstringExtension::mb_detect_encoding( $str, $encoding_list, $strict );
52
  }
53
  }
15
  }
16
 
17
  public static function mb_list_encodings(){
18
+ return ['UTF-8','ISO-8859-1'];
19
  }
20
 
21
  public static function mb_strlen( $str, $encoding = null ){
47
  // @codeCoverageIgnoreStart
48
 
49
  if( ! function_exists('mb_detect_encoding') ){
50
+ function mb_detect_encoding( $str = '', array $encoding_list = [], $strict = false ){
51
  return Loco_compat_MbstringExtension::mb_detect_encoding( $str, $encoding_list, $strict );
52
  }
53
  }
src/compat/PosixExtension.php CHANGED
@@ -99,7 +99,7 @@ abstract class Loco_compat_PosixExtension {
99
  }
100
  }
101
  // @codeCoverageIgnoreStart
102
- foreach( array('apache','nginx') as $name ){
103
  if( false !== stripos(PHP_SAPI,$name) ){
104
  return $name;
105
  }
99
  }
100
  }
101
  // @codeCoverageIgnoreStart
102
+ foreach( ['apache','nginx'] as $name ){
103
  if( false !== stripos(PHP_SAPI,$name) ){
104
  return $name;
105
  }
src/compat/TokenizerExtension.php CHANGED
@@ -8,7 +8,7 @@
8
  abstract class Loco_compat_TokenizerExtension {
9
 
10
  public static function token_get_all( $value ){
11
- return array();
12
  }
13
 
14
  }
8
  abstract class Loco_compat_TokenizerExtension {
9
 
10
  public static function token_get_all( $value ){
11
+ return [];
12
  }
13
 
14
  }
src/config/ArrayModel.php CHANGED
@@ -9,7 +9,7 @@ class Loco_config_ArrayModel extends Loco_config_Model {
9
  * {@inheritdoc}
10
  */
11
  public function createDom(){
12
- return new LocoConfigDocument( array('#document', array(), array() ) );
13
  }
14
 
15
 
@@ -32,7 +32,7 @@ class Loco_config_ArrayModel extends Loco_config_Model {
32
  */
33
  public function loadArray( array $root ){
34
  $dom = $this->getDom();
35
- $dom->load( array('#document', array(), array($root) ) );
36
  }
37
 
38
 
@@ -125,7 +125,7 @@ abstract class LocoConfigNode implements IteratorAggregate {
125
 
126
 
127
  public function __get( $prop ){
128
- $method = array( $this, 'get_'.$prop );
129
  if( is_callable($method) ){
130
  return call_user_func( $method );
131
  }
@@ -181,7 +181,7 @@ class LocoConfigNodeList implements Iterator, Countable, ArrayAccess {
181
 
182
  private $n;
183
 
184
- public function __construct( array $nodes = array() ){
185
  $this->nodes = $nodes;
186
  $this->n = count( $nodes );
187
  }
@@ -300,7 +300,7 @@ class LocoConfigDocument extends LocoConfigNode {
300
  * @return LocoConfigElement
301
  */
302
  public function createElement( $name ){
303
- return new LocoConfigElement( array( $name, array(), array() ) );
304
  }
305
 
306
 
9
  * {@inheritdoc}
10
  */
11
  public function createDom(){
12
+ return new LocoConfigDocument( ['#document', [], [] ] );
13
  }
14
 
15
 
32
  */
33
  public function loadArray( array $root ){
34
  $dom = $this->getDom();
35
+ $dom->load( ['#document', [], [$root] ] );
36
  }
37
 
38
 
125
 
126
 
127
  public function __get( $prop ){
128
+ $method = [ $this, 'get_'.$prop ];
129
  if( is_callable($method) ){
130
  return call_user_func( $method );
131
  }
181
 
182
  private $n;
183
 
184
+ public function __construct( array $nodes = [] ){
185
  $this->nodes = $nodes;
186
  $this->n = count( $nodes );
187
  }
300
  * @return LocoConfigElement
301
  */
302
  public function createElement( $name ){
303
+ return new LocoConfigElement( [ $name, [], [] ] );
304
  }
305
 
306
 
src/config/FormModel.php CHANGED
@@ -16,32 +16,32 @@ class Loco_config_FormModel extends Loco_config_ArrayModel {
16
  public function getPost(){
17
  $dom = $this->getDom();
18
  $root = $dom->documentElement;
19
- $post = new Loco_mvc_PostParams( array (
20
  'name' => $root->getAttribute('name'),
21
- 'exclude' => array (
22
  'path' => '',
23
- ),
24
- 'conf' => array(),
25
- ) );
26
  /* @var LocoConfigElement $domain */
27
  foreach( $this->query('domain',$root) as $domain ){
28
  $domainName = $domain->getAttribute('name');
29
  /* @var LocoConfigElement $project */
30
  foreach( $domain as $project ){
31
- $tree = array (
32
  'name' => $project->getAttribute('name'),
33
  'slug' => $project->getAttribute('slug'),
34
  'domain' => $domainName,
35
- 'source' => array (
36
  'path' => '',
37
- 'exclude' => array( 'path' => '' ),
38
- ),
39
- 'target' => array (
40
  'path' => '',
41
- 'exclude' => array( 'path' => '' ),
42
- ),
43
- 'template' => array( 'path' => '', 'locked' => false ),
44
- );
45
  $post['conf'][] = $this->collectPaths( $project, $tree );
46
  }
47
  }
@@ -56,7 +56,7 @@ class Loco_config_FormModel extends Loco_config_ArrayModel {
56
 
57
 
58
  private function collectPaths( LocoConfigElement $parent, array $branch ){
59
- $texts = array();
60
  foreach( $parent as $child ){
61
  $name = $child->nodeName;
62
  // all file types as "path" in form model
@@ -132,12 +132,12 @@ class Loco_config_FormModel extends Loco_config_ArrayModel {
132
  $root->setAttribute( 'name', $name );
133
 
134
  // bundle level excluded paths
135
- if( $nodes = array_intersect_key( $post->getArrayCopy(), array( 'exclude' => '' ) ) ) {
136
  $this->loadStruct( $root, $nodes );
137
  }
138
 
139
  // collect all projects grouped by domain
140
- $domains = array();
141
  foreach( $confs as $i => $conf ){
142
  if( ! empty($conf['removed']) ){
143
  continue;
@@ -147,13 +147,13 @@ class Loco_config_FormModel extends Loco_config_ArrayModel {
147
  }
148
  $domains[ $conf['domain'] ][] = $project = $dom->createElement('project');
149
  // project attributes
150
- foreach( array('name','slug') as $attr ){
151
  if( isset($conf[$attr]) ){
152
  $project->setAttribute( $attr, $conf[$attr] );
153
  }
154
  }
155
  // project children
156
- if( $nodes = array_intersect_key( $conf, array( 'source' => '', 'target' => '', 'template' => '' ) ) ) {
157
  $this->loadStruct( $project, $nodes );
158
  }
159
  }
16
  public function getPost(){
17
  $dom = $this->getDom();
18
  $root = $dom->documentElement;
19
+ $post = new Loco_mvc_PostParams( [
20
  'name' => $root->getAttribute('name'),
21
+ 'exclude' => [
22
  'path' => '',
23
+ ],
24
+ 'conf' => [],
25
+ ] );
26
  /* @var LocoConfigElement $domain */
27
  foreach( $this->query('domain',$root) as $domain ){
28
  $domainName = $domain->getAttribute('name');
29
  /* @var LocoConfigElement $project */
30
  foreach( $domain as $project ){
31
+ $tree = [
32
  'name' => $project->getAttribute('name'),
33
  'slug' => $project->getAttribute('slug'),
34
  'domain' => $domainName,
35
+ 'source' => [
36
  'path' => '',
37
+ 'exclude' => [ 'path' => '' ],
38
+ ],
39
+ 'target' => [
40
  'path' => '',
41
+ 'exclude' => [ 'path' => '' ],
42
+ ],
43
+ 'template' => [ 'path' => '', 'locked' => false ],
44
+ ];
45
  $post['conf'][] = $this->collectPaths( $project, $tree );
46
  }
47
  }
56
 
57
 
58
  private function collectPaths( LocoConfigElement $parent, array $branch ){
59
+ $texts = [];
60
  foreach( $parent as $child ){
61
  $name = $child->nodeName;
62
  // all file types as "path" in form model
132
  $root->setAttribute( 'name', $name );
133
 
134
  // bundle level excluded paths
135
+ if( $nodes = array_intersect_key( $post->getArrayCopy(), [ 'exclude' => '' ] ) ) {
136
  $this->loadStruct( $root, $nodes );
137
  }
138
 
139
  // collect all projects grouped by domain
140
+ $domains = [];
141
  foreach( $confs as $i => $conf ){
142
  if( ! empty($conf['removed']) ){
143
  continue;
147
  }
148
  $domains[ $conf['domain'] ][] = $project = $dom->createElement('project');
149
  // project attributes
150
+ foreach( ['name','slug'] as $attr ){
151
  if( isset($conf[$attr]) ){
152
  $project->setAttribute( $attr, $conf[$attr] );
153
  }
154
  }
155
  // project children
156
+ if( $nodes = array_intersect_key( $conf, [ 'source' => '', 'target' => '', 'template' => '' ] ) ) {
157
  $this->loadStruct( $project, $nodes );
158
  }
159
  }
src/config/Model.php CHANGED
@@ -36,7 +36,7 @@ abstract class Loco_config_Model {
36
  *
37
  */
38
  final public function __construct(){
39
- $this->dirs = array();
40
  $this->dom = $this->createDom();
41
  $this->setDirectoryPath( loco_constant('ABSPATH') );
42
  }
@@ -94,7 +94,7 @@ abstract class Loco_config_Model {
94
  // Map to a configured base path if target is not under our root. This makes XML more portable
95
  // matching order is most specific first, resulting in shortest path
96
  if( $relpath && ( Loco_fs_File::abs($relpath) || '..' === substr($relpath,0,2) || $this->base === $this->getDirectoryPath('ABSPATH') ) ){
97
- $bases = array( 'LOCO_LANG_DIR', 'WP_LANG_DIR', 'WP_PLUGIN_DIR', 'WPMU_PLUGIN_DIR', 'WP_CONTENT_DIR', 'ABSPATH' );
98
  foreach( $bases as $key ){
99
  if( ( $base = $this->getDirectoryPath($key) ) && $base !== $this->base ){
100
  $base .= '/';
36
  *
37
  */
38
  final public function __construct(){
39
+ $this->dirs = [];
40
  $this->dom = $this->createDom();
41
  $this->setDirectoryPath( loco_constant('ABSPATH') );
42
  }
94
  // Map to a configured base path if target is not under our root. This makes XML more portable
95
  // matching order is most specific first, resulting in shortest path
96
  if( $relpath && ( Loco_fs_File::abs($relpath) || '..' === substr($relpath,0,2) || $this->base === $this->getDirectoryPath('ABSPATH') ) ){
97
+ $bases = [ 'LOCO_LANG_DIR', 'WP_LANG_DIR', 'WP_PLUGIN_DIR', 'WPMU_PLUGIN_DIR', 'WP_CONTENT_DIR', 'ABSPATH' ];
98
  foreach( $bases as $key ){
99
  if( ( $base = $this->getDirectoryPath($key) ) && $base !== $this->base ){
100
  $base .= '/';
src/data/Cookie.php CHANGED
@@ -73,7 +73,7 @@ class Loco_data_Cookie extends ArrayObject {
73
  * @return Loco_data_Cookie
74
  */
75
  public function kill(){
76
- $this->exchangeArray( array() );
77
  $this->expires = time() - 86400;
78
  return $this;
79
  }
73
  * @return Loco_data_Cookie
74
  */
75
  public function kill(){
76
+ $this->exchangeArray( [] );
77
  $this->expires = time() - 86400;
78
  return $this;
79
  }
src/data/Permissions.php CHANGED
@@ -12,7 +12,7 @@ class Loco_data_Permissions {
12
  * Loco capabilities applicable to roles
13
  * @var array
14
  */
15
- private static $caps = array('loco_admin');
16
 
17
 
18
  /**
@@ -34,7 +34,7 @@ class Loco_data_Permissions {
34
  */
35
  public static function init(){
36
  $roles = self::wp_roles();
37
- $apply = array();
38
  // ensure translator role exists and is not locked out
39
  $role = $roles->get_role('translator');
40
  if( $role instanceof WP_Role ){
@@ -43,7 +43,7 @@ class Loco_data_Permissions {
43
  // else absence of translator role indicates first run
44
  // by default we'll initially allow full access to anyone that can manage_options
45
  else {
46
- $apply['translator'] = $roles->add_role( 'translator', 'Translator', array('read'=>true) );
47
  foreach( $roles->role_objects as $id => $role ){
48
  if( $role->has_cap('manage_options') ){
49
  $apply[$id] = $role;
@@ -114,7 +114,7 @@ class Loco_data_Permissions {
114
  // we'll only remove our custom role if it has no capabilities other than admin access
115
  // this avoids breaking other plugins that use it, or added it before Loco was installed.
116
  if( $role = get_role('translator') ){
117
- if( ! $role->capabilities || array('read') === array_keys($role->capabilities) ){
118
  remove_role('translator');
119
  }
120
  }
12
  * Loco capabilities applicable to roles
13
  * @var array
14
  */
15
+ private static $caps = ['loco_admin'];
16
 
17
 
18
  /**
34
  */
35
  public static function init(){
36
  $roles = self::wp_roles();
37
+ $apply = [];
38
  // ensure translator role exists and is not locked out
39
  $role = $roles->get_role('translator');
40
  if( $role instanceof WP_Role ){
43
  // else absence of translator role indicates first run
44
  // by default we'll initially allow full access to anyone that can manage_options
45
  else {
46
+ $apply['translator'] = $roles->add_role( 'translator', 'Translator', ['read'=>true] );
47
  foreach( $roles->role_objects as $id => $role ){
48
  if( $role->has_cap('manage_options') ){
49
  $apply[$id] = $role;
114
  // we'll only remove our custom role if it has no capabilities other than admin access
115
  // this avoids breaking other plugins that use it, or added it before Loco was installed.
116
  if( $role = get_role('translator') ){
117
+ if( ! $role->capabilities || ['read'] === array_keys($role->capabilities) ){
118
  remove_role('translator');
119
  }
120
  }
src/data/Preferences.php CHANGED
@@ -11,7 +11,7 @@ class Loco_data_Preferences extends Loco_data_Serializable {
11
  * User preference singletons
12
  * @var Loco_data_Preferences[]
13
  */
14
- private static $current = array();
15
 
16
  /**
17
  * ID of the currently operational user
@@ -23,10 +23,10 @@ class Loco_data_Preferences extends Loco_data_Serializable {
23
  * Available options and their defaults
24
  * @var array
25
  */
26
- private static $defaults = array (
27
  'credit' => '',
28
- 'locales' => array(),
29
- );
30
 
31
 
32
  /**
11
  * User preference singletons
12
  * @var Loco_data_Preferences[]
13
  */
14
+ private static $current = [];
15
 
16
  /**
17
  * ID of the currently operational user
23
  * Available options and their defaults
24
  * @var array
25
  */
26
+ private static $defaults = [
27
  'credit' => '',
28
+ 'locales' => [],
29
+ ];
30
 
31
 
32
  /**
src/data/RecentItems.php CHANGED
@@ -49,7 +49,7 @@ class Loco_data_RecentItems extends Loco_data_Option {
49
  */
50
  private function push( $object, array $indexes ){
51
  foreach( $indexes as $key => $id ){
52
- $stack = isset($this[$key]) ? $this[$key] : array();
53
  // remove before add ensures latest item appended to hashmap
54
  unset($stack[$id]);
55
  $stack[$id] = time();
@@ -65,7 +65,7 @@ class Loco_data_RecentItems extends Loco_data_Option {
65
  * @return array
66
  */
67
  private function getItems( $key, $offset, $count ){
68
- $stack = isset($this[$key]) ? $this[$key] : array();
69
  // hash map should automatically be in "push" order, meaning most recent last
70
  // sorting gives wrong order for same-second updates (only relevent in tests, but still..)
71
  // asort( $stack, SORT_NUMERIC );
@@ -93,7 +93,7 @@ class Loco_data_RecentItems extends Loco_data_Option {
93
  * @return Loco_data_RecentItems
94
  */
95
  public function pushBundle( Loco_package_Bundle $bundle ){
96
- return $this->push( $bundle, array( 'bundle' => $bundle->getId() ) );
97
  }
98
 
99
 
49
  */
50
  private function push( $object, array $indexes ){
51
  foreach( $indexes as $key => $id ){
52
+ $stack = isset($this[$key]) ? $this[$key] : [];
53
  // remove before add ensures latest item appended to hashmap
54
  unset($stack[$id]);
55
  $stack[$id] = time();
65
  * @return array
66
  */
67
  private function getItems( $key, $offset, $count ){
68
+ $stack = isset($this[$key]) ? $this[$key] : [];
69
  // hash map should automatically be in "push" order, meaning most recent last
70
  // sorting gives wrong order for same-second updates (only relevent in tests, but still..)
71
  // asort( $stack, SORT_NUMERIC );
93
  * @return Loco_data_RecentItems
94
  */
95
  public function pushBundle( Loco_package_Bundle $bundle ){
96
+ return $this->push( $bundle, [ 'bundle' => $bundle->getId() ] );
97
  }
98
 
99
 
src/data/Serializable.php CHANGED
@@ -37,7 +37,7 @@ abstract class Loco_data_Serializable extends ArrayObject {
37
  /**
38
  * {@inheritdoc}
39
  */
40
- public function __construct( array $data = array() ){
41
  $this->setFlags( ArrayObject::ARRAY_AS_PROPS );
42
  parent::__construct( $data );
43
  $this->dirty = (bool) $data;
@@ -165,12 +165,12 @@ abstract class Loco_data_Serializable extends ArrayObject {
165
  * @return array
166
  */
167
  protected function getSerializable(){
168
- return array (
169
  'c' => get_class($this),
170
  'v' => $this->getVersion(),
171
  'd' => $this->getArrayCopy(),
172
  't' => time(),
173
- );
174
  }
175
 
176
 
37
  /**
38
  * {@inheritdoc}
39
  */
40
+ public function __construct( array $data = [] ){
41
  $this->setFlags( ArrayObject::ARRAY_AS_PROPS );
42
  parent::__construct( $data );
43
  $this->dirty = (bool) $data;
165
  * @return array
166
  */
167
  protected function getSerializable(){
168
+ return [
169
  'c' => get_class($this),
170
  'v' => $this->getVersion(),
171
  'd' => $this->getArrayCopy(),
172
  't' => time(),
173
+ ];
174
  }
175
 
176
 
src/data/Session.php CHANGED
@@ -71,12 +71,12 @@ class Loco_data_Session extends Loco_data_Serializable {
71
  /**
72
  * @internal
73
  */
74
- final public function __construct( array $raw = array() ){
75
  $this->token = wp_get_session_token();
76
  if( ! $this->token ){
77
  throw new Loco_error_Exception('Failed to get session token');
78
  }
79
- parent::__construct( array() );
80
  $this->manager = WP_Session_Tokens::get_instance( get_current_user_id() );
81
  // populate object from stored session data
82
  $data = $this->getRaw();
@@ -91,7 +91,7 @@ class Loco_data_Session extends Loco_data_Serializable {
91
  self::$current = $this;
92
  // ensure against unclean shutdown
93
  if( loco_debugging() ){
94
- register_shutdown_function( array($this,'_on_shutdown') );
95
  }
96
  }
97
 
@@ -145,7 +145,7 @@ class Loco_data_Session extends Loco_data_Serializable {
145
  unset( $data['loco'] );
146
  $this->manager->update( $this->token, $data );
147
  }
148
- $this->exchangeArray( array() );
149
  $this->dirty = false;
150
  return $this;
151
  }
71
  /**
72
  * @internal
73
  */
74
+ final public function __construct( array $raw = [] ){
75
  $this->token = wp_get_session_token();
76
  if( ! $this->token ){
77
  throw new Loco_error_Exception('Failed to get session token');
78
  }
79
+ parent::__construct( [] );
80
  $this->manager = WP_Session_Tokens::get_instance( get_current_user_id() );
81
  // populate object from stored session data
82
  $data = $this->getRaw();
91
  self::$current = $this;
92
  // ensure against unclean shutdown
93
  if( loco_debugging() ){
94
+ register_shutdown_function( [$this,'_on_shutdown'] );
95
  }
96
  }
97
 
145
  unset( $data['loco'] );
146
  $this->manager->update( $this->token, $data );
147
  }
148
+ $this->exchangeArray( [] );
149
  $this->dirty = false;
150
  return $this;
151
  }
src/data/Settings.php CHANGED
@@ -24,7 +24,6 @@
24
  * @property string $deepl_api_key API key for DeepL Translator
25
  * @property string $deepl_api_url Base URL for DeepL Translator version
26
  * @property string $google_api_key API key for Google Translate
27
- * @property string $yandex_api_key API key for Yandex.Translate
28
  * @property string $lecto_api_key API key for Lecto Translation API
29
  * @property string $microsoft_api_key API key for Microsoft Translator text API
30
  * @property string $microsoft_api_region API region for Microsoft Translator text API
@@ -43,15 +42,15 @@ class Loco_data_Settings extends Loco_data_Serializable {
43
  * Available options and their defaults
44
  * @var array
45
  */
46
- private static $defaults = array (
47
  'version' => '',
48
  'gen_hash' => false,
49
  'use_fuzzy' => true,
50
  'fuzziness' => 20,
51
  'num_backups' => 5,
52
- 'pot_alias' => array( 'default.po', 'en_US.po', 'en.po' ),
53
- 'php_alias' => array( 'php', 'twig' ),
54
- 'jsx_alias' => array(),
55
  'fs_persist' => false,
56
  'fs_protect' => 1,
57
  'pot_protect' => 1,
@@ -65,11 +64,10 @@ class Loco_data_Settings extends Loco_data_Serializable {
65
  'deepl_api_key' => '',
66
  'deepl_api_url' => '',
67
  'google_api_key' => '',
68
- 'yandex_api_key' => '',
69
  'microsoft_api_key' => '',
70
  'microsoft_api_region' => 'global',
71
  'lecto_api_key' => '',
72
- );
73
 
74
 
75
  /**
@@ -174,11 +172,11 @@ class Loco_data_Settings extends Loco_data_Serializable {
174
  if( version_compare($old,$new,'<') ){
175
  $this->persist();
176
  $updated = true;
177
- // feature alerts:
178
- if( '2.5.' === substr($new,0,4) && '2.5.' !== substr($old,0,4) ){
179
- Loco_error_AdminNotices::info( __('Loco Translate 2.5 adds supports for JSON language pack generation.','loco-translate') )
180
- ->addLink( apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/json'), __('Documentation','loco-translate') );
181
- }
182
  }
183
  return $updated;
184
  }
@@ -213,7 +211,7 @@ class Loco_data_Settings extends Loco_data_Serializable {
213
  }
214
  }
215
  // enforce missing values that must have a default, but were passed empty
216
- foreach( array('php_alias','max_php_size','po_width') as $prop ){
217
  if( isset($data[$prop]) && '' === $data[$prop] ){
218
  parent::offsetSet( $prop, self::$defaults[$prop] );
219
  }
24
  * @property string $deepl_api_key API key for DeepL Translator
25
  * @property string $deepl_api_url Base URL for DeepL Translator version
26
  * @property string $google_api_key API key for Google Translate
 
27
  * @property string $lecto_api_key API key for Lecto Translation API
28
  * @property string $microsoft_api_key API key for Microsoft Translator text API
29
  * @property string $microsoft_api_region API region for Microsoft Translator text API
42
  * Available options and their defaults
43
  * @var array
44
  */
45
+ private static $defaults = [
46
  'version' => '',
47
  'gen_hash' => false,
48
  'use_fuzzy' => true,
49
  'fuzziness' => 20,
50
  'num_backups' => 5,
51
+ 'pot_alias' => [ 'default.po', 'en_US.po', 'en.po' ],
52
+ 'php_alias' => [ 'php', 'twig' ],
53
+ 'jsx_alias' => [],
54
  'fs_persist' => false,
55
  'fs_protect' => 1,
56
  'pot_protect' => 1,
64
  'deepl_api_key' => '',
65
  'deepl_api_url' => '',
66
  'google_api_key' => '',
 
67
  'microsoft_api_key' => '',
68
  'microsoft_api_region' => 'global',
69
  'lecto_api_key' => '',
70
+ ];
71
 
72
 
73
  /**
172
  if( version_compare($old,$new,'<') ){
173
  $this->persist();
174
  $updated = true;
175
+ /*/ feature alerts:
176
+ if( '2.6.' === substr($new,0,4) && '2.6.' !== substr($old,0,4) ){
177
+ Loco_error_AdminNotices::info( __('Loco Translate 2.6 adds ......','loco-translate') )
178
+ ->addLink( apply_filters('loco_external','https://localise.biz/wordpress/plugin/changelog'), __('Documentation','loco-translate') );
179
+ }*/
180
  }
181
  return $updated;
182
  }
211
  }
212
  }
213
  // enforce missing values that must have a default, but were passed empty
214
+ foreach( ['php_alias','max_php_size','po_width'] as $prop ){
215
  if( isset($data[$prop]) && '' === $data[$prop] ){
216
  parent::offsetSet( $prop, self::$defaults[$prop] );
217
  }
src/error/AdminNotices.php CHANGED
@@ -10,7 +10,7 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
10
  /**
11
  * @var Loco_error_Exception[]
12
  */
13
- private $errors = array();
14
 
15
  /**
16
  * Inline messages are handled by our own template views
@@ -125,11 +125,11 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
125
  $notices = self::$singleton;
126
  if( $notices instanceof Loco_error_AdminNotices ){
127
  $buffer = $notices->errors;
128
- $notices->errors = array();
129
  self::$singleton = null;
130
  return $buffer;
131
  }
132
- return array();
133
  }
134
 
135
 
@@ -139,7 +139,7 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
139
  * @return array
140
  */
141
  public static function destroyAjax(){
142
- $data = array();
143
  foreach( self::destroy() as $notice ){
144
  $data[] = $notice->jsonSerialize();
145
  }
@@ -152,14 +152,14 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
152
  */
153
  private function flushHtml(){
154
  if( $this->errors ){
155
- $htmls = array();
156
  foreach( $this->errors as $error ){
157
  $html = sprintf (
158
  '<p><strong class="has-icon">%s:</strong> <span>%s</span></p>',
159
  esc_html( $error->getTitle() ),
160
  esc_html( $error->getMessage() )
161
  );
162
- $styles = array( 'notice', 'notice-'.$error->getType() );
163
  if( $this->inline ){
164
  $styles[] = 'inline';
165
  }
@@ -169,7 +169,7 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
169
  }
170
  $htmls[] = '<div class="'.implode(' ',$styles).'">'.$html.'</div>';
171
  }
172
- $this->errors = array();
173
  echo implode("\n", $htmls),"\n";
174
  }
175
  }
@@ -181,7 +181,7 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
181
  foreach( $this->errors as $e ){
182
  $e->logCli();
183
  }
184
- $this->errors = array();
185
 
186
  }
187
 
@@ -236,7 +236,7 @@ class Loco_error_AdminNotices extends Loco_hooks_Hookable {
236
  $this->flushHtml();
237
  }
238
  else {
239
- $this->errors = array();
240
  }
241
  }
242
 
10
  /**
11
  * @var Loco_error_Exception[]
12
  */
13
+ private $errors = [];
14
 
15
  /**
16
  * Inline messages are handled by our own template views
125
  $notices = self::$singleton;
126
  if( $notices instanceof Loco_error_AdminNotices ){
127
  $buffer = $notices->errors;
128
+ $notices->errors = [];
129
  self::$singleton = null;
130
  return $buffer;
131
  }
132
+ return [];
133
  }
134
 
135
 
139
  * @return array
140
  */
141
  public static function destroyAjax(){
142
+ $data = [];
143
  foreach( self::destroy() as $notice ){
144
  $data[] = $notice->jsonSerialize();
145
  }
152
  */
153
  private function flushHtml(){
154
  if( $this->errors ){
155
+ $htmls = [];
156
  foreach( $this->errors as $error ){
157
  $html = sprintf (
158
  '<p><strong class="has-icon">%s:</strong> <span>%s</span></p>',
159
  esc_html( $error->getTitle() ),
160
  esc_html( $error->getMessage() )
161
  );
162
+ $styles = [ 'notice', 'notice-'.$error->getType() ];
163
  if( $this->inline ){
164
  $styles[] = 'inline';
165
  }
169
  }
170
  $htmls[] = '<div class="'.implode(' ',$styles).'">'.$html.'</div>';
171
  }
172
+ $this->errors = [];
173
  echo implode("\n", $htmls),"\n";
174
  }
175
  }
181
  foreach( $this->errors as $e ){
182
  $e->logCli();
183
  }
184
+ $this->errors = [];
185
 
186
  }
187
 
236
  $this->flushHtml();
237
  }
238
  else {
239
+ $this->errors = [];
240
  }
241
  }
242
 
src/error/Exception.php CHANGED
@@ -14,7 +14,7 @@ class Loco_error_Exception extends Exception implements JsonSerializable {
14
  * Links to help docs etc.. to show along side error message
15
  * @var array
16
  */
17
- private $links = array();
18
 
19
  /**
20
  * Override file in which exception was thrown
@@ -170,7 +170,7 @@ class Loco_error_Exception extends Exception implements JsonSerializable {
170
  */
171
  #[ReturnTypeWillChange]
172
  public function jsonSerialize(){
173
- return array (
174
  'code' => $this->getCode(),
175
  'type' => $this->getType(),
176
  'class' => get_class($this),
@@ -178,7 +178,7 @@ class Loco_error_Exception extends Exception implements JsonSerializable {
178
  'message' => $this->getMessage(),
179
  //'file' => str_replace( ABSPATH, '', $this->getRealFile() ),
180
  //'line' => $this->getRealLine()
181
- );
182
  }
183
 
184
 
14
  * Links to help docs etc.. to show along side error message
15
  * @var array
16
  */
17
+ private $links = [];
18
 
19
  /**
20
  * Override file in which exception was thrown
170
  */
171
  #[ReturnTypeWillChange]
172
  public function jsonSerialize(){
173
+ return [
174
  'code' => $this->getCode(),
175
  'type' => $this->getType(),
176
  'class' => get_class($this),
178
  'message' => $this->getMessage(),
179
  //'file' => str_replace( ABSPATH, '', $this->getRealFile() ),
180
  //'line' => $this->getRealLine()
181
+ ];
182
  }
183
 
184
 
src/error/ParseException.php CHANGED
@@ -16,7 +16,7 @@ class Loco_error_ParseException extends Loco_error_Exception {
16
  * @return self
17
  */
18
  public function setContext( $line, $column, $source ){
19
- $this->context = array();
20
  $lines = preg_split( '/\\r?\\n/', $source, $line+1 );
21
  $offset = $line - 1;
22
  if( isset($lines[$offset]) ){
16
  * @return self
17
  */
18
  public function setContext( $line, $column, $source ){
19
+ $this->context = [];
20
  $lines = preg_split( '/\\r?\\n/', $source, $line+1 );
21
  $offset = $line - 1;
22
  if( isset($lines[$offset]) ){
src/fs/File.php CHANGED
@@ -72,7 +72,7 @@ class Loco_fs_File {
72
  /**
73
  * Internally set path value and flag whether relative or absolute
74
  * @param string
75
- * @return string
76
  */
77
  private function setPath( $path ){
78
  $path = (string) $path;
@@ -87,7 +87,6 @@ class Loco_fs_File {
87
  $this->path = $path;
88
  $this->info = null;
89
  }
90
- return $path;
91
  }
92
 
93
 
@@ -110,14 +109,13 @@ class Loco_fs_File {
110
  /**
111
  * Copy write context with our file reference
112
  * @param Loco_fs_FileWriter|null
113
- * @return Loco_fs_File
114
  */
115
  private function cloneWriteContext( Loco_fs_FileWriter $context = null ){
116
  if( $context ){
117
  $context = clone $context;
118
  $this->w = $context->setFile($this);
119
  }
120
- return $this;
121
  }
122
 
123
 
@@ -381,10 +379,10 @@ class Loco_fs_File {
381
  }
382
  else {
383
  if( ! $this->rel || ! $base ){
384
- $b = array();
385
  }
386
  else {
387
- $b = self::explode( $base, array() );
388
  }
389
  $b = self::explode( $path, $b );
390
  $this->setPath( implode('/',$b) );
@@ -429,7 +427,7 @@ class Loco_fs_File {
429
  */
430
  public function getRelativePath( $base ){
431
  $path = $this->normalize();
432
- if( $abspath = self::abs($path) ){
433
  // base may needs require normalizing
434
  $file = new Loco_fs_File($base);
435
  $base = $file->normalize();
@@ -606,16 +604,11 @@ class Loco_fs_File {
606
 
607
  /**
608
  * Copy this object as a WordPress script translation file
609
- * @param string relative path to .js file
610
- * @param string optional base URL if you want to run relative path filters
611
  * @return self
612
  */
613
- public function cloneJson( $ref, $url = '' ){
614
  $name = $this->filename();
615
- // Hook into load_script_textdomain_relative_path if script URL provided
616
- if( is_string($url) && '' !== $url ){
617
- $ref = apply_filters( 'load_script_textdomain_relative_path', $ref, trailingslashit($url).ltrim($ref,'/') );
618
- }
619
  if( is_string($ref) && '' !== $ref ){
620
  // Hashable reference is always finally unminified, as per load_script_textdomain()
621
  if( substr($ref,-7) === '.min.js' ) {
72
  /**
73
  * Internally set path value and flag whether relative or absolute
74
  * @param string
75
+ * @return void
76
  */
77
  private function setPath( $path ){
78
  $path = (string) $path;
87
  $this->path = $path;
88
  $this->info = null;
89
  }
 
90
  }
91
 
92
 
109
  /**
110
  * Copy write context with our file reference
111
  * @param Loco_fs_FileWriter|null
112
+ * @return void
113
  */
114
  private function cloneWriteContext( Loco_fs_FileWriter $context = null ){
115
  if( $context ){
116
  $context = clone $context;
117
  $this->w = $context->setFile($this);
118
  }
 
119
  }
120
 
121
 
379
  }
380
  else {
381
  if( ! $this->rel || ! $base ){
382
+ $b = [];
383
  }
384
  else {
385
+ $b = self::explode( $base, [] );
386
  }
387
  $b = self::explode( $path, $b );
388
  $this->setPath( implode('/',$b) );
427
  */
428
  public function getRelativePath( $base ){
429
  $path = $this->normalize();
430
+ if( self::abs($path) ){
431
  // base may needs require normalizing
432
  $file = new Loco_fs_File($base);
433
  $base = $file->normalize();
604
 
605
  /**
606
  * Copy this object as a WordPress script translation file
607
+ * @param string relative path to .js file presumed to exist
 
608
  * @return self
609
  */
610
+ public function cloneJson( $ref ){
611
  $name = $this->filename();
 
 
 
 
612
  if( is_string($ref) && '' !== $ref ){
613
  // Hashable reference is always finally unminified, as per load_script_textdomain()
614
  if( substr($ref,-7) === '.min.js' ) {
src/fs/FileFinder.php CHANGED
@@ -98,7 +98,7 @@ class Loco_fs_FileFinder implements Iterator, Countable, Loco_fs_FileListInterfa
98
  public function __construct( $root = '' ){
99
  $this->roots = new Loco_fs_FileList;
100
  $this->linked = new Loco_fs_FileList;
101
- $this->excluded = array();
102
  if( $root ){
103
  $this->addRoot( $root );
104
  }
@@ -235,7 +235,7 @@ class Loco_fs_FileFinder implements Iterator, Countable, Loco_fs_FileListInterfa
235
  */
236
  public function filterExtensions( array $exts ){
237
  $this->invalidate();
238
- $this->exts = array();
239
  foreach( $exts as $ext ){
240
  $this->exts[ ltrim($ext,'*.') ] = new Loco_fs_FileList;
241
  }
98
  public function __construct( $root = '' ){
99
  $this->roots = new Loco_fs_FileList;
100
  $this->linked = new Loco_fs_FileList;
101
+ $this->excluded = [];
102
  if( $root ){
103
  $this->addRoot( $root );
104
  }
235
  */
236
  public function filterExtensions( array $exts ){
237
  $this->invalidate();
238
+ $this->exts = [];
239
  foreach( $exts as $ext ){
240
  $this->exts[ ltrim($ext,'*.') ] = new Loco_fs_FileList;
241
  }
src/fs/FileList.php CHANGED
@@ -8,14 +8,14 @@ class Loco_fs_FileList extends ArrayIterator implements Loco_fs_FileListInterfac
8
  * Hash map for ensuring files only added once
9
  * @var array
10
  */
11
- private $unique = array();
12
 
13
  /**
14
  * Construct with initial list if files
15
  * @param Loco_fs_File[]
16
  */
17
- public function __construct( $a = array() ){
18
- parent::__construct( array() );
19
  foreach( $a as $file ){
20
  $this->add( $file );
21
  }
@@ -37,7 +37,7 @@ class Loco_fs_FileList extends ArrayIterator implements Loco_fs_FileListInterfac
37
  * @return array
38
  */
39
  public function export(){
40
- $a = array();
41
  foreach( $this as $file ){
42
  $a[] = (string) $file;
43
  }
8
  * Hash map for ensuring files only added once
9
  * @var array
10
  */
11
+ private $unique = [];
12
 
13
  /**
14
  * Construct with initial list if files
15
  * @param Loco_fs_File[]
16
  */
17
+ public function __construct( $a = [] ){
18
+ parent::__construct( [] );
19
  foreach( $a as $file ){
20
  $this->add( $file );
21
  }
37
  * @return array
38
  */
39
  public function export(){
40
+ $a = [];
41
  foreach( $this as $file ){
42
  $a[] = (string) $file;
43
  }
src/fs/FileWriter.php CHANGED
@@ -274,7 +274,7 @@ class Loco_fs_FileWriter {
274
  // may have bypassed definition of FS_CHMOD_DIR
275
  $mode = defined('FS_CHMOD_DIR') ? FS_CHMOD_DIR : 0755;
276
  // find first ancestor that exists while building tree
277
- $stack = array();
278
  /* @var $parent Loco_fs_Directory */
279
  while( $parent = $here->getParent() ){
280
  array_unshift( $stack, $this->mapPath( $here->getPath() ) );
274
  // may have bypassed definition of FS_CHMOD_DIR
275
  $mode = defined('FS_CHMOD_DIR') ? FS_CHMOD_DIR : 0755;
276
  // find first ancestor that exists while building tree
277
+ $stack = [];
278
  /* @var $parent Loco_fs_Directory */
279
  while( $parent = $here->getParent() ){
280
  array_unshift( $stack, $this->mapPath( $here->getPath() ) );
src/fs/LocaleFile.php CHANGED
@@ -48,7 +48,7 @@ class Loco_fs_LocaleFile extends Loco_fs_File {
48
  $this->locale = null;
49
  }
50
  }
51
- return array( $this->prefix, $this->suffix, $this->hash );
52
  }
53
 
54
 
48
  $this->locale = null;
49
  }
50
  }
51
+ return [ $this->prefix, $this->suffix, $this->hash ];
52
  }
53
 
54
 
src/fs/LocaleFileList.php CHANGED
@@ -8,7 +8,7 @@ class Loco_fs_LocaleFileList extends Loco_fs_FileList {
8
  * Look up locale entries by their tag
9
  * @var array
10
  */
11
- private $index = array();
12
 
13
 
14
  /**
@@ -49,7 +49,7 @@ class Loco_fs_LocaleFileList extends Loco_fs_FileList {
49
  * @return array<Loco_Locale>
50
  */
51
  public function getLocales(){
52
- $list = array();
53
  foreach( array_keys($this->index) as $tag ){
54
  $locale = Loco_Locale::parse($tag);
55
  if( $locale->isValid() ){
8
  * Look up locale entries by their tag
9
  * @var array
10
  */
11
+ private $index = [];
12
 
13
 
14
  /**
49
  * @return array<Loco_Locale>
50
  */
51
  public function getLocales(){
52
+ $list = [];
53
  foreach( array_keys($this->index) as $tag ){
54
  $locale = Loco_Locale::parse($tag);
55
  if( $locale->isValid() ){
src/fs/Locations.php CHANGED
@@ -54,9 +54,9 @@ class Loco_fs_Locations extends ArrayObject {
54
  */
55
  public static function getRoot(){
56
  if( ! self::$roots ){
57
- self::$roots = new Loco_fs_Locations( array(
58
  loco_constant('ABSPATH'),
59
- ) );
60
  }
61
  return self::$roots;
62
  }
@@ -67,10 +67,10 @@ class Loco_fs_Locations extends ArrayObject {
67
  */
68
  public static function getContent(){
69
  if( ! self::$conts ){
70
- self::$conts = new Loco_fs_Locations( array(
71
  loco_constant('WP_CONTENT_DIR'), // <- defined WP_CONTENT_DIR
72
  trailingslashit(ABSPATH).'wp-content', // <- default /wp-content
73
- ) );
74
  }
75
  return self::$conts;
76
  }
@@ -81,9 +81,9 @@ class Loco_fs_Locations extends ArrayObject {
81
  */
82
  public static function getGlobal(){
83
  if( ! self::$langs ){
84
- self::$langs = new Loco_fs_Locations( array(
85
  loco_constant('WP_LANG_DIR'),
86
- ) );
87
  }
88
  return self::$langs;
89
  }
@@ -94,7 +94,7 @@ class Loco_fs_Locations extends ArrayObject {
94
  */
95
  public static function getThemes(){
96
  if( ! self::$theme ){
97
- $roots = isset($GLOBALS['wp_theme_directories']) ? $GLOBALS['wp_theme_directories'] : array();
98
  if( ! $roots ){
99
  $roots[] = trailingslashit( loco_constant('WP_CONTENT_DIR') ).'themes';
100
  }
@@ -109,10 +109,10 @@ class Loco_fs_Locations extends ArrayObject {
109
  */
110
  public static function getPlugins(){
111
  if( ! self::$plugin ){
112
- self::$plugin = new Loco_fs_Locations( array(
113
  loco_constant('WP_PLUGIN_DIR'),
114
  loco_constant('WPMU_PLUGIN_DIR'),
115
- ) );
116
  }
117
  return self::$plugin;
118
  }
@@ -122,7 +122,7 @@ class Loco_fs_Locations extends ArrayObject {
122
  * @param array
123
  */
124
  public function __construct( array $paths ){
125
- parent::__construct( array() );
126
  foreach( $paths as $path ){
127
  $this->add( $path );
128
  }
@@ -189,7 +189,7 @@ class Loco_fs_Locations extends ArrayObject {
189
  if( ! $path ){
190
  throw new InvalidArgumentException('Expected absolute path');
191
  }
192
- $paths = array( trailingslashit($path) );
193
  // add real path if differs
194
  $real = realpath($path);
195
  if( $real && $real !== $path ){
54
  */
55
  public static function getRoot(){
56
  if( ! self::$roots ){
57
+ self::$roots = new Loco_fs_Locations( [
58
  loco_constant('ABSPATH'),
59
+ ] );
60
  }
61
  return self::$roots;
62
  }
67
  */
68
  public static function getContent(){
69
  if( ! self::$conts ){
70
+ self::$conts = new Loco_fs_Locations( [
71
  loco_constant('WP_CONTENT_DIR'), // <- defined WP_CONTENT_DIR
72
  trailingslashit(ABSPATH).'wp-content', // <- default /wp-content
73
+ ] );
74
  }
75
  return self::$conts;
76
  }
81
  */
82
  public static function getGlobal(){
83
  if( ! self::$langs ){
84
+ self::$langs = new Loco_fs_Locations( [
85
  loco_constant('WP_LANG_DIR'),
86
+ ] );
87
  }
88
  return self::$langs;
89
  }
94
  */
95
  public static function getThemes(){
96
  if( ! self::$theme ){
97
+ $roots = isset($GLOBALS['wp_theme_directories']) ? $GLOBALS['wp_theme_directories'] : [];
98
  if( ! $roots ){
99
  $roots[] = trailingslashit( loco_constant('WP_CONTENT_DIR') ).'themes';
100
  }
109
  */
110
  public static function getPlugins(){
111
  if( ! self::$plugin ){
112
+ self::$plugin = new Loco_fs_Locations( [
113
  loco_constant('WP_PLUGIN_DIR'),
114
  loco_constant('WPMU_PLUGIN_DIR'),
115
+ ] );
116
  }
117
  return self::$plugin;
118
  }
122
  * @param array
123
  */
124
  public function __construct( array $paths ){
125
+ parent::__construct( [] );
126
  foreach( $paths as $path ){
127
  $this->add( $path );
128
  }
189
  if( ! $path ){
190
  throw new InvalidArgumentException('Expected absolute path');
191
  }
192
+ $paths = [ trailingslashit($path) ];
193
  // add real path if differs
194
  $real = realpath($path);
195
  if( $real && $real !== $path ){
src/fs/Revisions.php CHANGED
@@ -32,7 +32,7 @@ class Loco_fs_Revisions implements Countable/*, IteratorAggregate*/ {
32
  * Paths to delete when object removed from memory
33
  * @var array
34
  */
35
- private $trash = array();
36
 
37
 
38
  /**
@@ -145,7 +145,7 @@ class Loco_fs_Revisions implements Countable/*, IteratorAggregate*/ {
145
  */
146
  public function getPaths(){
147
  if( is_null($this->paths) ){
148
- $this->paths = array();
149
  $regex = $this->getRegExp();
150
  $finder = new Loco_fs_FileFinder( $this->master->dirname() );
151
  $finder->setRecursive(false);
32
  * Paths to delete when object removed from memory
33
  * @var array
34
  */
35
+ private $trash = [];
36
 
37
 
38
  /**
145
  */
146
  public function getPaths(){
147
  if( is_null($this->paths) ){
148
+ $this->paths = [];
149
  $regex = $this->getRegExp();
150
  $finder = new Loco_fs_FileFinder( $this->master->dirname() );
151
  $finder->setRecursive(false);
src/fs/Siblings.php CHANGED
@@ -39,9 +39,9 @@ class Loco_fs_Siblings {
39
  * @return Loco_fs_File[]
40
  */
41
  public function expand(){
42
- $siblings = array();
43
  // Source and binary pair
44
- foreach( array( $this->po, $this->mo ) as $file ){
45
  if( $file && $file->exists() ){
46
  $siblings[] = $file;
47
  }
39
  * @return Loco_fs_File[]
40
  */
41
  public function expand(){
42
+ $siblings = [];
43
  // Source and binary pair
44
+ foreach( [ $this->po, $this->mo ] as $file ){
45
  if( $file && $file->exists() ){
46
  $siblings[] = $file;
47
  }
src/gettext/Compiler.php CHANGED
@@ -34,11 +34,11 @@ class Loco_gettext_Compiler {
34
  public function __construct( Loco_fs_LocaleFile $pofile ){
35
  $this->fs = new Loco_api_WordPressFileSystem;
36
  $this->files = new Loco_fs_Siblings($pofile);
37
- $this->progress = new Loco_mvc_ViewParams( array(
38
  'pobytes' => 0,
39
  'mobytes' => 0,
40
  'numjson' => 0,
41
- ) );
42
  }
43
 
44
 
@@ -140,9 +140,10 @@ class Loco_gettext_Compiler {
140
  // continue as per default, generating multiple per-script JSON
141
  else {
142
  $base_dir = $project->getBundle()->getDirectoryPath();
143
- $buffer = array();
144
  /* @var Loco_gettext_Data $fragment */
145
  foreach( $po->exportRefs('\\.js') as $ref => $fragment ){
 
146
  // Reference could be source js, or minified version.
147
  // Some build systems may differ, but WordPress only supports this. See WP-CLI MakeJsonCommand.
148
  if( substr($ref,-7) === '.min.js' ) {
@@ -153,34 +154,33 @@ class Loco_gettext_Compiler {
153
  $src = $ref;
154
  $min = substr($ref,0,-3).'.min.js';
155
  }
156
- // Try both script paths to check whether deployed script actually exists
157
- $found = false;
158
- foreach( array($min,$src) as $ref ){
159
  // Hook into load_script_textdomain_relative_path like load_script_textdomain() does.
160
- $url = $project->getBundle()->getDirectoryUrl().$ref;
161
- $ref = apply_filters( 'load_script_textdomain_relative_path', $ref, $url );
162
- if( ! is_string($ref) || '' === $ref ){
163
  continue;
164
  }
165
- $file = new Loco_fs_File($ref);
 
166
  $file->normalize($base_dir);
167
- if( ! $file->exists() ){
168
- continue;
169
- }
170
- // add .js strings to buffer for this json and merge if already present
171
- if( array_key_exists($ref,$buffer) ){
172
- $buffer[$ref]->concat($fragment);
173
- }
174
- else {
175
- $buffer[$ref] = $fragment;
176
  }
177
- $found = true;
178
- break;
179
  }
180
  // if neither exists in the bundle, this is a source path that will never be resolved at runtime
181
- if( ! $found ){
182
  Loco_error_AdminNotices::debug( sprintf('Skipping JSON for %s; script not found in bundle',$ref) );
183
  }
 
 
 
 
 
 
 
184
  }
185
  // write all buffered fragments to their computed JSON paths
186
  foreach( $buffer as $ref => $fragment ) {
@@ -246,7 +246,7 @@ class Loco_gettext_Compiler {
246
  * @return string[]
247
  */
248
  private function getJsExtMap(){
249
- $map = array('js'=>'js', 'jsx'=>'js');
250
  $exts = Loco_data_Settings::get()->jsx_alias;
251
  if( is_array($exts) && $exts ){
252
  foreach( $exts as $ext ){
34
  public function __construct( Loco_fs_LocaleFile $pofile ){
35
  $this->fs = new Loco_api_WordPressFileSystem;
36
  $this->files = new Loco_fs_Siblings($pofile);
37
+ $this->progress = new Loco_mvc_ViewParams( [
38
  'pobytes' => 0,
39
  'mobytes' => 0,
40
  'numjson' => 0,
41
+ ] );
42
  }
43
 
44
 
140
  // continue as per default, generating multiple per-script JSON
141
  else {
142
  $base_dir = $project->getBundle()->getDirectoryPath();
143
+ $buffer = [];
144
  /* @var Loco_gettext_Data $fragment */
145
  foreach( $po->exportRefs('\\.js') as $ref => $fragment ){
146
+ $use = null;
147
  // Reference could be source js, or minified version.
148
  // Some build systems may differ, but WordPress only supports this. See WP-CLI MakeJsonCommand.
149
  if( substr($ref,-7) === '.min.js' ) {
154
  $src = $ref;
155
  $min = substr($ref,0,-3).'.min.js';
156
  }
157
+ // Try .js and .min.js paths to check whether deployed script actually exists
158
+ foreach( [$min,$src] as $try ){
 
159
  // Hook into load_script_textdomain_relative_path like load_script_textdomain() does.
160
+ $url = $project->getBundle()->getDirectoryUrl().$try;
161
+ $try = apply_filters( 'load_script_textdomain_relative_path', $try, $url );
162
+ if( ! is_string($try) || '' === $try ){
163
  continue;
164
  }
165
+ // by default ignore js file that is not in deployed code
166
+ $file = new Loco_fs_File($try);
167
  $file->normalize($base_dir);
168
+ if( apply_filters('loco_compile_script_reference',$file->exists(),$try,$domain) ){
169
+ $use = $try;
170
+ break;
 
 
 
 
 
 
171
  }
 
 
172
  }
173
  // if neither exists in the bundle, this is a source path that will never be resolved at runtime
174
+ if( is_null($use) ){
175
  Loco_error_AdminNotices::debug( sprintf('Skipping JSON for %s; script not found in bundle',$ref) );
176
  }
177
+ // add .js strings to buffer for this json and merge if already present
178
+ else if( array_key_exists($use,$buffer) ){
179
+ $buffer[$use]->concat($fragment);
180
+ }
181
+ else {
182
+ $buffer[$use] = $fragment;
183
+ }
184
  }
185
  // write all buffered fragments to their computed JSON paths
186
  foreach( $buffer as $ref => $fragment ) {
246
  * @return string[]
247
  */
248
  private function getJsExtMap(){
249
+ $map = ['js'=>'js', 'jsx'=>'js'];
250
  $exts = Loco_data_Settings::get()->jsx_alias;
251
  if( is_array($exts) && $exts ){
252
  foreach( $exts as $ext ){
src/gettext/Data.php CHANGED
@@ -88,7 +88,7 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
88
  * @return Loco_gettext_Data
89
  */
90
  public static function dummy(){
91
- return new Loco_gettext_Data( array( array('source'=>'','target'=>'Language:') ) );
92
  }
93
 
94
 
@@ -147,7 +147,7 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
147
  // set maximum line width, zero or >= 15
148
  $this->wrap( Loco_data_Settings::get()->po_width );
149
  // concat with default text sorting if specified
150
- $po = $this->render( $sort ? array( 'LocoPoIterator', 'compare' ) : null );
151
  // Prepend byte order mark only if configured
152
  if( Loco_data_Settings::get()->po_utf8_bom ){
153
  $po = "\xEF\xBB\xBF".$po;
@@ -172,15 +172,15 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
172
  $json_options |= loco_constant('JSON_PRETTY_PRINT') | loco_constant('JSON_UNESCAPED_SLASHES'); // | loco_constant('JSON_UNESCAPED_UNICODE');
173
  }
174
  // PO should have a date if localised properly
175
- return json_encode( array (
176
  'translation-revision-date' => $head['PO-Revision-Date'],
177
  'generator' => $head['X-Generator'],
178
  'source' => $source,
179
  'domain' => $domain,
180
- 'locale_data' => array (
181
  $domain => $data,
182
- ),
183
- ), $json_options );
184
  }
185
 
186
 
@@ -220,16 +220,16 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
220
  * @param string[] custom headers
221
  * @return Loco_gettext_Data
222
  */
223
- public function localize( Loco_Locale $locale, array $custom = array() ){
224
- $date = gmdate('Y-m-d H:i').'+0000'; // <- forcing UCT
225
  // headers that must always be set if absent
226
- $defaults = array (
227
  'Project-Id-Version' => '',
228
  'Report-Msgid-Bugs-To' => '',
229
  'POT-Creation-Date' => $date,
230
- );
231
  // headers that must always override when localizing
232
- $required = array (
233
  'PO-Revision-Date' => $date,
234
  'Last-Translator' => '',
235
  'Language-Team' => $locale->getName(),
@@ -240,7 +240,19 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
240
  'Content-Transfer-Encoding' => '8bit',
241
  'X-Generator' => 'Loco https://localise.biz/',
242
  'X-Loco-Version' => sprintf('%s; wp-%s', loco_plugin_version(), $GLOBALS['wp_version'] ),
243
- );
 
 
 
 
 
 
 
 
 
 
 
 
244
  // set user's preferred Last-Translator credit if configured
245
  if( function_exists('get_current_user_id') && get_current_user_id() ){
246
  $prefs = Loco_data_Preferences::get();
@@ -275,11 +287,11 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
275
  */
276
  public function templatize( $domain = '' ){
277
  $date = gmdate('Y-m-d H:i').'+0000'; // <- forcing UCT
278
- $defaults = array (
279
  'Project-Id-Version' => 'PACKAGE VERSION',
280
  'Report-Msgid-Bugs-To' => '',
281
- );
282
- $required = array (
283
  'POT-Creation-Date' => $date,
284
  'PO-Revision-Date' => 'YEAR-MO-DA HO:MI+ZONE',
285
  'Last-Translator' => 'FULL NAME <EMAIL@ADDRESS>',
@@ -292,7 +304,7 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
292
  'X-Generator' => 'Loco https://localise.biz/',
293
  'X-Loco-Version' => sprintf('%s; wp-%s', loco_plugin_version(), $GLOBALS['wp_version'] ),
294
  'X-Domain' => $domain,
295
- );
296
  $headers = $this->applyHeaders($required,$defaults);
297
  // finally allow headers to be modified via filter
298
  $replaced = apply_filters( 'loco_pot_headers', $headers );
@@ -309,7 +321,7 @@ class Loco_gettext_Data extends LocoPoIterator implements JsonSerializable {
309
  * @param string[] Custom headers
310
  * @return LocoPoHeaders
311
  */
312
- private function applyHeaders( array $required = array(), array $defaults = array(), array $custom = array() ){
313
  $headers = $this->getHeaders();
314
  // only set absent or empty headers from default list
315
  foreach( $defaults as $key => $value ){
88
  * @return Loco_gettext_Data
89
  */
90
  public static function dummy(){
91
+ return new Loco_gettext_Data( [ ['source'=>'','target'=>'Language:'] ] );
92
  }
93
 
94
 
147
  // set maximum line width, zero or >= 15
148
  $this->wrap( Loco_data_Settings::get()->po_width );
149
  // concat with default text sorting if specified
150
+ $po = $this->render( $sort ? [ 'LocoPoIterator', 'compare' ] : null );
151
  // Prepend byte order mark only if configured
152
  if( Loco_data_Settings::get()->po_utf8_bom ){
153
  $po = "\xEF\xBB\xBF".$po;
172
  $json_options |= loco_constant('JSON_PRETTY_PRINT') | loco_constant('JSON_UNESCAPED_SLASHES'); // | loco_constant('JSON_UNESCAPED_UNICODE');
173
  }
174
  // PO should have a date if localised properly
175
+ return json_encode( [
176
  'translation-revision-date' => $head['PO-Revision-Date'],
177
  'generator' => $head['X-Generator'],
178
  'source' => $source,
179
  'domain' => $domain,
180
+ 'locale_data' => [
181
  $domain => $data,
182
+ ],
183
+ ], $json_options );
184
  }
185
 
186
 
220
  * @param string[] custom headers
221
  * @return Loco_gettext_Data
222
  */
223
+ public function localize( Loco_Locale $locale, array $custom = [] ){
224
+ $date = gmdate('Y-m-d H:i').'+0000';
225
  // headers that must always be set if absent
226
+ $defaults = [
227
  'Project-Id-Version' => '',
228
  'Report-Msgid-Bugs-To' => '',
229
  'POT-Creation-Date' => $date,
230
+ ];
231
  // headers that must always override when localizing
232
+ $required = [
233
  'PO-Revision-Date' => $date,
234
  'Last-Translator' => '',
235
  'Language-Team' => $locale->getName(),
240
  'Content-Transfer-Encoding' => '8bit',
241
  'X-Generator' => 'Loco https://localise.biz/',
242
  'X-Loco-Version' => sprintf('%s; wp-%s', loco_plugin_version(), $GLOBALS['wp_version'] ),
243
+ ];
244
+ // Allow some existing headers to remain if PO was previously localized to the same language
245
+ $headers = $this->getHeaders();
246
+ $previous = Loco_Locale::parse( $headers->trimmed('Language') );
247
+ if( $previous->lang === $locale->lang ){
248
+ $header = $headers->trimmed('Plural-Forms');
249
+ if( preg_match('/^\\s*nplurals\\s*=\\s*\\d+\\s*;\\s*plural\\s*=/', $header) ) {
250
+ $required['Plural-Forms'] = $header;
251
+ }
252
+ if( $previous->region === $locale->region && $previous->variant === $locale->variant ){
253
+ unset( $required['Language-Team'] );
254
+ }
255
+ }
256
  // set user's preferred Last-Translator credit if configured
257
  if( function_exists('get_current_user_id') && get_current_user_id() ){
258
  $prefs = Loco_data_Preferences::get();
287
  */
288
  public function templatize( $domain = '' ){
289
  $date = gmdate('Y-m-d H:i').'+0000'; // <- forcing UCT
290
+ $defaults = [
291
  'Project-Id-Version' => 'PACKAGE VERSION',
292
  'Report-Msgid-Bugs-To' => '',
293
+ ];
294
+ $required = [
295
  'POT-Creation-Date' => $date,
296
  'PO-Revision-Date' => 'YEAR-MO-DA HO:MI+ZONE',
297
  'Last-Translator' => 'FULL NAME <EMAIL@ADDRESS>',
304
  'X-Generator' => 'Loco https://localise.biz/',
305
  'X-Loco-Version' => sprintf('%s; wp-%s', loco_plugin_version(), $GLOBALS['wp_version'] ),
306
  'X-Domain' => $domain,
307
+ ];
308
  $headers = $this->applyHeaders($required,$defaults);
309
  // finally allow headers to be modified via filter
310
  $replaced = apply_filters( 'loco_pot_headers', $headers );
321
  * @param string[] Custom headers
322
  * @return LocoPoHeaders
323
  */
324
+ private function applyHeaders( array $required = [], array $defaults = [], array $custom = [] ){
325
  $headers = $this->getHeaders();
326
  // only set absent or empty headers from default list
327
  foreach( $defaults as $key => $value ){
src/gettext/Extraction.php CHANGED
@@ -48,7 +48,7 @@ class Loco_gettext_Extraction {
48
  $this->bundle = $bundle;
49
  $this->extracted = new LocoExtracted;
50
  $this->extracted->setDomain('default');
51
- $this->extras = array();
52
  $default = $bundle->getDefaultProject();
53
  if( $default instanceof Loco_package_Project ){
54
  $domain = $default->getDomain()->getName();
@@ -59,12 +59,12 @@ class Loco_gettext_Extraction {
59
  $this->extracted->setDomain('');
60
  }
61
  // pull bundle's default metadata. these are translations that may not be encountered in files
62
- $extras = array();
63
  $header = $bundle->getHeaderInfo();
64
  foreach( $bundle->getMetaTranslatable() as $prop => $notes ){
65
  if( $source = $header->__get($prop) ){
66
  if( is_string($source) ){
67
- $extras[] = array( $source, $notes );
68
  }
69
  }
70
  }
@@ -105,9 +105,9 @@ class Loco_gettext_Extraction {
105
  }
106
  // extract headers from theme PHP files in
107
  if( $project->getBundle()->isTheme() ){
108
- $extr->headerize( array (
109
  'Template Name' => 'Name of the template',
110
- ), (string) $project->getDomain() );
111
  }
112
  }
113
  $this->extracted->extractSource( $extr, $file->getContents(), $file->getRelativePath( $base ) );
@@ -126,7 +126,7 @@ class Loco_gettext_Extraction {
126
  $this->extracted->pushMeta( $args[0], $args[1], $domain );
127
  }
128
  }
129
- $this->extras = array();
130
  return $this;
131
  }
132
 
48
  $this->bundle = $bundle;
49
  $this->extracted = new LocoExtracted;
50
  $this->extracted->setDomain('default');
51
+ $this->extras = [];
52
  $default = $bundle->getDefaultProject();
53
  if( $default instanceof Loco_package_Project ){
54
  $domain = $default->getDomain()->getName();
59
  $this->extracted->setDomain('');
60
  }
61
  // pull bundle's default metadata. these are translations that may not be encountered in files
62
+ $extras = [];
63
  $header = $bundle->getHeaderInfo();
64
  foreach( $bundle->getMetaTranslatable() as $prop => $notes ){
65
  if( $source = $header->__get($prop) ){
66
  if( is_string($source) ){
67
+ $extras[] = [ $source, $notes ];
68
  }
69
  }
70
  }
105
  }
106
  // extract headers from theme PHP files in
107
  if( $project->getBundle()->isTheme() ){
108
+ $extr->headerize( [
109
  'Template Name' => 'Name of the template',
110
+ ], (string) $project->getDomain() );
111
  }
112
  }
113
  $this->extracted->extractSource( $extr, $file->getContents(), $file->getRelativePath( $base ) );
126
  $this->extracted->pushMeta( $args[0], $args[1], $domain );
127
  }
128
  }
129
+ $this->extras = [];
130
  return $this;
131
  }
132
 
src/gettext/Matcher.php CHANGED
@@ -67,7 +67,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
67
  // TODO handle empty msgid case that uses weird "msgctxt\4(msgctxt)" format?
68
  }
69
  // string may exist in original template, and also in multiple JSONs.
70
- $new = array('source'=>$msgid,'context'=>$msgctxt,'refs'=>$ref );
71
  $old = $this->getArrayRef($new);
72
  if( $old ){
73
  $refs = array_key_exists('refs',$old) ? (string) $old['refs'] : '';
@@ -91,7 +91,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
91
  // handle plurals, noting that msgid_plural is not stored in JED structure
92
  if( 1 < count($arr) ){
93
  $index = 0;
94
- $plurals = $old && array_key_exists('plurals',$old) ? $old['plurals'] : array();
95
  while( array_key_exists(++$index,$arr) ){
96
  if( array_key_exists($index,$plurals) ){
97
  $raw = $plurals[$index];
@@ -100,7 +100,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
100
  }
101
  }
102
  else {
103
- $raw = array('source'=>'','target'=>'');
104
  }
105
  if( $this->translate && ( ! array_key_exists('target',$raw) || '' === $raw['target'] ) ){
106
  $raw['target'] = $arr[$index];
@@ -150,7 +150,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
150
  * @return string[] keys matched exactly
151
  */
152
  public function mergeValid( LocoPoIterator $original, LocoPoIterator $merged ){
153
- $valid = array();
154
  $translate = $this->translate;
155
  /* @var LocoPoMessage $old */
156
  foreach( $original as $old ){
@@ -177,7 +177,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
177
  * @return string[] strings fuzzy-matched
178
  */
179
  public function mergeFuzzy( LocoPoIterator $merged ){
180
- $fuzzy = array();
181
  foreach( $this->getFuzzyMatches() as $pair ){
182
  list($old,$new) = $pair;
183
  $p = clone $old;
@@ -195,7 +195,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
195
  * @return string[] strings added
196
  */
197
  public function mergeAdded( LocoPoIterator $merged ){
198
- $added = array();
199
  $translate = $this->translate;
200
  /* @var LocoPoMessage $new */
201
  foreach( $this->unmatched() as $new ){
@@ -222,17 +222,17 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
222
  $fuzzy = $this->mergeFuzzy($merged);
223
  $added = $this->mergeAdded($merged);
224
  /* @var LocoPoMessage $old */
225
- $dropped = array();
226
  foreach( $this->redundant() as $old ){
227
  $dropped[] = $old->getKey();
228
  }
229
  // return to JavaScript with stats in the same form as old front end merge
230
- return array (
231
  'add' => $added,
232
  'fuz' => $fuzzy,
233
  'del' => $dropped,
234
  'trn' => $this->translated,
235
- );
236
  }
237
 
238
 
@@ -243,7 +243,7 @@ class Loco_gettext_Matcher extends LocoFuzzyMatcher {
243
  private function getArrayRef( array $a ){
244
  $r = $this->getRef($a);
245
  if( is_null($r) ){
246
- return array();
247
  }
248
  if( $r instanceof ArrayObject ){
249
  return $r->getArrayCopy();
67
  // TODO handle empty msgid case that uses weird "msgctxt\4(msgctxt)" format?
68
  }
69
  // string may exist in original template, and also in multiple JSONs.
70
+ $new = ['source'=>$msgid,'context'=>$msgctxt,'refs'=>$ref ];
71
  $old = $this->getArrayRef($new);
72
  if( $old ){
73
  $refs = array_key_exists('refs',$old) ? (string) $old['refs'] : '';
91
  // handle plurals, noting that msgid_plural is not stored in JED structure
92
  if( 1 < count($arr) ){
93
  $index = 0;
94
+ $plurals = $old && array_key_exists('plurals',$old) ? $old['plurals'] : [];
95
  while( array_key_exists(++$index,$arr) ){
96
  if( array_key_exists($index,$plurals) ){
97
  $raw = $plurals[$index];
100
  }
101
  }
102
  else {
103
+ $raw = ['source'=>'','target'=>''];
104
  }
105
  if( $this->translate && ( ! array_key_exists('target',$raw) || '' === $raw['target'] ) ){
106
  $raw['target'] = $arr[$index];
150
  * @return string[] keys matched exactly
151
  */
152
  public function mergeValid( LocoPoIterator $original, LocoPoIterator $merged ){
153
+ $valid = [];
154
  $translate = $this->translate;
155
  /* @var LocoPoMessage $old */
156
  foreach( $original as $old ){
177
  * @return string[] strings fuzzy-matched
178
  */
179
  public function mergeFuzzy( LocoPoIterator $merged ){
180
+ $fuzzy = [];
181
  foreach( $this->getFuzzyMatches() as $pair ){
182
  list($old,$new) = $pair;
183
  $p = clone $old;
195
  * @return string[] strings added
196
  */
197
  public function mergeAdded( LocoPoIterator $merged ){
198
+ $added = [];
199
  $translate = $this->translate;
200
  /* @var LocoPoMessage $new */
201
  foreach( $this->unmatched() as $new ){
222
  $fuzzy = $this->mergeFuzzy($merged);
223
  $added = $this->mergeAdded($merged);
224
  /* @var LocoPoMessage $old */
225
+ $dropped = [];
226
  foreach( $this->redundant() as $old ){
227
  $dropped[] = $old->getKey();
228
  }
229
  // return to JavaScript with stats in the same form as old front end merge
230
+ return [
231
  'add' => $added,
232
  'fuz' => $fuzzy,
233
  'del' => $dropped,
234
  'trn' => $this->translated,
235
+ ];
236
  }
237
 
238
 
243
  private function getArrayRef( array $a ){
244
  $r = $this->getRef($a);
245
  if( is_null($r) ){
246
+ return [];
247
  }
248
  if( $r instanceof ArrayObject ){
249
  return $r->getArrayCopy();
src/gettext/Metadata.php CHANGED
@@ -57,9 +57,9 @@ class Loco_gettext_Metadata extends Loco_data_Transient {
57
  $bytes = $po->size();
58
  $mtime = $po->modified();
59
  // quick construct of new meta object. enough to query and validate cache
60
- $meta = new Loco_gettext_Metadata( array(
61
  'rpath' => $po->getRelativePath( loco_constant('WP_CONTENT_DIR') ),
62
- ) );
63
  // pull from cache if exists and has not been modified
64
  if( $nocache || ! $meta->fetch() || $bytes !== $meta['bytes'] || $mtime !== $meta['mtime'] ){
65
  // not available from cache, or cache is invalidated
@@ -95,12 +95,12 @@ class Loco_gettext_Metadata extends Loco_data_Transient {
95
  * @return Loco_gettext_Metadata
96
  */
97
  public static function create( Loco_fs_File $file, Loco_gettext_Data $data ){
98
- return new Loco_gettext_Metadata( array (
99
  'valid' => true,
100
  'bytes' => $file->size(),
101
  'mtime' => $file->modified(),
102
  'stats' => self::stats( $data->getArrayCopy() ),
103
- ) );
104
  }
105
 
106
 
@@ -114,7 +114,7 @@ class Loco_gettext_Metadata extends Loco_data_Transient {
114
  return $this['stats'];
115
  }
116
  // fallback to empty stats
117
- return array( 't' => 0, 'p' => 0, 'f' => 0 );
118
  }
119
 
120
 
@@ -200,7 +200,7 @@ class Loco_gettext_Metadata extends Loco_data_Transient {
200
  * @return string
201
  */
202
  public function getProgressSummary(){
203
- $extra = array();
204
  $stext = sprintf( __('%s%% translated','loco-translate'), $this->getPercent() ).', '.$this->getTotalSummary();
205
  if( $num = $this->countFuzzy() ){
206
  $extra[] = sprintf( __('%s fuzzy','loco-translate'), number_format($num) );
57
  $bytes = $po->size();
58
  $mtime = $po->modified();
59
  // quick construct of new meta object. enough to query and validate cache
60
+ $meta = new Loco_gettext_Metadata( [
61
  'rpath' => $po->getRelativePath( loco_constant('WP_CONTENT_DIR') ),
62
+ ] );
63
  // pull from cache if exists and has not been modified
64
  if( $nocache || ! $meta->fetch() || $bytes !== $meta['bytes'] || $mtime !== $meta['mtime'] ){
65
  // not available from cache, or cache is invalidated
95
  * @return Loco_gettext_Metadata
96
  */
97
  public static function create( Loco_fs_File $file, Loco_gettext_Data $data ){
98
+ return new Loco_gettext_Metadata( [
99
  'valid' => true,
100
  'bytes' => $file->size(),
101
  'mtime' => $file->modified(),
102
  'stats' => self::stats( $data->getArrayCopy() ),
103
+ ] );
104
  }
105
 
106
 
114
  return $this['stats'];
115
  }
116
  // fallback to empty stats
117
+ return [ 't' => 0, 'p' => 0, 'f' => 0 ];
118
  }
119
 
120
 
200
  * @return string
201
  */
202
  public function getProgressSummary(){
203
+ $extra = [];
204
  $stext = sprintf( __('%s%% translated','loco-translate'), $this->getPercent() ).', '.$this->getTotalSummary();
205
  if( $num = $this->countFuzzy() ){
206
  $extra[] = sprintf( __('%s fuzzy','loco-translate'), number_format($num) );
src/gettext/SearchPaths.php CHANGED
@@ -34,7 +34,7 @@ class Loco_gettext_SearchPaths extends Loco_fs_FileFinder {
34
  $head = LocoPoHeaders::fromSource( $pofile->getContents() );
35
  }
36
  $ninc = 0;
37
- foreach( array('Poedit') as $vendor ){
38
  $key = 'X-'.$vendor.'-Basepath';
39
  if( ! $head->has($key) ){
40
  continue;
34
  $head = LocoPoHeaders::fromSource( $pofile->getContents() );
35
  }
36
  $ninc = 0;
37
+ foreach( ['Poedit'] as $vendor ){
38
  $key = 'X-'.$vendor.'-Basepath';
39
  if( ! $head->has($key) ){
40
  continue;
src/gettext/String.php CHANGED
@@ -22,10 +22,10 @@ class Loco_gettext_String {
22
  * @param string Optional context
23
  */
24
  public function __construct( $msgid, $msgctxt = '' ){
25
- $this->raw = array (
26
  'source' => (string) $msgid,
27
  'context' => (string) $msgctxt,
28
- );
29
  }
30
 
31
 
@@ -45,9 +45,9 @@ class Loco_gettext_String {
45
  * @return string[]
46
  */
47
  public function exportPlural(){
48
- return array (
49
  'source' => $this->plural,
50
- );
51
  }
52
 
53
 
@@ -59,7 +59,7 @@ class Loco_gettext_String {
59
  */
60
  private function merge( $prop, $value, $glue ){
61
  if( is_string($value) ){
62
- $value = array($value);
63
  }
64
  else if( ! is_array($value) ){
65
  throw new InvalidArgumentException('Expected Array or String');
22
  * @param string Optional context
23
  */
24
  public function __construct( $msgid, $msgctxt = '' ){
25
+ $this->raw = [
26
  'source' => (string) $msgid,
27
  'context' => (string) $msgctxt,
28
+ ];
29
  }
30
 
31
 
45
  * @return string[]
46
  */
47
  public function exportPlural(){
48
+ return [
49
  'source' => $this->plural,
50
+ ];
51
  }
52
 
53
 
59
  */
60
  private function merge( $prop, $value, $glue ){
61
  if( is_string($value) ){
62
+ $value = [$value];
63
  }
64
  else if( ! is_array($value) ){
65
  throw new InvalidArgumentException('Expected Array or String');
src/hooks/AdminHooks.php CHANGED
@@ -24,7 +24,7 @@ class Loco_hooks_AdminHooks extends Loco_hooks_Hookable {
24
  */
25
  public function __construct(){
26
  // renders failure notice if plugin failed to start up admin hooks.
27
- add_action( 'admin_notices', array(__CLASS__,'print_hook_failure') );
28
  // initialize hooks
29
  parent::__construct();
30
  // Ajax router will be called directly in tests
@@ -64,7 +64,7 @@ class Loco_hooks_AdminHooks extends Loco_hooks_Hookable {
64
  esc_html( __("This plugin doesn't collect any data from public website visitors.",'loco-translate') ).'<br />'.
65
  wp_kses(
66
  sprintf( __('Administrators and auditors may wish to review Loco\'s <a href="%s">plugin privacy notice</a>.','loco-translate'), esc_url($url) ),
67
- array('a'=>array('href'=>true)), array('https')
68
  )
69
  );
70
  }
@@ -81,7 +81,7 @@ class Loco_hooks_AdminHooks extends Loco_hooks_Hookable {
81
  load_plugin_textdomain( 'loco-translate', false, $domainPath );
82
  }
83
  // Unhook failure notice that would fire if this hook was not successful
84
- remove_action( 'admin_notices', array(__CLASS__,'print_hook_failure') );
85
  }
86
 
87
 
@@ -96,10 +96,10 @@ class Loco_hooks_AdminHooks extends Loco_hooks_Hookable {
96
  if( $plugin && current_user_can('loco_admin') && Loco_package_Plugin::get_plugin($plugin) ){
97
  // coerce links to array
98
  if( ! is_array($links) ){
99
- $links = $links && is_string($links) ? (array) $links : array();
100
  }
101
  // ok to add "translate" link into meta row
102
- $href = Loco_mvc_AdminRouter::generate('plugin-view', array( 'bundle' => $plugin) );
103
  $links[] = '<a href="'.esc_attr($href).'">'.esc_html__('Translate','loco-translate').'</a>';
104
  }
105
  }
24
  */
25
  public function __construct(){
26
  // renders failure notice if plugin failed to start up admin hooks.
27
+ add_action( 'admin_notices', [__CLASS__,'print_hook_failure'] );
28
  // initialize hooks
29
  parent::__construct();
30
  // Ajax router will be called directly in tests
64
  esc_html( __("This plugin doesn't collect any data from public website visitors.",'loco-translate') ).'<br />'.
65
  wp_kses(
66
  sprintf( __('Administrators and auditors may wish to review Loco\'s <a href="%s">plugin privacy notice</a>.','loco-translate'), esc_url($url) ),
67
+ ['a'=>['href'=>true]], ['https']
68
  )
69
  );
70
  }
81
  load_plugin_textdomain( 'loco-translate', false, $domainPath );
82
  }
83
  // Unhook failure notice that would fire if this hook was not successful
84
+ remove_action( 'admin_notices', [__CLASS__,'print_hook_failure'] );
85
  }
86
 
87
 
96
  if( $plugin && current_user_can('loco_admin') && Loco_package_Plugin::get_plugin($plugin) ){
97
  // coerce links to array
98
  if( ! is_array($links) ){
99
+ $links = $links && is_string($links) ? (array) $links : [];
100
  }
101
  // ok to add "translate" link into meta row
102
+ $href = Loco_mvc_AdminRouter::generate('plugin-view', [ 'bundle' => $plugin] );
103
  $links[] = '<a href="'.esc_attr($href).'">'.esc_html__('Translate','loco-translate').'</a>';
104
  }
105
  }
src/hooks/Hookable.php CHANGED
@@ -19,7 +19,7 @@ abstract class Loco_hooks_Hookable {
19
  public function __construct(){
20
 
21
  $ref = new ReflectionClass( $this );
22
- $reg = array();
23
  foreach( $ref->getMethods( ReflectionMethod::IS_PUBLIC ) as $method ){
24
  $func = $method->name;
25
  // support filter_{filter_hook} methods
@@ -43,9 +43,9 @@ abstract class Loco_hooks_Hookable {
43
  // call add_action or add_filter with required arguments and hook is registered
44
  // add_action actually calls add_filter, although unsure how long that's been the case.
45
  $num_args = $method->getNumberOfParameters();
46
- add_filter( $hook, array( $this, $func ), $priority, $num_args );
47
  // register hook for destruction so object can be removed from memory
48
- $reg[] = array( $hook, $func, $priority );
49
  }
50
 
51
  $this->hooks = $reg;
@@ -59,7 +59,7 @@ abstract class Loco_hooks_Hookable {
59
  public function unhook(){
60
  if( is_array($this->hooks) ){
61
  foreach( $this->hooks as $r ){
62
- remove_filter( $r[0], array($this,$r[1]), $r[2] );
63
  }
64
  }
65
  $this->hooks = null;
19
  public function __construct(){
20
 
21
  $ref = new ReflectionClass( $this );
22
+ $reg = [];
23
  foreach( $ref->getMethods( ReflectionMethod::IS_PUBLIC ) as $method ){
24
  $func = $method->name;
25
  // support filter_{filter_hook} methods
43
  // call add_action or add_filter with required arguments and hook is registered
44
  // add_action actually calls add_filter, although unsure how long that's been the case.
45
  $num_args = $method->getNumberOfParameters();
46
+ add_filter( $hook, [ $this, $func ], $priority, $num_args );
47
  // register hook for destruction so object can be removed from memory
48
+ $reg[] = [ $hook, $func, $priority ];
49
  }
50
 
51
  $this->hooks = $reg;
59
  public function unhook(){
60
  if( is_array($this->hooks) ){
61
  foreach( $this->hooks as $r ){
62
+ remove_filter( $r[0], [$this,$r[1]], $r[2] );
63
  }
64
  }
65
  $this->hooks = null;
src/hooks/LoadHelper.php CHANGED
@@ -43,8 +43,8 @@ class Loco_hooks_LoadHelper extends Loco_hooks_Hookable {
43
  */
44
  public function __construct(){
45
  parent::__construct();
46
- $this->lock = array();
47
- $this->json = array();
48
  $this->base = trailingslashit( loco_constant('LOCO_LANG_DIR') );
49
  // add system locations which have direct equivalent custom/safe locations under LOCO_LANG_DIR
50
  // not adding theme paths because as long as load_theme_textdomain is used they will be mapped by context.
@@ -63,7 +63,7 @@ class Loco_hooks_LoadHelper extends Loco_hooks_Hookable {
63
  private function add( $subdir, $path ){
64
  if( $path ){
65
  $path = trailingslashit($path);
66
- $this->map[] = array( $subdir, $path, strlen($path) );
67
  }
68
  return $this;
69
  }
@@ -98,7 +98,7 @@ class Loco_hooks_LoadHelper extends Loco_hooks_Hookable {
98
  * @return string
99
  */
100
  public function filter_theme_locale( $locale, $domain = '' ){
101
- $this->context = array( 'themes/', $domain, $locale );
102
  unset( $this->lock[$domain] );
103
  return $locale;
104
  }
@@ -112,7 +112,7 @@ class Loco_hooks_LoadHelper extends Loco_hooks_Hookable {
112
  * @return string
113
  */
114
  public function filter_plugin_locale( $locale, $domain = '' ){
115
- $this->context = array( 'plugins/', $domain, $locale );
116
  unset( $this->lock[$domain] );
117
  return $locale;
118
  }
@@ -236,9 +236,9 @@ class Loco_hooks_LoadHelper extends Loco_hooks_Hookable {
236
  // $overrideMessages[''] += $fallbackMessages[''];
237
  // Continuing to use "messages" here as per WordPress. Good backward compatibility is likely.
238
  // Note that our custom JED is sparse (exported with empty keys absent). This is essential for + operator.
239
- $overrideJed['locale_data'] = array (
240
  'messages' => $overrideMessages + $fallbackMessages,
241
- );
242
  // Note that envelope will be the custom one. No functional difference but demonstrates that merge worked.
243
  $overrideJed['merged'] = true;
244
  $json = json_encode($overrideJed);
43
  */
44
  public function __construct(){
45
  parent::__construct();
46
+ $this->lock = [];
47
+ $this->json = [];
48
  $this->base = trailingslashit( loco_constant('LOCO_LANG_DIR') );
49
  // add system locations which have direct equivalent custom/safe locations under LOCO_LANG_DIR
50
  // not adding theme paths because as long as load_theme_textdomain is used they will be mapped by context.
63
  private function add( $subdir, $path ){
64
  if( $path ){
65
  $path = trailingslashit($path);
66
+ $this->map[] = [ $subdir, $path, strlen($path) ];
67
  }
68
  return $this;
69
  }
98
  * @return string
99
  */
100
  public function filter_theme_locale( $locale, $domain = '' ){
101
+ $this->context = [ 'themes/', $domain, $locale ];
102
  unset( $this->lock[$domain] );
103
  return $locale;
104
  }
112
  * @return string
113
  */
114
  public function filter_plugin_locale( $locale, $domain = '' ){
115
+ $this->context = [ 'plugins/', $domain, $locale ];
116
  unset( $this->lock[$domain] );
117
  return $locale;
118
  }
236
  // $overrideMessages[''] += $fallbackMessages[''];
237
  // Continuing to use "messages" here as per WordPress. Good backward compatibility is likely.
238
  // Note that our custom JED is sparse (exported with empty keys absent). This is essential for + operator.
239
+ $overrideJed['locale_data'] = [
240
  'messages' => $overrideMessages + $fallbackMessages,
241
+ ];
242
  // Note that envelope will be the custom one. No functional difference but demonstrates that merge worked.
243
  $overrideJed['merged'] = true;
244
  $json = json_encode($overrideJed);
src/hooks/TranslateBuffer.php CHANGED
@@ -9,7 +9,7 @@ class Loco_hooks_TranslateBuffer extends Loco_hooks_Hookable {
9
  * Temporary buffer of raw translation lookupkeys
10
  * @var array
11
  */
12
- private $buffer = array();
13
 
14
  /**
15
  * `gettext` filter callback
@@ -54,7 +54,7 @@ class Loco_hooks_TranslateBuffer extends Loco_hooks_Hookable {
54
  * @return array
55
  */
56
  public function flush( $domain ){
57
- $export = array();
58
  if( isset($this->buffer[$domain]) ){
59
  // what we captures was just a unique namespace
60
  $captured = $this->buffer[$domain];
9
  * Temporary buffer of raw translation lookupkeys
10
  * @var array
11
  */
12
+ private $buffer = [];
13
 
14
  /**
15
  * `gettext` filter callback
54
  * @return array
55
  */
56
  public function flush( $domain ){
57
+ $export = [];
58
  if( isset($this->buffer[$domain]) ){
59
  // what we captures was just a unique namespace
60
  $captured = $this->buffer[$domain];
src/mvc/AdminController.php CHANGED
@@ -24,7 +24,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
24
  /**
25
  * @var string[]
26
  */
27
- private $scripts = array();
28
 
29
 
30
  /**
@@ -70,7 +70,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
70
  $this->baseurl = plugins_url( '', loco_plugin_self() );
71
 
72
  // add common admin page resources
73
- $this->enqueueStyle('admin', array('wp-jquery-ui-dialog') );
74
 
75
  // load colour scheme is user has non-default
76
  $skin = get_user_option('admin_color');
@@ -79,7 +79,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
79
  }
80
 
81
  // core minimized admin.js loaded on all pages before any other Loco scripts
82
- $this->enqueueScript('admin', array('jquery-ui-dialog') );
83
 
84
  $this->init();
85
  return $this;
@@ -134,7 +134,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
134
  public function filter_loco_external( $url ){
135
  $u = parse_url( $url );
136
  if( isset($u['host']) && 'localise.biz' === $u['host'] ){
137
- $query = http_build_query( array( 'utm_medium' => 'plugin', 'utm_campaign' => 'wp', 'utm_source' => 'admin', 'utm_content' => $this->get('_route') ) );
138
  $url = 'https://localise.biz'.$u['path'];
139
  if( isset($u['query']) ){
140
  $url .= '?'. $u['query'].'&'.$query;
@@ -155,7 +155,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
155
  * @return array
156
  */
157
  public function getHelpTabs(){
158
- return array();
159
  }
160
 
161
 
@@ -183,7 +183,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
183
  * @param array template arguments
184
  * @return string
185
  */
186
- public function view( $tpl, array $args = array() ){
187
  /*if( ! $this->baseurl ){
188
  throw new Loco_error_Debug('Did you mean to call $this->viewSnippet('.json_encode($tpl,JSON_UNESCAPED_SLASHES).') in '.get_class($this).'?');
189
  }*/
@@ -205,7 +205,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
205
  if( $jsConf instanceof Loco_mvc_ViewParams ){
206
  // ensure config has access to latest version information
207
  // we will use this to ensure scripts are not cached by browser, or hijacked by other plugins
208
- $jsConf->offsetSet('$v', array( loco_plugin_version(), $GLOBALS['wp_version']) );
209
  $jsConf->offsetSet('$js', array_keys($this->scripts) );
210
  $jsConf->offsetSet('WP_DEBUG', loco_debugging() );
211
  // localize script if translations in memory
@@ -222,18 +222,14 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
222
  // localized formatting from core translations
223
  global $wp_locale;
224
  if( is_object($wp_locale) && property_exists($wp_locale,'number_format') ){
225
- $jsConf->offsetSet('wpnum', array_map(array($this,'filter_number_format_i18n'),$wp_locale->number_format) );
226
  }
227
  }
228
  // take benchmark for debugger to be rendered in footer
229
  if( $this->bench ){
230
- $this->set('_debug', new Loco_mvc_ViewParams( array(
231
  'time' => microtime(true) - $this->bench,
232
- ) ) );
233
- }
234
- // add urgent deprecation warning. Next version of Loco Translate will not run below these versions.
235
- if( version_compare(PHP_VERSION,'5.6.20','<') || version_compare($GLOBALS['wp_version'],'5.2','<') ){
236
- $this->set('_deprecation', true );
237
  }
238
 
239
  return $view->render( $tpl );
@@ -256,7 +252,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
256
  * @param string[] dependencies of this stylesheet
257
  * @return Loco_mvc_Controller
258
  */
259
- public function enqueueStyle( $name, array $deps = array() ){
260
  $base = $this->baseurl;
261
  if( ! $base ){
262
  throw new Loco_error_Exception('Too early to enqueueStyle('.var_export($name,1).')');
@@ -276,7 +272,7 @@ abstract class Loco_mvc_AdminController extends Loco_mvc_Controller {
276
  * @param string[] dependencies of this script
277
  * @return Loco_mvc_Controller
278
  */
279
- public function enqueueScript( $name, array $deps = array() ){
280
  $base = $this->baseurl;
281
  if( ! $base ){
282
  throw new Loco_error_Exception('Too early to enqueueScript('.json_encode($name).')');
24
  /**
25
  * @var string[]
26
  */
27
+ private $scripts = [];
28
 
29
 
30
  /**
70
  $this->baseurl = plugins_url( '', loco_plugin_self() );
71
 
72
  // add common admin page resources
73
+ $this->enqueueStyle('admin', ['wp-jquery-ui-dialog'] );
74
 
75
  // load colour scheme is user has non-default
76
  $skin = get_user_option('admin_color');
79
  }
80
 
81
  // core minimized admin.js loaded on all pages before any other Loco scripts
82
+ $this->enqueueScript('admin', ['jquery-ui-dialog'] );
83
 
84
  $this->init();
85
  return $this;
134
  public function filter_loco_external( $url ){
135
  $u = parse_url( $url );
136
  if( isset($u['host']) && 'localise.biz' === $u['host'] ){
137
+ $query = http_build_query( [ 'utm_medium' => 'plugin', 'utm_campaign' => 'wp', 'utm_source' => 'admin', 'utm_content' => $this->get('_route') ] );
138
  $url = 'https://localise.biz'.$u['path'];
139
  if( isset($u['query']) ){
140
  $url .= '?'. $u['query'].'&'.$query;
155
  * @return array
156
  */
157
  public function getHelpTabs(){
158
+ return [];
159
  }
160
 
161
 
183
  * @param array template arguments
184
  * @return string
185
  */
186
+ public function view( $tpl, array $args = [] ){
187
  /*if( ! $this->baseurl ){
188
  throw new Loco_error_Debug('Did you mean to call $this->viewSnippet('.json_encode($tpl,JSON_UNESCAPED_SLASHES).') in '.get_class($this).'?');
189
  }*/
205
  if( $jsConf instanceof Loco_mvc_ViewParams ){
206
  // ensure config has access to latest version information
207
  // we will use this to ensure scripts are not cached by browser, or hijacked by other plugins
208
+ $jsConf->offsetSet('$v', [ loco_plugin_version(), $GLOBALS['wp_version']] );
209
  $jsConf->offsetSet('$js', array_keys($this->scripts) );
210
  $jsConf->offsetSet('WP_DEBUG', loco_debugging() );
211
  // localize script if translations in memory
222
  // localized formatting from core translations
223
  global $wp_locale;
224
  if( is_object($wp_locale) && property_exists($wp_locale,'number_format') ){
225
+ $jsConf->offsetSet('wpnum', array_map([$this,'filter_number_format_i18n'],$wp_locale->number_format) );
226
  }
227
  }
228
  // take benchmark for debugger to be rendered in footer
229
  if( $this->bench ){
230
+ $this->set('_debug', new Loco_mvc_ViewParams( [
231
  'time' => microtime(true) - $this->bench,
232
+ ] ) );
 
 
 
 
233
  }
234
 
235
  return $view->render( $tpl );
252
  * @param string[] dependencies of this stylesheet
253
  * @return Loco_mvc_Controller
254
  */
255
+ public function enqueueStyle( $name, array $deps = [] ){
256
  $base = $this->baseurl;
257
  if( ! $base ){
258
  throw new Loco_error_Exception('Too early to enqueueStyle('.var_export($name,1).')');
272
  * @param string[] dependencies of this script
273
  * @return Loco_mvc_Controller
274
  */
275
+ public function enqueueScript( $name, array $deps = [] ){
276
  $base = $this->baseurl;
277
  if( ! $base ){
278
  throw new Loco_error_Exception('Too early to enqueueScript('.json_encode($name).')');
src/mvc/AdminRouter.php CHANGED
@@ -29,7 +29,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
29
  }
30
 
31
  // rendering hook for all menu items
32
- $render = array( $this, 'renderPage' );
33
 
34
  // main loco pages, hooking only if has permission
35
  if( $user->has_cap($cap) ){
@@ -96,7 +96,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
96
  */
97
  public function initPage( WP_Screen $screen, $action = '' ){
98
  $class = null;
99
- $args = array ();
100
  // suppress error display when establishing Loco page
101
  $page = self::screenToPage($screen);
102
  if( is_string($page) ){
@@ -130,7 +130,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
130
  $this->ctrl = new Loco_admin_ErrorController;
131
  // can't afford an error during an error
132
  try {
133
- $this->ctrl->_init( array( 'error' => $e ) );
134
  }
135
  catch( Exception $_e ){
136
  Loco_error_AdminNotices::debug( $_e->getMessage() );
@@ -173,7 +173,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
173
  * @return string|null
174
  */
175
  private static function pageToClass( $page, $action, array &$args ){
176
- $routes = array (
177
  '' => 'Root',
178
  'debug' => 'Debug',
179
  // site-wide plugin configurations
@@ -207,7 +207,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
207
  '{type}-file-delete' => 'file_Delete',
208
  // test routes that don't actually exist
209
  'test-no-class' => 'test_NonExistantClass',
210
- );
211
  if( ! $page ){
212
  $page = $action;
213
  }
@@ -246,7 +246,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
246
  catch( Exception $e ){
247
  $ctrl = new Loco_admin_ErrorController;
248
  try {
249
- $ctrl->_init( array() );
250
  }
251
  catch( Exception $_e ){
252
  // avoid errors during error rendering
@@ -266,7 +266,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
266
  * @param array
267
  * @return string
268
  */
269
- public static function generate( $route, array $args = array() ){
270
  $url = null;
271
  $page = null;
272
  $action = null;
@@ -291,7 +291,7 @@ class Loco_mvc_AdminRouter extends Loco_hooks_Hookable {
291
  }
292
  // sanitize extended route in debug mode only. useful in tests
293
  if( loco_debugging() ){
294
- $tmp = array();
295
  $class = self::pageToClass( (string) substr($page,5), $action, $tmp );
296
  if( ! $class ){
297
  throw new UnexpectedValueException( sprintf('Invalid admin route: %s', json_encode($route) ) );
29
  }
30
 
31
  // rendering hook for all menu items
32
+ $render = [ $this, 'renderPage' ];
33
 
34
  // main loco pages, hooking only if has permission
35
  if( $user->has_cap($cap) ){
96
  */
97
  public function initPage( WP_Screen $screen, $action = '' ){
98
  $class = null;
99
+ $args = [];
100
  // suppress error display when establishing Loco page
101
  $page = self::screenToPage($screen);
102
  if( is_string($page) ){
130
  $this->ctrl = new Loco_admin_ErrorController;
131
  // can't afford an error during an error
132
  try {
133
+ $this->ctrl->_init( [ 'error' => $e ] );
134
  }
135
  catch( Exception $_e ){
136
  Loco_error_AdminNotices::debug( $_e->getMessage() );
173
  * @return string|null
174
  */
175
  private static function pageToClass( $page, $action, array &$args ){
176
+ $routes = [
177
  '' => 'Root',
178
  'debug' => 'Debug',
179
  // site-wide plugin configurations
207
  '{type}-file-delete' => 'file_Delete',
208
  // test routes that don't actually exist
209
  'test-no-class' => 'test_NonExistantClass',
210
+ ];
211
  if( ! $page ){
212
  $page = $action;
213
  }
246
  catch( Exception $e ){
247
  $ctrl = new Loco_admin_ErrorController;
248
  try {
249
+ $ctrl->_init( [] );
250
  }
251
  catch( Exception $_e ){
252
  // avoid errors during error rendering
266
  * @param array
267
  * @return string
268
  */
269
+ public static function generate( $route, array $args = [] ){
270
  $url = null;
271
  $page = null;
272
  $action = null;
291
  }
292
  // sanitize extended route in debug mode only. useful in tests
293
  if( loco_debugging() ){
294
+ $tmp = [];
295
  $class = self::pageToClass( (string) substr($page,5), $action, $tmp );
296
  if( ! $class ){
297
  throw new UnexpectedValueException( sprintf('Invalid admin route: %s', json_encode($route) ) );
src/mvc/AjaxController.php CHANGED
@@ -65,9 +65,9 @@ abstract class Loco_mvc_AjaxController extends Loco_mvc_Controller {
65
  * @return string JSON
66
  */
67
  public function render(){
68
- $data = array (
69
  'data' => $this->output->getArrayCopy(),
70
- );
71
  // non-fatal notices deliberately not in "error" key
72
  $array = Loco_error_AdminNotices::destroyAjax();
73
  if( $array && is_array($array) ){
65
  * @return string JSON
66
  */
67
  public function render(){
68
+ $data = [
69
  'data' => $this->output->getArrayCopy(),
70
+ ];
71
  // non-fatal notices deliberately not in "error" key
72
  $array = Loco_error_AdminNotices::destroyAjax();
73
  if( $array && is_array($array) ){
src/mvc/AjaxRouter.php CHANGED
@@ -21,16 +21,16 @@ class Loco_mvc_AjaxRouter extends Loco_hooks_Hookable {
21
  * @param array
22
  * @return string
23
  */
24
- public static function generate( $route, array $args = array() ){
25
  // validate route autoload if debugging
26
  if( loco_debugging() ){
27
  class_exists( self::routeToClass($route) );
28
  }
29
- $args += array (
30
  'route' => $route,
31
  'action' => 'loco_ajax',
32
  'loco-nonce' => wp_create_nonce($route),
33
- );
34
  return admin_url('admin-ajax.php','relative').'?'.http_build_query($args);
35
  }
36
 
@@ -85,9 +85,9 @@ class Loco_mvc_AjaxRouter extends Loco_hooks_Hookable {
85
  */
86
  public function on_wp_ajax_loco_json(){
87
  $json = $this->renderAjax();
88
- $this->exitScript( $json, array (
89
  'Content-Type' => 'application/json; charset=UTF-8',
90
- ) );
91
  }
92
 
93
 
@@ -111,14 +111,14 @@ class Loco_mvc_AjaxRouter extends Loco_hooks_Hookable {
111
  $data = (string) $data;
112
  $ext = null;
113
  }
114
- $mimes = array (
115
  'mo' => 'application/x-gettext-translation',
116
  'po' => 'application/x-gettext',
117
  'pot' => 'application/x-gettext',
118
  'xml' => 'text/xml',
119
  'json' => 'application/json',
120
- );
121
- $headers = array();
122
  if( $ext && isset($mimes[$ext]) ){
123
  $headers['Content-Type'] = $mimes[$ext].'; charset=UTF-8';
124
  $headers['Content-Disposition'] = 'attachment; filename='.$file->basename();
@@ -175,11 +175,11 @@ class Loco_mvc_AjaxRouter extends Loco_hooks_Hookable {
175
  }
176
  }
177
  catch( Loco_error_Exception $e ){
178
- $json = json_encode( array( 'error' => $e->jsonSerialize(), 'notices' => Loco_error_AdminNotices::destroyAjax() ) );
179
  }
180
  catch( Exception $e ){
181
  $e = Loco_error_Exception::convert($e);
182
- $json = json_encode( array( 'error' => $e->jsonSerialize(), 'notices' => Loco_error_AdminNotices::destroyAjax() ) );
183
  }
184
  $this->buffer->discard();
185
  return $json;
21
  * @param array
22
  * @return string
23
  */
24
+ public static function generate( $route, array $args = [] ){
25
  // validate route autoload if debugging
26
  if( loco_debugging() ){
27
  class_exists( self::routeToClass($route) );
28
  }
29
+ $args += [
30
  'route' => $route,
31
  'action' => 'loco_ajax',
32
  'loco-nonce' => wp_create_nonce($route),
33
+ ];
34
  return admin_url('admin-ajax.php','relative').'?'.http_build_query($args);
35
  }
36
 
85
  */
86
  public function on_wp_ajax_loco_json(){
87
  $json = $this->renderAjax();
88
+ $this->exitScript( $json, [
89
  'Content-Type' => 'application/json; charset=UTF-8',
90
+ ] );
91
  }
92
 
93
 
111
  $data = (string) $data;
112
  $ext = null;
113
  }
114
+ $mimes = [
115
  'mo' => 'application/x-gettext-translation',
116
  'po' => 'application/x-gettext',
117
  'pot' => 'application/x-gettext',
118
  'xml' => 'text/xml',
119
  'json' => 'application/json',
120
+ ];
121
+ $headers = [];
122
  if( $ext && isset($mimes[$ext]) ){
123
  $headers['Content-Type'] = $mimes[$ext].'; charset=UTF-8';
124
  $headers['Content-Disposition'] = 'attachment; filename='.$file->basename();
175
  }
176
  }
177
  catch( Loco_error_Exception $e ){
178
+ $json = json_encode( [ 'error' => $e->jsonSerialize(), 'notices' => Loco_error_AdminNotices::destroyAjax() ] );
179
  }
180
  catch( Exception $e ){
181
  $e = Loco_error_Exception::convert($e);
182
+ $json = json_encode( [ 'error' => $e->jsonSerialize(), 'notices' => Loco_error_AdminNotices::destroyAjax() ] );
183
  }
184
  $this->buffer->discard();
185
  return $json;
src/mvc/FileParams.php CHANGED
@@ -40,7 +40,7 @@ class Loco_mvc_FileParams extends Loco_mvc_ViewParams {
40
  $s = $a[0];
41
  $d = trim($a[1],'0') and $s .= '.'.$d;
42
  }
43
- $units = array( ' bytes', ' KB', ' MB', ' GB', ' TB' );
44
  $s .= $units[$i];
45
 
46
  return $s;
@@ -52,7 +52,7 @@ class Loco_mvc_FileParams extends Loco_mvc_ViewParams {
52
  * @return Loco_mvc_FileParams
53
  */
54
  public static function create( Loco_fs_File $file ) {
55
- return new Loco_mvc_FileParams( array(), $file );
56
  }
57
 
58
 
@@ -62,7 +62,7 @@ class Loco_mvc_FileParams extends Loco_mvc_ViewParams {
62
  * @param Loco_fs_File
63
  */
64
  public function __construct( array $props, Loco_fs_File $file ){
65
- parent::__construct( array (
66
  'name' => '',
67
  'path' => '',
68
  'relpath' => '',
@@ -73,7 +73,7 @@ class Loco_mvc_FileParams extends Loco_mvc_ViewParams {
73
  'smode' => '',
74
  'owner' => '',
75
  'group' => '',
76
- ) + $props );
77
  $this->file = $file;
78
  }
79
 
@@ -84,7 +84,7 @@ class Loco_mvc_FileParams extends Loco_mvc_ViewParams {
84
  */
85
  #[ReturnTypeWillChange]
86
  public function offsetGet( $prop ){
87
- $getter = array( $this, '_get_'.$prop );
88
  if( is_callable($getter) ){
89
  return call_user_func( $getter );
90
  }
@@ -98,7 +98,7 @@ class Loco_mvc_FileParams extends Loco_mvc_ViewParams {
98
  */
99
  #[ReturnTypeWillChange]
100
  public function getArrayCopy(){
101
- $a = array();
102
  foreach( $this as $prop => $dflt ){
103
  $a[$prop] = $this[$prop];
104
  }
40
  $s = $a[0];
41
  $d = trim($a[1],'0') and $s .= '.'.$d;
42
  }
43
+ $units = [ ' bytes', ' KB', ' MB', ' GB', ' TB' ];
44
  $s .= $units[$i];
45
 
46
  return $s;
52
  * @return Loco_mvc_FileParams
53
  */
54
  public static function create( Loco_fs_File $file ) {
55
+ return new Loco_mvc_FileParams( [], $file );
56
  }
57
 
58
 
62
  * @param Loco_fs_File
63
  */
64
  public function __construct( array $props, Loco_fs_File $file ){
65
+ parent::__construct( [
66
  'name' => '',
67
  'path' => '',
68
  'relpath' => '',
73
  'smode' => '',
74
  'owner' => '',
75
  'group' => '',
76
+ ] + $props );
77
  $this->file = $file;
78
  }
79
 
84
  */
85
  #[ReturnTypeWillChange]
86
  public function offsetGet( $prop ){
87
+ $getter = [ $this, '_get_'.$prop ];
88
  if( is_callable($getter) ){
89
  return call_user_func( $getter );
90
  }
98
  */
99
  #[ReturnTypeWillChange]
100
  public function getArrayCopy(){
101
+ $a = [];
102
  foreach( $this as $prop => $dflt ){
103
  $a[$prop] = $this[$prop];
104
  }
src/mvc/PostParams.php CHANGED
@@ -45,7 +45,7 @@ class Loco_mvc_PostParams extends Loco_mvc_ViewParams {
45
  * @return Loco_mvc_PostParams
46
  */
47
  public static function create(){
48
- $post = array();
49
  if( 'POST' === $_SERVER['REQUEST_METHOD'] ){
50
  // attempt to use clean input if available (without added slashes)
51
  $raw = (string) file_get_contents('php://input');
@@ -69,7 +69,7 @@ class Loco_mvc_PostParams extends Loco_mvc_ViewParams {
69
  * @return Loco_mvc_PostParams
70
  */
71
  public static function fromSerial( array $serial ){
72
- $pairs = array();
73
  foreach( $serial as $pair ){
74
  $pairs[] = rawurlencode($pair[0]).'='.rawurlencode($pair[1]);
75
  }
@@ -83,7 +83,7 @@ class Loco_mvc_PostParams extends Loco_mvc_ViewParams {
83
  * @return array
84
  */
85
  public function getSerial(){
86
- $serial = array();
87
  $query = http_build_query( $this->getArrayCopy(), false, '&' );
88
  foreach( explode('&',$query) as $str ){
89
  $serial[] = array_map( 'urldecode', explode( '=', $str, 2 ) );
45
  * @return Loco_mvc_PostParams
46
  */
47
  public static function create(){
48
+ $post = [];
49
  if( 'POST' === $_SERVER['REQUEST_METHOD'] ){
50
  // attempt to use clean input if available (without added slashes)
51
  $raw = (string) file_get_contents('php://input');
69
  * @return Loco_mvc_PostParams
70
  */
71
  public static function fromSerial( array $serial ){
72
+ $pairs = [];
73
  foreach( $serial as $pair ){
74
  $pairs[] = rawurlencode($pair[0]).'='.rawurlencode($pair[1]);
75
  }
83
  * @return array
84
  */
85
  public function getSerial(){
86
+ $serial = [];
87
  $query = http_build_query( $this->getArrayCopy(), false, '&' );
88
  foreach( explode('&',$query) as $str ){
89
  $serial[] = array_map( 'urldecode', explode( '=', $str, 2 ) );
src/mvc/View.php CHANGED
@@ -40,7 +40,7 @@ class Loco_mvc_View implements IteratorAggregate {
40
  * @internal
41
  * @param array
42
  */
43
- public function __construct( array $args = array() ){
44
  $this->scope = new Loco_mvc_ViewParams( $args );
45
  $this->cwd = loco_plugin_root().'/tpl';
46
  }
@@ -280,10 +280,10 @@ class Loco_mvc_View implements IteratorAggregate {
280
  * @param array optional page arguments
281
  * @return Loco_mvc_ViewParams
282
  */
283
- public function route( $route, array $args = array() ){
284
- return new Loco_mvc_ViewParams( array (
285
  'href' => Loco_mvc_AdminRouter::generate( $route, $args ),
286
- ) );
287
  }
288
 
289
 
40
  * @internal
41
  * @param array
42
  */
43
+ public function __construct( array $args = [] ){
44
  $this->scope = new Loco_mvc_ViewParams( $args );
45
  $this->cwd = loco_plugin_root().'/tpl';
46
  }
280
  * @param array optional page arguments
281
  * @return Loco_mvc_ViewParams
282
  */
283
+ public function route( $route, array $args = [] ){
284
+ return new Loco_mvc_ViewParams( [
285
  'href' => Loco_mvc_AdminRouter::generate( $route, $args ),
286
+ ] );
287
  }
288
 
289
 
src/output/DiffRenderer.php CHANGED
@@ -13,12 +13,12 @@ class Loco_output_DiffRenderer extends WP_Text_Diff_Renderer_Table {
13
  /**
14
  * {@inheritdoc}
15
  */
16
- public function __construct( $params = array() ){
17
- parent::__construct( $params + array (
18
  'show_split_view' => true,
19
  'leading_context_lines' => 1,
20
  'trailing_context_lines' => 1,
21
- ) );
22
  }
23
 
24
 
@@ -49,7 +49,7 @@ class Loco_output_DiffRenderer extends WP_Text_Diff_Renderer_Table {
49
  $src = Loco_gettext_Data::ensureUtf8($src);
50
  $arr = preg_split( '/\\r?\\n/', $src );
51
  if( ! is_array($arr) ){
52
- $f = new Loco_mvc_FileParams( array(), $file );
53
  throw new Loco_error_Exception('Failed to split '.$f->relpath.' ('.$f->size.')' );
54
  }
55
  return $arr;
13
  /**
14
  * {@inheritdoc}
15
  */
16
+ public function __construct( $params = [] ){
17
+ parent::__construct( $params + [
18
  'show_split_view' => true,
19
  'leading_context_lines' => 1,
20
  'trailing_context_lines' => 1,
21
+ ] );
22
  }
23
 
24
 
49
  $src = Loco_gettext_Data::ensureUtf8($src);
50
  $arr = preg_split( '/\\r?\\n/', $src );
51
  if( ! is_array($arr) ){
52
+ $f = new Loco_mvc_FileParams( [], $file );
53
  throw new Loco_error_Exception('Failed to split '.$f->relpath.' ('.$f->size.')' );
54
  }
55
  return $arr;
src/package/Bundle.php CHANGED
@@ -104,7 +104,7 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
104
  * @throws Loco_error_Exception
105
  */
106
  public static function createType( $type, $handle ){
107
- $func = array( 'Loco_package_'.ucfirst($type), 'create' );
108
  if( is_callable($func) ){
109
  $bundle = call_user_func( $func, $handle );
110
  }
@@ -142,7 +142,7 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
142
  * @param string
143
  */
144
  public function __construct( $handle, $name ){
145
- parent::__construct( array() );
146
  $this->setHandle($handle)->setName($name);
147
  $this->xpaths = new Loco_fs_FileList;
148
  }
@@ -153,7 +153,7 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
153
  * @return Loco_package_Bundle
154
  */
155
  public function reload(){
156
- return call_user_func( array( get_class($this), 'create' ), $this->getSlug() );
157
  }
158
 
159
 
@@ -305,9 +305,9 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
305
  * @return string[]
306
  */
307
  public function getVendorRoots(){
308
- $dirs = array();
309
  $base = (string) $this->getDirectoryPath();
310
- foreach( array('node_modules','vendor') as $f ){
311
  $path = $base.'/'.$f;
312
  if( is_dir($path) ){
313
  $dirs[] = $path;
@@ -433,7 +433,7 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
433
  * @return array indexed by Text Domain name
434
  */
435
  public function exportGrouped(){
436
- $domains = array();
437
  /* @var $proj Loco_package_Project */
438
  foreach( $this as $proj ){
439
  $domain = $proj->getDomain();
@@ -697,7 +697,7 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
697
  * @return array<Loco_package_TextDomain>
698
  */
699
  public function getDomains(){
700
- $domains = array();
701
  /* @var $project Loco_package_Project */
702
  foreach( $this as $project ){
703
  if( $domain = $project->getDomain() ){
@@ -747,7 +747,7 @@ abstract class Loco_package_Bundle extends ArrayObject implements JsonSerializab
747
  * @return Loco_package_Bundle
748
  */
749
  public function clear(){
750
- $this->exchangeArray( array() );
751
  $this->xpaths = new Loco_fs_FileList;
752
  $this->saved = false;
753
  return $this;
104
  * @throws Loco_error_Exception
105
  */
106
  public static function createType( $type, $handle ){
107
+ $func = [ 'Loco_package_'.ucfirst($type), 'create' ];
108
  if( is_callable($func) ){
109
  $bundle = call_user_func( $func, $handle );
110
  }
142
  * @param string
143
  */
144
  public function __construct( $handle, $name ){
145
+ parent::__construct( [] );
146
  $this->setHandle($handle)->setName($name);
147
  $this->xpaths = new Loco_fs_FileList;
148
  }
153
  * @return Loco_package_Bundle
154
  */
155
  public function reload(){
156
+ return call_user_func( [ get_class($this), 'create' ], $this->getSlug() );
157
  }
158
 
159
 
305
  * @return string[]
306
  */
307
  public function getVendorRoots(){
308
+ $dirs = [];
309
  $base = (string) $this->getDirectoryPath();
310
+ foreach( ['node_modules','vendor'] as $f ){
311
  $path = $base.'/'.$f;
312
  if( is_dir($path) ){
313
  $dirs[] = $path;
433
  * @return array indexed by Text Domain name
434
  */
435
  public function exportGrouped(){
436
+ $domains = [];
437
  /* @var $proj Loco_package_Project */
438
  foreach( $this as $proj ){
439
  $domain = $proj->getDomain();
697
  * @return array<Loco_package_TextDomain>
698
  */
699
  public function getDomains(){
700
+ $domains = [];
701
  /* @var $project Loco_package_Project */
702
  foreach( $this as $project ){
703
  if( $domain = $project->getDomain() ){
747
  * @return Loco_package_Bundle
748
  */
749
  public function clear(){
750
+ $this->exchangeArray( [] );
751
  $this->xpaths = new Loco_fs_FileList;
752
  $this->saved = false;
753
  return $this;
src/package/Core.php CHANGED
@@ -8,10 +8,10 @@ class Loco_package_Core extends Loco_package_Bundle {
8
  * {@inheritdoc}
9
  */
10
  public function getSystemTargets(){
11
- return array (
12
  untrailingslashit( loco_constant('LOCO_LANG_DIR') ),
13
  untrailingslashit( loco_constant('WP_LANG_DIR') )
14
- );
15
  }
16
 
17
 
@@ -19,7 +19,7 @@ class Loco_package_Core extends Loco_package_Bundle {
19
  * {@inheritdoc}
20
  */
21
  public function getHeaderInfo(){
22
- return new Loco_package_Header( array (
23
  'TextDomain' => 'default',
24
  'DomainPath' => '/wp-content/languages/',
25
  // dummy author info for core components
@@ -27,7 +27,7 @@ class Loco_package_Core extends Loco_package_Bundle {
27
  'Version' => $GLOBALS['wp_version'],
28
  'Author' => __('The WordPress Team','default'),
29
  'AuthorURI' => __('https://wordpress.org/','default'),
30
- ) );
31
  }
32
 
33
 
@@ -35,7 +35,7 @@ class Loco_package_Core extends Loco_package_Bundle {
35
  * {@inheritdoc}
36
  */
37
  public function getMetaTranslatable(){
38
- return array();
39
  }
40
 
41
 
8
  * {@inheritdoc}
9
  */
10
  public function getSystemTargets(){
11
+ return [
12
  untrailingslashit( loco_constant('LOCO_LANG_DIR') ),
13
  untrailingslashit( loco_constant('WP_LANG_DIR') )
14
+ ];
15
  }
16
 
17
 
19
  * {@inheritdoc}
20
  */
21
  public function getHeaderInfo(){
22
+ return new Loco_package_Header( [
23
  'TextDomain' => 'default',
24
  'DomainPath' => '/wp-content/languages/',
25
  // dummy author info for core components
27
  'Version' => $GLOBALS['wp_version'],
28
  'Author' => __('The WordPress Team','default'),
29
  'AuthorURI' => __('https://wordpress.org/','default'),
30
+ ] );
31
  }
32
 
33
 
35
  * {@inheritdoc}
36
  */
37
  public function getMetaTranslatable(){
38
+ return [];
39
  }
40
 
41
 
src/package/Debugger.php CHANGED
@@ -20,13 +20,13 @@ class Loco_package_Debugger implements IteratorAggregate {
20
  */
21
  public function __construct( Loco_package_Bundle $bundle ){
22
 
23
- $this->messages = array();
24
- $this->counts = array(
25
  'success' => 0,
26
  'warning' => 0,
27
  'debug' => 0,
28
  'info' => 0,
29
- );
30
 
31
  // config storage type
32
  switch( $bundle->isConfigured() ){
@@ -58,7 +58,7 @@ class Loco_package_Debugger implements IteratorAggregate {
58
  $this->info('WordPress says primary text domain is "%s"', $value);
59
  // WordPress 4.6 changes mean this header could be a fallback and not actually declared by author
60
  if( $bundle->isPlugin() ){
61
- $map = array ( 'TextDomain' => 'Text Domain' );
62
  $raw = get_file_data( $bundle->getBootstrapPath(), $map, 'plugin' );
63
  if( empty($raw['TextDomain']) ){
64
  $this->warn('Author doesn\'t define the TextDomain header, WordPress guessed it');
@@ -89,8 +89,8 @@ class Loco_package_Debugger implements IteratorAggregate {
89
  }
90
 
91
  // collecting only configured domains to match against source code
92
- $domains = array();
93
- $templates = array();
94
 
95
  // show each known subset
96
  if( $count = count($bundle) ){
@@ -104,7 +104,7 @@ class Loco_package_Debugger implements IteratorAggregate {
104
  }
105
  $domains[$domain] = true;
106
  // Domain path[s] within bundle directory
107
- $targets = array();
108
  /* @var $dir Loco_fs_Directory */
109
  foreach( $project->getConfiguredTargets() as $dir ){
110
  $targets[] = $dir->getRelativePath($base);
@@ -169,7 +169,7 @@ class Loco_package_Debugger implements IteratorAggregate {
169
 
170
  // source code extraction across entire bundle
171
  $tmp = clone $bundle;
172
- $tmp->exchangeArray( array() );
173
  $project = $tmp->createDefault( (string) $default->getDomain() );
174
  $extr = new Loco_gettext_Extraction( $tmp );
175
  $extr->addProject( $project );
20
  */
21
  public function __construct( Loco_package_Bundle $bundle ){
22
 
23
+ $this->messages = [];
24
+ $this->counts = [
25
  'success' => 0,
26
  'warning' => 0,
27
  'debug' => 0,
28
  'info' => 0,
29
+ ];
30
 
31
  // config storage type
32
  switch( $bundle->isConfigured() ){
58
  $this->info('WordPress says primary text domain is "%s"', $value);
59
  // WordPress 4.6 changes mean this header could be a fallback and not actually declared by author
60
  if( $bundle->isPlugin() ){
61
+ $map = [ 'TextDomain' => 'Text Domain' ];
62
  $raw = get_file_data( $bundle->getBootstrapPath(), $map, 'plugin' );
63
  if( empty($raw['TextDomain']) ){
64
  $this->warn('Author doesn\'t define the TextDomain header, WordPress guessed it');
89
  }
90
 
91
  // collecting only configured domains to match against source code
92
+ $domains = [];
93
+ $templates = [];
94
 
95
  // show each known subset
96
  if( $count = count($bundle) ){
104
  }
105
  $domains[$domain] = true;
106
  // Domain path[s] within bundle directory
107
+ $targets = [];
108
  /* @var $dir Loco_fs_Directory */
109
  foreach( $project->getConfiguredTargets() as $dir ){
110
  $targets[] = $dir->getRelativePath($base);
169
 
170
  // source code extraction across entire bundle
171
  $tmp = clone $bundle;
172
+ $tmp->exchangeArray( [] );
173
  $project = $tmp->createDefault( (string) $default->getDomain() );
174
  $extr = new Loco_gettext_Extraction( $tmp );
175
  $extr->addProject( $project );
src/package/Inverter.php CHANGED
@@ -17,7 +17,7 @@ abstract class Loco_package_Inverter {
17
  foreach( $bundle as $project ){
18
  if( $file = $project->getPot() ){
19
  // excluding all extensions in case POT is actually a PO/MO pair
20
- foreach( array('pot','po','mo') as $ext ){
21
  $file = $file->cloneExtension($ext);
22
  if( $path = realpath( $file->getPath() ) ){
23
  $finder->exclude( $path );
@@ -55,9 +55,9 @@ abstract class Loco_package_Inverter {
55
 
56
 
57
  // first iteration groups found files into common locations that should hopefully indicate translation sets
58
- $groups = array();
59
- $templates = array();
60
- $localised = array();
61
  $root = $bundle->getDirectoryPath();
62
 
63
  /* @var $list Loco_fs_FileList */
@@ -71,8 +71,8 @@ abstract class Loco_package_Inverter {
71
  //
72
  if( ! isset($groups[$key]) ){
73
  $groups[$key] = $dir;
74
- $templates[$key] = array();
75
- $localised[$key] = array();
76
  }
77
  // template should define single set of translations unique by directory and file prefix
78
  if( 'pot' === $ext ){
@@ -99,7 +99,7 @@ abstract class Loco_package_Inverter {
99
 
100
 
101
  // next iteration matches collected files together into likely project sets
102
- $unique = array();
103
 
104
  /* @var $list Loco_fs_Directory */
105
  foreach( $groups as $key => $dir ){
17
  foreach( $bundle as $project ){
18
  if( $file = $project->getPot() ){
19
  // excluding all extensions in case POT is actually a PO/MO pair
20
+ foreach( ['pot','po','mo'] as $ext ){
21
  $file = $file->cloneExtension($ext);
22
  if( $path = realpath( $file->getPath() ) ){
23
  $finder->exclude( $path );
55
 
56
 
57
  // first iteration groups found files into common locations that should hopefully indicate translation sets
58
+ $groups = [];
59
+ $templates = [];
60
+ $localised = [];
61
  $root = $bundle->getDirectoryPath();
62
 
63
  /* @var $list Loco_fs_FileList */
71
  //
72
  if( ! isset($groups[$key]) ){
73
  $groups[$key] = $dir;
74
+ $templates[$key] = [];
75
+ $localised[$key] = [];
76
  }
77
  // template should define single set of translations unique by directory and file prefix
78
  if( 'pot' === $ext ){
99
 
100
 
101
  // next iteration matches collected files together into likely project sets
102
+ $unique = [];
103
 
104
  /* @var $list Loco_fs_Directory */
105
  foreach( $groups as $key => $dir ){
src/package/Listener.php CHANGED
@@ -97,16 +97,16 @@ class Loco_package_Listener extends Loco_hooks_Hookable {
97
  * @return Loco_package_Listener
98
  */
99
  public function clear(){
100
- $this->buffer = array();
101
- $this->themes = array();
102
- $this->plugins = array();
103
- $this->domains = array();
104
- $this->domainPaths = array();
105
  $this->pluginHandles = null;
106
  $this->buffered = false;
107
- $this->globalPaths = array();
108
 
109
- foreach( array('WP_LANG_DIR') as $name ){
110
  if( $value = loco_constant($name) ){
111
  $this->globalPaths[$value] = strlen($value);
112
  }
@@ -179,7 +179,7 @@ class Loco_package_Listener extends Loco_hooks_Hookable {
179
  */
180
  private function isPlugin( $check ){
181
  if( ! $this->pluginHandles ){
182
- $this->pluginHandles = array();
183
  foreach( Loco_package_Plugin::get_plugins() as $handle => $data ){
184
  $this->pluginHandles[ dirname($handle) ] = $handle;
185
  // set default text domain because additional domains could be discovered before the canonical one
@@ -269,14 +269,14 @@ class Loco_package_Listener extends Loco_hooks_Hookable {
269
  }
270
 
271
  // check if MO file lives inside a plugin
272
- foreach( array( 'WP_PLUGIN_DIR', 'WPMU_PLUGIN_DIR' ) as $const ){
273
  $root = loco_constant( $const );
274
  $relative = self::relative($path, $root);
275
  if( is_null($relative) ){
276
  continue;
277
  }
278
  // plugin *might* live directly under root
279
- $stack = array();
280
  foreach( explode( '/', dirname($relative) ) as $next ){
281
  $stack[] = $next;
282
  $relbase = implode('/', $stack );
@@ -338,7 +338,7 @@ class Loco_package_Listener extends Loco_hooks_Hookable {
338
  }
339
  }
340
  }
341
- $this->buffer = array();
342
  $this->buffered = false;
343
  }
344
  }
97
  * @return Loco_package_Listener
98
  */
99
  public function clear(){
100
+ $this->buffer = [];
101
+ $this->themes = [];
102
+ $this->plugins = [];
103
+ $this->domains = [];
104
+ $this->domainPaths = [];
105
  $this->pluginHandles = null;
106
  $this->buffered = false;
107
+ $this->globalPaths = [];
108
 
109
+ foreach( ['WP_LANG_DIR'] as $name ){
110
  if( $value = loco_constant($name) ){
111
  $this->globalPaths[$value] = strlen($value);
112
  }
179
  */
180
  private function isPlugin( $check ){
181
  if( ! $this->pluginHandles ){
182
+ $this->pluginHandles = [];
183
  foreach( Loco_package_Plugin::get_plugins() as $handle => $data ){
184
  $this->pluginHandles[ dirname($handle) ] = $handle;
185
  // set default text domain because additional domains could be discovered before the canonical one
269
  }
270
 
271
  // check if MO file lives inside a plugin
272
+ foreach( [ 'WP_PLUGIN_DIR', 'WPMU_PLUGIN_DIR' ] as $const ){
273
  $root = loco_constant( $const );
274
  $relative = self::relative($path, $root);
275
  if( is_null($relative) ){
276
  continue;
277
  }
278
  // plugin *might* live directly under root
279
+ $stack = [];
280
  foreach( explode( '/', dirname($relative) ) as $next ){
281
  $stack[] = $next;
282
  $relbase = implode('/', $stack );
338
  }
339
  }
340
  }
341
+ $this->buffer = [];
342
  $this->buffered = false;
343
  }
344
  }
src/package/Locale.php CHANGED
@@ -27,7 +27,7 @@ class Loco_package_Locale {
27
  */
28
  public function __construct( Loco_locale $locale = null ){
29
  $this->index = new ArrayObject;
30
- $this->match = array();
31
  if( $locale ){
32
  $this->addLocale( $locale );
33
  }
@@ -67,7 +67,7 @@ class Loco_package_Locale {
67
  public function getBundles(){
68
  $bundles = $this->bundles;
69
  if( ! $bundles ){
70
- $bundles = array( Loco_package_Core::create() );
71
  $bundles = array_merge( $bundles, Loco_package_Plugin::getAll() );
72
  $bundles = array_merge( $bundles, Loco_package_Theme::getAll() );
73
  $this->bundles = $bundles;
27
  */
28
  public function __construct( Loco_locale $locale = null ){
29
  $this->index = new ArrayObject;
30
+ $this->match = [];
31
  if( $locale ){
32
  $this->addLocale( $locale );
33
  }
67
  public function getBundles(){
68
  $bundles = $this->bundles;
69
  if( ! $bundles ){
70
+ $bundles = [ Loco_package_Core::create() ];
71
  $bundles = array_merge( $bundles, Loco_package_Plugin::getAll() );
72
  $bundles = array_merge( $bundles, Loco_package_Theme::getAll() );
73
  $this->bundles = $bundles;
src/package/Plugin.php CHANGED
@@ -9,10 +9,10 @@ class Loco_package_Plugin extends Loco_package_Bundle {
9
  * {@inheritdoc}
10
  */
11
  public function getSystemTargets(){
12
- return array (
13
  trailingslashit( loco_constant('LOCO_LANG_DIR') ).'plugins',
14
  trailingslashit( loco_constant('WP_LANG_DIR') ).'plugins',
15
- );
16
  }
17
 
18
 
@@ -55,7 +55,7 @@ class Loco_package_Plugin extends Loco_package_Bundle {
55
  * @return Loco_package_Plugin[]
56
  */
57
  public static function getAll(){
58
- $plugins = array();
59
  foreach( self::get_plugins() as $handle => $data ){
60
  try {
61
  $plugins[] = Loco_package_Plugin::create($handle);
@@ -75,12 +75,12 @@ class Loco_package_Plugin extends Loco_package_Bundle {
75
  public static function get_plugins(){
76
  $cached = wp_cache_get('plugins','loco');
77
  if( ! is_array($cached) ){
78
- $cached = array();
79
  // regular plugins + mu plugins:
80
- $search = array (
81
  'WP_PLUGIN_DIR' => 'get_plugins',
82
  'WPMU_PLUGIN_DIR' => 'get_mu_plugins',
83
- );
84
  foreach( $search as $const => $getter ){
85
  if( $list = call_user_func($getter) ){
86
  $base = loco_constant($const);
@@ -129,7 +129,7 @@ class Loco_package_Plugin extends Loco_package_Bundle {
129
  }
130
  // else plugin is not known to WordPress
131
  else {
132
- $data = apply_filters( 'loco_missing_plugin', array(), $handle );
133
  }
134
  // plugin not valid if name absent from raw data
135
  if( empty($data['Name']) ){
@@ -159,7 +159,7 @@ class Loco_package_Plugin extends Loco_package_Bundle {
159
  $data = get_plugin_data( $path, false, false );
160
  }
161
  else {
162
- $data = array();
163
  }
164
  }
165
  return new Loco_package_Header( $data );
@@ -170,14 +170,14 @@ class Loco_package_Plugin extends Loco_package_Bundle {
170
  * {@inheritdoc}
171
  */
172
  public function getMetaTranslatable(){
173
- return array (
174
  'Name' => 'Name of the plugin',
175
  'Description' => 'Description of the plugin',
176
  'PluginURI' => 'URI of the plugin',
177
  'Author' => 'Author of the plugin',
178
  'AuthorURI' => 'Author URI of the plugin',
179
  // 'Tags' => 'Tags of the plugin',
180
- );
181
  }
182
 
183
 
9
  * {@inheritdoc}
10
  */
11
  public function getSystemTargets(){
12
+ return [
13
  trailingslashit( loco_constant('LOCO_LANG_DIR') ).'plugins',
14
  trailingslashit( loco_constant('WP_LANG_DIR') ).'plugins',
15
+ ];
16
  }
17
 
18
 
55
  * @return Loco_package_Plugin[]
56
  */
57
  public static function getAll(){
58
+ $plugins = [];
59
  foreach( self::get_plugins() as $handle => $data ){
60
  try {
61
  $plugins[] = Loco_package_Plugin::create($handle);
75
  public static function get_plugins(){
76
  $cached = wp_cache_get('plugins','loco');
77
  if( ! is_array($cached) ){
78
+ $cached = [];
79
  // regular plugins + mu plugins:
80
+ $search = [
81
  'WP_PLUGIN_DIR' => 'get_plugins',
82
  'WPMU_PLUGIN_DIR' => 'get_mu_plugins',
83
+ ];
84
  foreach( $search as $const => $getter ){
85
  if( $list = call_user_func($getter) ){
86
  $base = loco_constant($const);
129
  }
130
  // else plugin is not known to WordPress
131
  else {
132
+ $data = apply_filters( 'loco_missing_plugin', [], $handle );
133
  }
134
  // plugin not valid if name absent from raw data
135
  if( empty($data['Name']) ){
159
  $data = get_plugin_data( $path, false, false );
160
  }
161
  else {
162
+ $data = [];
163
  }
164
  }
165
  return new Loco_package_Header( $data );
170
  * {@inheritdoc}
171
  */
172
  public function getMetaTranslatable(){
173
+ return [
174
  'Name' => 'Name of the plugin',
175
  'Description' => 'Description of the plugin',
176
  'PluginURI' => 'URI of the plugin',
177
  'Author' => 'Author of the plugin',
178
  'AuthorURI' => 'Author URI of the plugin',
179
  // 'Tags' => 'Tags of the plugin',
180
+ ];
181
  }
182
 
183
 
src/package/Project.php CHANGED
@@ -141,7 +141,7 @@ class Loco_package_Project {
141
  $r = preg_split('/(?<!\\\\)\\./', $id, 2 );
142
  $domain = stripcslashes($r[0]);
143
  $slug = isset($r[1]) ? stripcslashes($r[1]) : $domain;
144
- return array( $domain, $slug );
145
  }
146
 
147
 
@@ -375,7 +375,7 @@ class Loco_package_Project {
375
  }
376
  // fallback to unconfigured, but possibly existent folders
377
  $base = $this->getBundle()->getDirectoryPath();
378
- foreach( array('languages','language','lang','l10n','i18n') as $d ){
379
  $d = new Loco_fs_Directory($d);
380
  $d->normalize($base);
381
  if( $this->isTargetExcluded($d) ){
@@ -425,7 +425,7 @@ class Loco_package_Project {
425
  $exts = array_merge( $exts, (array) $conf->jsx_alias );
426
  }
427
  // always ensure we have at least PHP files scanned
428
- return array_merge( $exts, array('php') );
429
  }
430
 
431
 
@@ -581,7 +581,7 @@ class Loco_package_Project {
581
  $targets->add( new Loco_fs_Directory($root) );
582
  // look in alternative language directories if only root is configured
583
  if( 1 === count($targets) ){
584
- foreach( array('languages','language','lang','l10n','i18n') as $d ) {
585
  $alt = new Loco_fs_Directory($root.'/'.$d);
586
  if( ! $this->isTargetExcluded($alt) ){
587
  $targets->add($alt);
@@ -639,7 +639,7 @@ class Loco_package_Project {
639
  }
640
  $this->excludeTargets($finder);
641
  $files = $finder->group('pot','po','mo')->exportGroups();
642
- foreach( array('pot','po') as $ext ){
643
  /* @var $pot Loco_fs_File */
644
  foreach( $files[$ext] as $pot ){
645
  $name = $pot->filename();
@@ -648,7 +648,7 @@ class Loco_package_Project {
648
  return $pot;
649
  }
650
  // support unconventional <slug>-en_US.<ext>
651
- foreach( array('-en_US'=>6, '-en'=>3 ) as $tail => $len ){
652
  if( '-en_US' === substr($name,-$len) && $slug === substr($name,0,-$len) ){
653
  return $pot;
654
  }
@@ -665,7 +665,7 @@ class Loco_package_Project {
665
  if( $this->isDomainDefault() ){
666
  $options = Loco_data_Settings::get();
667
  if( $aliases = $options->pot_alias ){
668
- $found = array();
669
  /* @var $pot Loco_fs_File */
670
  foreach( $finder as $pot ){
671
  $priority = array_search( $pot->basename(), $aliases, true );
141
  $r = preg_split('/(?<!\\\\)\\./', $id, 2 );
142
  $domain = stripcslashes($r[0]);
143
  $slug = isset($r[1]) ? stripcslashes($r[1]) : $domain;
144
+ return [ $domain, $slug ];
145
  }
146
 
147
 
375
  }
376
  // fallback to unconfigured, but possibly existent folders
377
  $base = $this->getBundle()->getDirectoryPath();
378
+ foreach( ['languages','language','lang','l10n','i18n'] as $d ){
379
  $d = new Loco_fs_Directory($d);
380
  $d->normalize($base);
381
  if( $this->isTargetExcluded($d) ){
425
  $exts = array_merge( $exts, (array) $conf->jsx_alias );
426
  }
427
  // always ensure we have at least PHP files scanned
428
+ return array_merge( $exts, ['php'] );
429
  }
430
 
431
 
581
  $targets->add( new Loco_fs_Directory($root) );
582
  // look in alternative language directories if only root is configured
583
  if( 1 === count($targets) ){
584
+ foreach( ['languages','language','lang','l10n','i18n'] as $d ) {
585
  $alt = new Loco_fs_Directory($root.'/'.$d);
586
  if( ! $this->isTargetExcluded($alt) ){
587
  $targets->add($alt);
639
  }
640
  $this->excludeTargets($finder);
641
  $files = $finder->group('pot','po','mo')->exportGroups();
642
+ foreach( ['pot','po'] as $ext ){
643
  /* @var $pot Loco_fs_File */
644
  foreach( $files[$ext] as $pot ){
645
  $name = $pot->filename();
648
  return $pot;
649
  }
650
  // support unconventional <slug>-en_US.<ext>
651
+ foreach( ['-en_US'=>6, '-en'=>3 ] as $tail => $len ){
652
  if( '-en_US' === substr($name,-$len) && $slug === substr($name,0,-$len) ){
653
  return $pot;
654
  }
665
  if( $this->isDomainDefault() ){
666
  $options = Loco_data_Settings::get();
667
  if( $aliases = $options->pot_alias ){
668
+ $found = [];
669
  /* @var $pot Loco_fs_File */
670
  foreach( $finder as $pot ){
671
  $priority = array_search( $pot->basename(), $aliases, true );
src/package/Theme.php CHANGED
@@ -14,10 +14,10 @@ class Loco_package_Theme extends Loco_package_Bundle {
14
  * {@inheritdoc}
15
  */
16
  public function getSystemTargets(){
17
- return array (
18
  trailingslashit( loco_constant('LOCO_LANG_DIR') ).'themes',
19
  trailingslashit( loco_constant('WP_LANG_DIR') ).'themes',
20
- );
21
  }
22
 
23
 
@@ -60,14 +60,14 @@ class Loco_package_Theme extends Loco_package_Bundle {
60
  * {@inheritdoc}
61
  */
62
  public function getMetaTranslatable(){
63
- return array (
64
  'Name' => 'Name of the theme',
65
  'Description' => 'Description of the theme',
66
  'ThemeURI' => 'URI of the theme',
67
  'Author' => 'Author of the theme',
68
  'AuthorURI' => 'Author URI of the theme',
69
  // 'Tags' => 'Tags of the theme',
70
- );
71
  }
72
 
73
 
@@ -84,8 +84,8 @@ class Loco_package_Theme extends Loco_package_Bundle {
84
  * @return Loco_package_Theme[]
85
  */
86
  public static function getAll(){
87
- $themes = array();
88
- foreach( wp_get_themes(array('errors'=>null)) as $theme ){
89
  try {
90
  $themes[] = self::createFromTheme($theme);
91
  }
@@ -137,11 +137,11 @@ class Loco_package_Theme extends Loco_package_Bundle {
137
  // otherwise project will use theme root by default
138
 
139
 
140
- $bundle->configure( $base, array (
141
  'Name' => $name,
142
  'TextDomain' => $domain,
143
  'DomainPath' => $target,
144
- ) );
145
 
146
  // parent theme inheritance:
147
  if( $parent = $theme->parent() ){
@@ -166,7 +166,7 @@ class Loco_package_Theme extends Loco_package_Bundle {
166
  */
167
  public static function fromFile( Loco_fs_File $file ){
168
  $find = $file->getPath();
169
- foreach( wp_get_themes( array('errors'=>null) ) as $theme ){
170
  $base = $theme->get_stylesheet_directory();
171
  $path = $base.substr( $find, strlen($base) );
172
  if( $find === $path ){
14
  * {@inheritdoc}
15
  */
16
  public function getSystemTargets(){
17
+ return [
18
  trailingslashit( loco_constant('LOCO_LANG_DIR') ).'themes',
19
  trailingslashit( loco_constant('WP_LANG_DIR') ).'themes',
20
+ ];
21
  }
22
 
23
 
60
  * {@inheritdoc}
61
  */
62
  public function getMetaTranslatable(){
63
+ return [
64
  'Name' => 'Name of the theme',
65
  'Description' => 'Description of the theme',
66
  'ThemeURI' => 'URI of the theme',
67
  'Author' => 'Author of the theme',
68
  'AuthorURI' => 'Author URI of the theme',
69
  // 'Tags' => 'Tags of the theme',
70
+ ];
71
  }
72
 
73
 
84
  * @return Loco_package_Theme[]
85
  */
86
  public static function getAll(){
87
+ $themes = [];
88
+ foreach( wp_get_themes(['errors'=>null]) as $theme ){
89
  try {
90
  $themes[] = self::createFromTheme($theme);
91
  }
137
  // otherwise project will use theme root by default
138
 
139
 
140
+ $bundle->configure( $base, [
141
  'Name' => $name,
142
  'TextDomain' => $domain,
143
  'DomainPath' => $target,
144
+ ] );
145
 
146
  // parent theme inheritance:
147
  if( $parent = $theme->parent() ){
166
  */
167
  public static function fromFile( Loco_fs_File $file ){
168
  $find = $file->getPath();
169
+ foreach( wp_get_themes( ['errors'=>null] ) as $theme ){
170
  $base = $theme->get_stylesheet_directory();
171
  $path = $base.substr( $find, strlen($base) );
172
  if( $find === $path ){
src/test/DummyFtpConnect.php CHANGED
@@ -72,7 +72,7 @@ class WP_Filesystem_Debug extends WP_Filesystem_Base {
72
  */
73
  public function disconnect(){
74
  $this->authed = false;
75
- $this->options = array();
76
  return $this;
77
  }
78
 
@@ -98,7 +98,7 @@ class WP_Filesystem_Debug extends WP_Filesystem_Base {
98
  private function _call( $method, array $args ){
99
  if( $this->authed ){
100
  $real = Loco_api_WordPressFileSystem::direct();
101
- return call_user_func_array( array($real,$method), $args );
102
  }
103
  return false;
104
  }
72
  */
73
  public function disconnect(){
74
  $this->authed = false;
75
+ $this->options = [];
76
  return $this;
77
  }
78
 
98
  private function _call( $method, array $args ){
99
  if( $this->authed ){
100
  $real = Loco_api_WordPressFileSystem::direct();
101
+ return call_user_func_array( [$real,$method], $args );
102
  }
103
  return false;
104
  }
src/test/WordPressTestCase.php CHANGED
@@ -37,7 +37,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
37
  protected static function dropOptions(){
38
  global $wpdb;
39
 
40
- $args = array('loco_%','_%_loco_%','%_auto_update_%');
41
  $query = $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%s' OR option_name LIKE '%s' OR option_name LIKE '%s';", $args );
42
  if( $results = $wpdb->get_results($query,ARRAY_N) ){
43
  foreach( $results as $row ){
@@ -89,7 +89,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
89
  wp_cache_flush();
90
  // text domains should be unloaded at start of all tests, and locale reset
91
  unset( $GLOBALS['locale'] );
92
- $GLOBALS['l10n'] = array();
93
  $this->enable_locale('en_US');
94
  $this->assertSame( 'en_US', get_locale(), 'Ensure test site is English to start');
95
  $this->assertSame( 'en_US', get_user_locale(),'Ensure test site is English to start');
@@ -103,13 +103,13 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
103
  }
104
  // test plugins require a filter as multiple roots not supported in wp
105
  remove_all_filters('loco_missing_plugin');
106
- add_filter( 'loco_missing_plugin', array(__CLASS__,'filter_allows_fake_plugins_to_exist'), 10, 2 );
107
  // avoid WordPress missing index notices
108
- $GLOBALS['_SERVER'] += array (
109
  'HTTP_HOST' => 'localhost',
110
  'SERVER_PROTOCOL' => 'HTTP/1.0',
111
  'HTTP_USER_AGENT' => 'Loco/'.get_class($this),
112
- );
113
  // remove all filters before adding
114
  remove_all_filters('filesystem_method');
115
  remove_all_filters('loco_constant_DISALLOW_FILE_MODS');
@@ -117,13 +117,13 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
117
  remove_all_filters('loco_file_mod_allowed_context');
118
  remove_all_filters('loco_setcookie');
119
  // tests should always dictate the file system method, which defaults to direct
120
- add_filter('filesystem_method', array($this,'filter_fs_method') );
121
- add_filter('loco_constant_DISALLOW_FILE_MODS', array($this,'filter_fs_disallow') );
122
- add_filter('file_mod_allowed', array($this,'filter_fs_allow'), 10, 2 ); // <- wp 4.8
123
- add_filter('loco_file_mod_allowed_context', array($this,'filter_fs_allow_context'),10,2); // <- used with file_mod_allowed
124
  // capture cookies so we can test what is set
125
- add_filter('loco_setcookie', array($this,'captureCookie'), 10, 1 );
126
- $this->cookies_set = array();
127
  $this->enable_network();
128
  }
129
 
@@ -133,8 +133,8 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
133
  */
134
  public function clean_up_global_scope(){
135
  parent::clean_up_global_scope();
136
- $_COOKIE = array();
137
- $_REQUEST = array();
138
  }
139
 
140
 
@@ -169,14 +169,14 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
169
  $screen = get_current_screen();
170
  $action = isset($_GET['action']) ? $_GET['action'] : null;
171
  $router->initPage( $screen, $action );
172
- $html = get_echo( array($router,'renderPage') );
173
  // ensure further hooks fired as WordPress continues to render admin footer
174
  do_action('in_admin_footer');
175
  do_action('admin_footer','');
176
- get_echo( 'do_action', array('admin_print_footer_scripts') );
177
  // Capture late errors flushed on destruct
178
  // $data = Loco_error_AdminNotices::destroyAjax();
179
- $html .= get_echo( array(Loco_error_AdminNotices::get(),'on_loco_admin_notices') );
180
  return $html;
181
  }
182
 
@@ -261,7 +261,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
261
  $root = new Loco_fs_Directory( LOCO_TEST_DATA_ROOT.'/tmp' );
262
  $dir = new Loco_fs_FileFinder( $root );
263
  $dir->setRecursive( true );
264
- $dirs = array();
265
  /* @var $file Loco_fs_File */
266
  foreach( $dir as $file ){
267
  $dirs[ $file->dirname() ] = true;
@@ -292,7 +292,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
292
  throw new Exception( $role.' role has no capabilities' );
293
  }
294
 
295
- $user = self::factory()->user->create( array( 'role' => $role ) );
296
  if( $user instanceof WP_Error ){
297
  foreach( $user->get_error_messages() as $message ){
298
  trigger_error( $message );
@@ -383,7 +383,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
383
  $locale = Loco_Locale::parse($tag);
384
  $this->locale = (string) $locale;
385
  remove_all_filters('locale');
386
- add_filter('locale', array($this,'_filter_locale') );
387
  }
388
 
389
 
@@ -401,7 +401,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
401
  */
402
  public function enable_test_content_dir(){
403
  remove_all_filters('loco_constant_WP_CONTENT_DIR');
404
- add_filter('loco_constant_WP_CONTENT_DIR', array($this,'_filter_wp_content_dir'), 10, 0 );
405
  }
406
 
407
 
@@ -418,7 +418,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
418
  */
419
  public function capture_redirects(){
420
  remove_all_filters('wp_redirect');
421
- add_filter('wp_redirect', array($this,'filter_wp_redirect'), 10, 2 );
422
  }
423
 
424
 
@@ -464,7 +464,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
464
  $_POST = $post;
465
  $_REQUEST = array_merge( $_GET, $_POST, $_COOKIE );
466
  $_SERVER['REQUEST_METHOD'] = 'POST';
467
- $_FILES = array();
468
  Loco_mvc_PostParams::destroy();
469
  }
470
 
@@ -488,7 +488,7 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
488
  $_GET = $get;
489
  $_REQUEST = array_merge( $_GET, $_POST, $_COOKIE );
490
  $_SERVER['REQUEST_METHOD'] = 'GET';
491
- $_FILES = array();
492
  }
493
 
494
 
@@ -516,11 +516,11 @@ abstract class Loco_test_WordPressTestCase extends WP_UnitTestCase {
516
  if( $len !== strlen($src) ){
517
  throw new Exception('Bad file params');
518
  }
519
- $_FILES[$key] = array (
520
  'error' => 0,
521
  'tmp_name' => $tmp,
522
  'name' => basename($path),
523
- );
524
  }
525
 
526
 
37
  protected static function dropOptions(){
38
  global $wpdb;
39
 
40
+ $args = ['loco_%','_%_loco_%','%_auto_update_%'];
41
  $query = $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%s' OR option_name LIKE '%s' OR option_name LIKE '%s';", $args );
42
  if( $results = $wpdb->get_results($query,ARRAY_N) ){
43
  foreach( $results as $row ){
89
  wp_cache_flush();
90
  // text domains should be unloaded at start of all tests, and locale reset
91
  unset( $GLOBALS['locale'] );
92
+ $GLOBALS['l10n'] = [];
93
  $this->enable_locale('en_US');
94
  $this->assertSame( 'en_US', get_locale(), 'Ensure test site is English to start');
95
  $this->assertSame( 'en_US', get_user_locale(),'Ensure test site is English to start');
103
  }
104
  // test plugins require a filter as multiple roots not supported in wp
105
  remove_all_filters('loco_missing_plugin');
106
+ add_filter( 'loco_missing_plugin', [__CLASS__,'filter_allows_fake_plugins_to_exist'], 10, 2 );
107
  // avoid WordPress missing index notices
108
+ $GLOBALS['_SERVER'] += [
109
  'HTTP_HOST' => 'localhost',
110
  'SERVER_PROTOCOL' => 'HTTP/1.0',
111
  'HTTP_USER_AGENT' => 'Loco/'.get_class($this),
112
+ ];
113
  // remove all filters before adding
114
  remove_all_filters('filesystem_method');
115
  remove_all_filters('loco_constant_DISALLOW_FILE_MODS');
117
  remove_all_filters('loco_file_mod_allowed_context');
118
  remove_all_filters('loco_setcookie');
119
  // tests should always dictate the file system method, which defaults to direct
120
+ add_filter('filesystem_method', [$this,'filter_fs_method'] );
121
+ add_filter('loco_constant_DISALLOW_FILE_MODS', [$this,'filter_fs_disallow'] );
122
+ add_filter('file_mod_allowed', [$this,'filter_fs_allow'], 10, 2 ); // <- wp 4.8
123
+ add_filter('loco_file_mod_allowed_context', [$this,'filter_fs_allow_context'],10,2); // <- used with file_mod_allowed
124
  // capture cookies so we can test what is set
125
+ add_filter('loco_setcookie', [$this,'captureCookie'], 10, 1 );
126
+ $this->cookies_set = [];
127
  $this->enable_network();
128
  }
129
 
133
  */
134
  public function clean_up_global_scope(){
135
  parent::clean_up_global_scope();
136
+ $_COOKIE = [];
137
+ $_REQUEST = [];
138
  }
139
 
140
 
169
  $screen = get_current_screen();
170
  $action = isset($_GET['action']) ? $_GET['action'] : null;
171
  $router->initPage( $screen, $action );
172
+ $html = get_echo( [$router,'renderPage'] );
173
  // ensure further hooks fired as WordPress continues to render admin footer
174
  do_action('in_admin_footer');
175
  do_action('admin_footer','');
176
+ get_echo( 'do_action', ['admin_print_footer_scripts'] );
177
  // Capture late errors flushed on destruct
178
  // $data = Loco_error_AdminNotices::destroyAjax();
179
+ $html .= get_echo( [Loco_error_AdminNotices::get(),'on_loco_admin_notices'] );
180
  return $html;
181
  }
182
 
261
  $root = new Loco_fs_Directory( LOCO_TEST_DATA_ROOT.'/tmp' );
262
  $dir = new Loco_fs_FileFinder( $root );
263
  $dir->setRecursive( true );
264
+ $dirs = [];
265
  /* @var $file Loco_fs_File */
266
  foreach( $dir as $file ){
267
  $dirs[ $file->dirname() ] = true;
292
  throw new Exception( $role.' role has no capabilities' );
293
  }
294
 
295
+ $user = self::factory()->user->create( [ 'role' => $role ] );
296
  if( $user instanceof WP_Error ){
297
  foreach( $user->get_error_messages() as $message ){
298
  trigger_error( $message );
383
  $locale = Loco_Locale::parse($tag);
384
  $this->locale = (string) $locale;
385
  remove_all_filters('locale');
386
+ add_filter('locale', [$this,'_filter_locale'] );
387
  }
388
 
389
 
401
  */
402
  public function enable_test_content_dir(){
403
  remove_all_filters('loco_constant_WP_CONTENT_DIR');
404
+ add_filter('loco_constant_WP_CONTENT_DIR', [$this,'_filter_wp_content_dir'], 10, 0 );
405
  }
406
 
407
 
418
  */
419
  public function capture_redirects(){
420
  remove_all_filters('wp_redirect');
421
+ add_filter('wp_redirect', [$this,'filter_wp_redirect'], 10, 2 );
422
  }
423
 
424
 
464
  $_POST = $post;
465
  $_REQUEST = array_merge( $_GET, $_POST, $_COOKIE );
466
  $_SERVER['REQUEST_METHOD'] = 'POST';
467
+ $_FILES = [];
468
  Loco_mvc_PostParams::destroy();
469
  }
470
 
488
  $_GET = $get;
489
  $_REQUEST = array_merge( $_GET, $_POST, $_COOKIE );
490
  $_SERVER['REQUEST_METHOD'] = 'GET';
491
+ $_FILES = [];
492
  }
493
 
494
 
516
  if( $len !== strlen($src) ){
517
  throw new Exception('Bad file params');
518
  }
519
+ $_FILES[$key] = [
520
  'error' => 0,
521
  'tmp_name' => $tmp,
522
  'name' => basename($path),
523
+ ];
524
  }
525
 
526
 
tpl/admin/bundle/view.php CHANGED
@@ -17,8 +17,8 @@ foreach( $projects as $p ): ?>
17
  <h2><?php $p->e('name')?> <span>(<?php $p->e('short')?>)</span></h2><?php
18
  endif;
19
 
20
- echo $this->render('inc-po-links', array( 'nav' => $p->nav ) );
21
- echo $this->render('inc-po-table', array( 'pairs' => $p->po, 'domain' => $p->domain ) );
22
  ?>
23
 
24
  </div><?php
@@ -33,13 +33,13 @@ if( $unknown ):?>
33
  // Translators: %s is a URL. Keep the <a> tag intact
34
  echo wp_kses(
35
  sprintf( __('Click the <a href="%s">setup</a> tab to complete the bundle configuration','loco-translate'), $tabs[1]->href ),
36
- array('a'=>array('href'=>true)), array('http','https')
37
  );?>.
38
  </p>
39
  </div>
40
  <?php
41
  echo $this->render('../common/inc-table-filter');
42
- echo $this->render('inc-po-table', array( 'pairs' => $unknown, 'domain' => null ) )?>
43
  </div><?php
44
  endif;
45
 
@@ -55,14 +55,14 @@ else:?>
55
  esc_html_e("This bundle isn't automatically compatible and requires configuring before you can use all the functions of Loco Translate",'loco-translate')?>. <?php
56
  echo wp_kses(
57
  sprintf( __('Click the <a href="%s">setup</a> tab to complete the bundle configuration','loco-translate'), $tabs[1]->href ),
58
- array('a'=>array('href'=>true)), array('http','https')
59
  );?>.
60
  </p>
61
  </div>
62
  </div><?php
63
  if( $unknown ):?>
64
  <div class="loco-project">
65
- <?php echo $this->render('inc-po-table', array( 'pairs' => $unknown, 'domain' => null ) )?>
66
  </div><?php
67
  endif;
68
  endif;
17
  <h2><?php $p->e('name')?> <span>(<?php $p->e('short')?>)</span></h2><?php
18
  endif;
19
 
20
+ echo $this->render('inc-po-links', [ 'nav' => $p->nav ] );
21
+ echo $this->render('inc-po-table', [ 'pairs' => $p->po, 'domain' => $p->domain ] );
22
  ?>
23
 
24
  </div><?php
33
  // Translators: %s is a URL. Keep the <a> tag intact
34
  echo wp_kses(
35
  sprintf( __('Click the <a href="%s">setup</a> tab to complete the bundle configuration','loco-translate'), $tabs[1]->href ),
36
+ ['a'=>['href'=>true]], ['http','https']
37
  );?>.
38
  </p>
39
  </div>
40
  <?php
41
  echo $this->render('../common/inc-table-filter');
42
+ echo $this->render('inc-po-table', [ 'pairs' => $unknown, 'domain' => null ] )?>
43
  </div><?php
44
  endif;
45
 
55
  esc_html_e("This bundle isn't automatically compatible and requires configuring before you can use all the functions of Loco Translate",'loco-translate')?>. <?php
56
  echo wp_kses(
57
  sprintf( __('Click the <a href="%s">setup</a> tab to complete the bundle configuration','loco-translate'), $tabs[1]->href ),
58
+ ['a'=>['href'=>true]], ['http','https']
59
  );?>.
60
  </p>
61
  </div>
62
  </div><?php
63
  if( $unknown ):?>
64
  <div class="loco-project">
65
+ <?php echo $this->render('inc-po-table', [ 'pairs' => $unknown, 'domain' => null ] )?>
66
  </div><?php
67
  endif;
68
  endif;
tpl/admin/config/apis.php CHANGED
@@ -109,27 +109,6 @@ $help = apply_filters('loco_external','https://localise.biz/wordpress/plugin/man
109
  </p>
110
  </fieldset>
111
  </td>
112
- </tr><?php
113
- // YANDEX
114
- $api = $apis['yandex']?>
115
- <tr>
116
- <th scope="row"><?php $api->e('name')?></th>
117
- <td>
118
- <fieldset>
119
- <legend class="screen-reader-text">
120
- <span><?php $ui->e('api_key')?></span>
121
- </legend>
122
- <p>
123
- <label for="loco--yandex_api_key">
124
- <?php $ui->e('api_key')?>:
125
- </label>
126
- <input type="text" size="90" name="api[yandex][key]" id="loco--yandex_api_key" value="<?php $api->e('key')?>" spellcheck="false" />
127
- </p>
128
- <p>
129
- <span class="description"><a href="https://cloud.yandex.com/services/translate" target="_blank" tabindex="-1">https://cloud.yandex.com/services/translate</a></span>
130
- </p>
131
- </fieldset>
132
- </td>
133
  </tr>
134
  </tbody>
135
  </table>
109
  </p>
110
  </fieldset>
111
  </td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  </tr>
113
  </tbody>
114
  </table>
tpl/admin/config/version.php CHANGED
@@ -50,12 +50,11 @@ $this->extend('../layout');
50
  </h3>
51
  <p><?php
52
  // translators: (1) Name of software, e.g. "WordPress" (2) Version number, e.g. "5.6"
53
- self::e( __('Your version of %1$s is very old. We recommend you upgrade to at least v%2$s, but preferably to the latest stable version.','loco-translate'),'PHP',$phpupdate)?>
54
  </p>
55
  <p class="submit">
56
- <a class="button button-primary" href="https://www.php.net/releases/#<?php echo $phpupdate?>" target="_blank">PHP <?php echo $phpupdate?></a>
57
- <a class="button" href="https://www.php.net/downloads.php#v7" target="_blank">PHP 7</a>
58
- <a class="button" href="https://www.php.net/downloads.php#v8" target="_blank">PHP 8</a>
59
  </p>
60
  </div><?php
61
  endif;
@@ -69,7 +68,7 @@ $this->extend('../layout');
69
  self::e( __('WordPress %s','loco-translate'), $wpversion )?>
70
  </h3>
71
  <p><?php
72
- self::e( __('Your version of %1$s is very old. We recommend you upgrade to at least v%2$s, but preferably to the latest stable version.','loco-translate'),'WordPress',$wpupdate)?>
73
  </p>
74
  <p class="submit">
75
  <a class="button button-primary" href="<?php echo esc_url($wpupdate_href)?>"><?php esc_html_e('Update Now','default')?></a>
50
  </h3>
51
  <p><?php
52
  // translators: (1) Name of software, e.g. "WordPress" (2) Version number, e.g. "5.6"
53
+ self::e( __('Your version of %1$s is out of date. We recommend you upgrade to at least v%2$s, but preferably to the latest stable version.','loco-translate'),'PHP',$phpupdate)?>
54
  </p>
55
  <p class="submit">
56
+ <a class="button" href="https://www.php.net/downloads.php#v7" target="_blank">PHP 7.4</a>
57
+ <a class="button button-primary" href="https://www.php.net/downloads.php#v8" target="_blank">PHP 8.x</a>
 
58
  </p>
59
  </div><?php
60
  endif;
68
  self::e( __('WordPress %s','loco-translate'), $wpversion )?>
69
  </h3>
70
  <p><?php
71
+ self::e( __('Your version of %1$s is out of date. We recommend you upgrade to at least v%2$s, but preferably to the latest stable version.','loco-translate'),'WordPress',$wpupdate)?>
72
  </p>
73
  <p class="submit">
74
  <a class="button button-primary" href="<?php echo esc_url($wpupdate_href)?>"><?php esc_html_e('Update Now','default')?></a>
tpl/admin/errors/no-tokenizer.php CHANGED
@@ -15,7 +15,7 @@ $this->extend('../layout');
15
  // Translators: change "en" in the URL to your language if it's available at https://www.php.net/docs.php
16
  echo wp_kses(
17
  __('Loco requires the <a href="http://php.net/manual/en/book.tokenizer.php" target="_blank">Tokenizer extension</a> to scan PHP source code for translatable strings','loco-translate'),
18
- array('a'=>array('href'=>true,'target'=>true)), array('http','https')
19
  );?>.
20
  </p>
21
  <p><?php
@@ -23,7 +23,7 @@ $this->extend('../layout');
23
  $help = apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/templates');
24
  echo wp_kses(
25
  sprintf( __('You can still translate any bundle that has a <a href="%s" target="_blank">template</a>','loco-translate'), $help ),
26
- array('a'=>array('href'=>true,'target'=>true)), array('https')
27
  );?>.
28
  </p>
29
  </div>
15
  // Translators: change "en" in the URL to your language if it's available at https://www.php.net/docs.php
16
  echo wp_kses(
17
  __('Loco requires the <a href="http://php.net/manual/en/book.tokenizer.php" target="_blank">Tokenizer extension</a> to scan PHP source code for translatable strings','loco-translate'),
18
+ ['a'=>['href'=>true,'target'=>true]], ['http','https']
19
  );?>.
20
  </p>
21
  <p><?php
23
  $help = apply_filters('loco_external','https://localise.biz/wordpress/plugin/manual/templates');
24
  echo wp_kses(
25
  sprintf( __('You can still translate any bundle that has a <a href="%s" target="_blank">template</a>','loco-translate'), $help ),
26
+ ['a'=>['href'=>true,'target'=>true]], ['https']
27
  );?>.
28
  </p>
29
  </div>
tpl/admin/file/view-mo.php CHANGED
@@ -20,7 +20,7 @@ $this->start('source');
20
  $i = 0;
21
  $r = 0;
22
  $cols = 24;
23
- $line = array();
24
  $bytes = strlen($bin);
25
  // establish formatting of row offset, nbased on largest row number
26
  $rowfmt = sprintf( '%%0%uX | ', strlen( sprintf( '%02X', $cols * floor( $bytes / $cols ) ) ) );
@@ -47,7 +47,7 @@ $this->start('source');
47
  // wrap at cols, and print plain text
48
  if( ++$i === $cols ){
49
  echo ' ', implode('', $line ), "\n";
50
- $line = array();
51
  $i = 0;
52
  $r++;
53
  }
20
  $i = 0;
21
  $r = 0;
22
  $cols = 24;
23
+ $line = [];
24
  $bytes = strlen($bin);
25
  // establish formatting of row offset, nbased on largest row number
26
  $rowfmt = sprintf( '%%0%uX | ', strlen( sprintf( '%02X', $cols * floor( $bytes / $cols ) ) ) );
47
  // wrap at cols, and print plain text
48
  if( ++$i === $cols ){
49
  echo ' ', implode('', $line ), "\n";
50
+ $line = [];
51
  $i = 0;
52
  $r++;
53
  }
tpl/admin/init/upload.php CHANGED
@@ -48,7 +48,7 @@ $this->extend('../layout');
48
  // translators: This is HTML formatted. (1) placeholder for language code, (2) Example language code
49
  echo wp_kses (
50
  sprintf( __('Your file must be named as shown above where %1$s is the language code, e.g. %2$s','loco-translate'), '<code>{locale}</code>', '<code>'.$locale.'</code>' ),
51
- array('code'=>array())
52
  )?>
53
  </p>
54
  <p>
48
  // translators: This is HTML formatted. (1) placeholder for language code, (2) Example language code
49
  echo wp_kses (
50
  sprintf( __('Your file must be named as shown above where %1$s is the language code, e.g. %2$s','loco-translate'), '<code>{locale}</code>', '<code>'.$locale.'</code>' ),
51
+ ['code'=>[]]
52
  )?>
53
  </p>
54
  <p>
tpl/admin/layout.php CHANGED
@@ -6,15 +6,6 @@
6
  /* @var Loco_mvc_ViewParams $params */
7
  ?><div class="wrap" id="loco-admin"><?php
8
 
9
- // urgent warnings not dismissable
10
- if( $this->has('_deprecation') ):?>
11
- <div class="update-nag">
12
- <strong>Deprecation notice:</strong>
13
- The next version of Loco Translate will require a minimum of WordPress 5.2 and PHP 5.6.20.
14
- <a href="https://wordpress.org/about/requirements/">Update your system</a> or roll back to Loco Translate 2.5.7 to get rid of this message.
15
- </div><?php
16
- endif;
17
-
18
  if( $this->has('breadcrumb') ):?>
19
  <h1>
20
  <ul><?php
6
  /* @var Loco_mvc_ViewParams $params */
7
  ?><div class="wrap" id="loco-admin"><?php
8
 
 
 
 
 
 
 
 
 
 
9
  if( $this->has('breadcrumb') ):?>
10
  <h1>
11
  <ul><?php
tpl/admin/root.php CHANGED
@@ -25,7 +25,7 @@ $this->extend('layout');
25
  <p>
26
  <?php esc_html_e("Translations have been recently modified in the following bundles",'loco-translate')?>:
27
  </p><?php
28
- echo $this->render('list/inc-table', array( 'bundles' => $recent ) );?>
29
  </div><?php
30
  endif;?>
31
 
@@ -34,7 +34,7 @@ $this->extend('layout');
34
  <h2>
35
  <?php esc_html_e('Active theme:','loco-translate')?>
36
  </h2><?php
37
- echo $this->render('list/inc-table', array( 'bundles' => array($theme) ) )?>
38
  <p>
39
  <a href="<?php $this->route('theme')->e('href')?>" class="button button-link has-raquo"><?php esc_html_e('See all themes','loco-translate')?></a>
40
  </p>
@@ -49,7 +49,7 @@ $this->extend('layout');
49
  <p>
50
  <?php esc_html_e('These plugins have recently loaded translation files into the admin area','loco-translate')?>:
51
  </p><?php
52
- echo $this->render('list/inc-table', array( 'bundles' => $plugins ) )?>
53
  <p>
54
  <a href="<?php $this->route('plugin')->e('href')?>" class="button button-link has-raquo"><?php esc_html_e('See all plugins','loco-translate')?></a>
55
  </p>
25
  <p>
26
  <?php esc_html_e("Translations have been recently modified in the following bundles",'loco-translate')?>:
27
  </p><?php
28
+ echo $this->render('list/inc-table', [ 'bundles' => $recent ] );?>
29
  </div><?php
30
  endif;?>
31
 
34
  <h2>
35
  <?php esc_html_e('Active theme:','loco-translate')?>
36
  </h2><?php
37
+ echo $this->render('list/inc-table', [ 'bundles' => [$theme] ] )?>
38
  <p>
39
  <a href="<?php $this->route('theme')->e('href')?>" class="button button-link has-raquo"><?php esc_html_e('See all themes','loco-translate')?></a>
40
  </p>
49
  <p>
50
  <?php esc_html_e('These plugins have recently loaded translation files into the admin area','loco-translate')?>:
51
  </p><?php
52
+ echo $this->render('list/inc-table', [ 'bundles' => $plugins ] )?>
53
  <p>
54
  <a href="<?php $this->route('plugin')->e('href')?>" class="button button-link has-raquo"><?php esc_html_e('See all plugins','loco-translate')?></a>
55
  </p>