kenan hace 1 año
padre
commit
e5f961dc4b
Se han modificado 100 ficheros con 13033 adiciones y 0 borrados
  1. 448 0
      admin/css/admin.css
  2. 105 0
      admin/css/load.css
  3. 140 0
      admin/css/other/console1.css
  4. 18 0
      admin/css/other/console2.css
  5. 6 0
      admin/css/other/department.css
  6. 76 0
      admin/css/other/error.css
  7. 531 0
      admin/css/other/icon.css
  8. 93 0
      admin/css/other/login.css
  9. 80 0
      admin/css/other/person.css
  10. 39 0
      admin/css/other/result.css
  11. 59 0
      admin/data/cpa_menu.json
  12. 51 0
      admin/data/cps_menu.json
  13. 67 0
      admin/data/menu.json
  14. 88 0
      admin/data/message.json
  15. 508 0
      admin/images/403.svg
  16. 314 0
      admin/images/404.svg
  17. 191 0
      admin/images/500.svg
  18. BIN
      admin/images/act.jpg
  19. BIN
      admin/images/avatar.jpg
  20. 33 0
      admin/images/background.svg
  21. BIN
      admin/images/captcha.gif
  22. BIN
      admin/images/logo.png
  23. BIN
      admin/images/show.png
  24. 627 0
      app/app.js
  25. 6191 0
      app/assets/js/crypto/crypto-js.js
  26. 27 0
      app/assets/js/plupload-2.3.7/bower.json
  27. 85 0
      app/assets/js/plupload-2.3.7/examples/custom.html
  28. 34 0
      app/assets/js/plupload-2.3.7/examples/dump.php
  29. 217 0
      app/assets/js/plupload-2.3.7/examples/events.html
  30. 139 0
      app/assets/js/plupload-2.3.7/examples/jquery/all_runtimes.html
  31. 113 0
      app/assets/js/plupload-2.3.7/examples/jquery/jquery_ui_widget.html
  32. 66 0
      app/assets/js/plupload-2.3.7/examples/jquery/queue_widget.html
  33. 131 0
      app/assets/js/plupload-2.3.7/examples/jquery/s3.php
  34. 126 0
      app/assets/js/plupload-2.3.7/examples/upload.php
  35. BIN
      app/assets/js/plupload-2.3.7/js/Moxie.swf
  36. BIN
      app/assets/js/plupload-2.3.7/js/Moxie.xap
  37. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ar.js
  38. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/az.js
  39. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/bg.js
  40. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/bs.js
  41. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ca.js
  42. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/cs.js
  43. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/cy.js
  44. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/da.js
  45. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/de.js
  46. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/el.js
  47. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/en.js
  48. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/es.js
  49. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/et.js
  50. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/fa.js
  51. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/fi.js
  52. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/fr.js
  53. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/he.js
  54. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/hr.js
  55. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/hu.js
  56. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/hy.js
  57. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/id.js
  58. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/it.js
  59. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ja.js
  60. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ka.js
  61. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/kk.js
  62. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/km.js
  63. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ko.js
  64. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ku_IQ.js
  65. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/lt.js
  66. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/lv.js
  67. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/ms.js
  68. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/nl.js
  69. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/pl.js
  70. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/pt.js
  71. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/pt_BR.js
  72. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/ro.js
  73. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/ru.js
  74. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/sk.js
  75. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/sl.js
  76. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/sq.js
  77. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/sr.js
  78. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/sv.js
  79. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/th_TH.js
  80. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/tr.js
  81. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/uk_UA.js
  82. 1 0
      app/assets/js/plupload-2.3.7/js/i18n/vi.js
  83. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/zh_CN.js
  84. 2 0
      app/assets/js/plupload-2.3.7/js/i18n/zh_TW.js
  85. 185 0
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/css/jquery.plupload.queue.css
  86. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/backgrounds.gif
  87. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/buttons-disabled.png
  88. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/buttons.png
  89. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/delete.gif
  90. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/done.gif
  91. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/error.gif
  92. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/throbber.gif
  93. BIN
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/transp50.png
  94. 433 0
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/jquery.plupload.queue.js
  95. 0 0
      app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/jquery.plupload.queue.min.js
  96. 379 0
      app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/css/jquery.ui.plupload.css
  97. BIN
      app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/img/loading.gif
  98. BIN
      app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/img/plupload.png
  99. 1358 0
      app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/jquery.ui.plupload.js
  100. 0 0
      app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/jquery.ui.plupload.min.js

+ 448 - 0
admin/css/admin.css

@@ -0,0 +1,448 @@
+html,
+body,
+.layui-layout {
+	height: 100%;
+}
+
+.pear-admin .layui-header,
+.pear-admin .layui-body,
+.pear-admin .layui-logo,
+.pear-admin .layui-side,
+.pear-admin .layui-header .layui-layout-left {
+	transition: all .3s;
+}
+
+.pear-admin .layui-logo .title {
+	font-size: 20px;
+}
+
+.pear-admin .layui-layout-right .layui-nav-child {
+	border: 1px solid whitesmoke;
+	border-radius: 4px;
+	width: 150px;
+}
+
+.pear-admin .layui-header {
+	left: 230px;
+	width: calc(100% - 230px);
+	background-color: white;
+	border-bottom: 1px solid whitesmoke;
+}
+
+.pear-admin .layui-header .layui-nav-img {
+	width: 30px;
+	height: 30px;
+}
+
+.pear-admin .layui-layout-control {
+	left: 140px;
+	position: absolute;
+}
+
+.pear-admin .layui-layout-control .layui-nav{
+	padding: 0px;
+}
+
+.pear-admin .layui-logo {
+	width: 230px;
+	height: 59px;
+	line-height: 59px;
+	position: relative;
+	background-color: #28333E;
+	border-bottom: 1px solid rgba(0,0,0,.12);
+}
+
+.pear-admin .layui-logo img {
+	width: 34px;
+	height: 34px;
+}
+
+.pear-admin .layui-logo .title {
+	font-size: 21px;
+	font-weight: 550;
+	color: #5FB878;
+	position: relative;
+	top: 5px;
+	margin-left: 5px;
+}
+
+.pear-admin .layui-logo .logo {
+	display: none;
+}
+
+.pear-admin .layui-side {
+	top: 0px;
+	width: 230px;
+	box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
+	z-index: 9999;
+}
+
+.pear-admin .layui-side-scroll::-webkit-scrollbar {
+	width: 0px;
+	height: 0px;
+}
+
+.pear-admin .layui-side-scroll {
+	height: calc(100% - 60px) !important;
+	background-color: #28333E;
+	width: 247px;
+
+}
+
+.pear-admin .layui-header .layui-nav .layui-nav-item>a {
+	color: black;
+	font-size: 15px;
+}
+
+.pear-admin .layui-body {
+	left: 230px;
+	bottom: 0px;
+	padding-bottom: 0px;
+}
+
+.pear-admin .layui-layout-left {
+	left: 0px;
+}
+
+/** 隐 藏 布 局 样 式 */
+.pear-mini .layui-logo .title {
+	display: none;
+}
+
+.pear-mini .layui-logo .logo {
+	display: inline-block;
+}
+
+.pear-mini .layui-side {
+	width: 60px;
+}
+
+.pear-mini .layui-header {
+	left: 60px;
+	width: calc(100% - 60px);
+}
+
+.pear-mini .layui-body {
+	left: 60px;
+}
+
+.pear-mini .layui-logo {
+	width: 60px;
+}
+
+.pear-mini .layui-nav-tree .layui-nav-item span {
+	display: none;
+}
+
+.pear-mini .bottom-nav li {
+	width: 100% !important;
+}
+
+.pear-mini .layui-side-scroll {
+	height: calc(100% - 60px);
+}
+
+.pear-admin .layui-header .layui-nav .layui-nav-bar {
+	top: 0px !important;
+	height: 2px !important;
+	background-color: #5FB878;
+}
+
+.pear-admin .layui-header .layui-nav .layui-this:after {
+	display: none;
+}
+
+.pear-admin .layui-header .layui-nav-more {
+	display: none;
+}
+
+.pear-collasped-pe {
+	display: none;
+	width: 50px;
+	position: absolute;
+	z-index: 400000;
+	bottom: 30px;
+	right: 30px;
+	background-color: #5FB878 !important;
+	height: 50px;
+	line-height: 50px;
+	text-align: center;
+	border-radius: 50px;
+	box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
+}
+
+.pear-collasped-pe a {
+	color: white !important;
+}
+
+@media screen and (min-width: 768px) {
+	.layui-hide-sm {
+		display: inline-block !important;
+	}
+}
+
+@media screen and (min-width: 769px) {
+	.layui-hide-sm {
+		display: none !important;
+	}
+}
+
+/** 新增兼容 */
+@media screen and (max-width:768px) {
+	.collaspe {
+		display: none !important;
+	}
+
+	.pear-collasped-pe {
+		display: inline-block !important;
+	}
+
+	.layui-layout-control {
+		left: 45px !important;
+	}
+
+	.layui-layout-left {
+		padding-left: 10px;
+		padding-right: 10px;
+	}
+
+	.pear-mini .bottom-nav {
+		display: none;
+	}
+
+	.pear-mini .layui-side-scroll {
+		height: calc(100% - 62px);
+	}
+
+	/** 隐 藏 布 局 样 式 */
+	.pear-mini .layui-side {
+		width: 0px;
+	}
+
+	.pear-mini .layui-header {
+		left: 0px;
+		width: 100%;
+	}
+
+	.pear-mini .layui-body {
+		left: 0px;
+	}
+
+	.pear-mini .layui-logo {
+		width: 0px;
+	}
+
+	.pear-admin .layui-body {
+		left: 0px;
+	}
+
+	.pear-admin .layui-header {
+		left: 0px;
+		width: 100%;
+	}
+
+	.pear-admin .pear-cover {
+		width: 100%;
+		height: 100%;
+		background-color: #1E1E1E;
+		display: block;
+		position: absolute;
+		z-index: 1000;
+		opacity: 0;
+		margin-top: -60px;
+	}
+
+	.pear-mini .pear-cover {
+		display: none;
+	}
+}
+
+@-webkit-keyframes am-horizontal-roll_show {
+	0% {
+		opacity: 1;
+		-webkit-transform: translateX(2000px);
+		transform: translateX(2000px)
+	}
+
+	100% {
+		opacity: 1;
+		-webkit-transform: translateX(0);
+		transform: translateX(0)
+	}
+}
+
+@keyframes am-horizontal-roll_show {
+	0% {
+		opacity: 1;
+		-webkit-transform: translateX(800px);
+		-ms-transform: translateX(800px);
+		transform: translateX(800px)
+	}
+
+	100% {
+		opacity: 1;
+		-webkit-transform: translateX(0);
+		-ms-transform: translateX(0);
+		transform: translateX(0)
+	}
+}
+
+.layer-anim-right {
+	-webkit-animation: am-horizontal-roll_show .6s ease-out;
+	animation: am-horizontal-roll_show .6s ease-out;
+
+}
+
+/** 亮色侧边风格 */
+.light-theme .layui-logo {
+	background-color: white !important;
+	color: black !important;
+	border-bottom: 1px whitesmoke solid;
+}
+
+.light-theme .layui-side-scroll {
+	background-color: white !important;
+	color: black !important;
+}
+
+.light-theme .layui-side {
+	box-shadow: 2px 0 8px 0 rgba(29, 35, 41, .05) !important;
+}
+
+/** 主 题 选 择 界 面 样 式 */
+.pearone-color .color-title {
+	padding: 15px 0 0px 20px;
+	margin-bottom: 4px;
+}
+
+.pearone-color .color-content {
+	padding: 15px 10px 0 20px;
+}
+
+.pearone-color .color-content ul {
+	list-style: none;
+	padding: 0px;
+}
+
+.pearone-color .color-content ul li {
+	position: relative;
+	display: inline-block;
+	vertical-align: top;
+	width: 70px;
+	height: 50px;
+	margin: 0 20px 20px 0;
+	padding: 2px 2px 2px 2px;
+	background-color: #f2f2f2;
+	cursor: pointer;
+	font-size: 12px;
+	color: #666;
+}
+
+.pearone-color .color-content li.layui-this:after,
+.pearone-color .color-content li:hover:after {
+	width: 100%;
+	height: 100%;
+	padding: 4px;
+	top: -5px;
+	left: -5px;
+	border: #5FB878 2px solid;
+	opacity: 1;
+	border-radius: 4px;
+}
+
+.pearone-color .color-content li:after {
+	content: '';
+	position: absolute;
+	z-index: 20;
+	top: 50%;
+	left: 50%;
+	width: 1px;
+	height: 0;
+	border: 2px solid #F2F2F2;
+	transition: all .3s;
+	-webkit-transition: all .3s;
+	opacity: 0;
+}
+
+.select-color {
+	margin-bottom: 30px;
+}
+
+.select-color .select-color-title {
+	padding: 15px 0 0px 20px;
+	margin-bottom: 4px;
+}
+
+.select-color .select-color-content {
+	padding: 20px 0 0px 0px;
+	margin-bottom: 4px;
+}
+
+.select-color .select-color-content .select-color-item {
+	background-color: gray;
+	width: 30px;
+	height: 30px;
+	border-radius: 3px;
+	float: left;
+	margin-left: 20px;
+	color: white;
+	font-size: 18px;
+	text-align: center;
+	box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .15);
+	line-height: 30px;
+}
+
+/** 友情链接 */
+.more-setting {
+	margin-top: 45px;
+}
+
+.more-setting form {
+	margin-top: 30px;
+}
+
+.more-setting-title {
+	padding: 15px 0 0px 20px;
+	margin-bottom: 4px;
+}
+
+.more-setting .layui-form-label {
+	width: 60px;
+}
+
+.more-menu-list {
+	width: 100%;
+	margin-top: 80px;
+}
+
+.more-menu-item:first-child {
+	border-top: 1px solid #e8e8e8;
+}
+
+.more-menu-item .layui-icon {
+	font-size: 18px;
+	padding-right: 10px;
+}
+
+.more-menu-item {
+	color: #595959;
+	height: 50px;
+	line-height: 50px;
+	font-size: 16px;
+	padding: 0 25px;
+	border-bottom: 1px solid #e8e8e8;
+	font-style: normal;
+	display: block;
+}
+
+.more-menu-item:hover {
+	background-color: whitesmoke;
+}
+
+.more-menu-item:after {
+	color: #8c8c8c;
+	right: 16px;
+	content: "\e602";
+	position: absolute;
+	font-family: layui-icon !important;
+}

+ 105 - 0
admin/css/load.css

@@ -0,0 +1,105 @@
+.loader-main{
+	position: fixed;
+	width: 100%;
+	height: 100%;
+	background-color: whitesmoke;
+	z-index: 9999999;
+}
+.loader {
+	width: 50px;
+	height: 50px;
+	margin: 30px auto 40px;
+	margin-top: 20%;
+	position: relative;
+	z-index: 999999;
+	background-color: whitesmoke;
+}
+.loader:before {
+	content: "";
+	width: 50px;
+	height: 7px;
+	border-radius: 50%;
+	background: #000;
+	opacity: 0.1;
+	position: absolute;
+	top: 59px;
+	left: 0;
+	animation: shadow .5s linear infinite;
+}
+.loader:after {
+	content: "";
+	width: 50px;
+	height: 50px;
+	border-radius: 3px;
+	 background-color: #5FB878;
+	position: absolute;
+	top: 0;
+	left: 0;
+	animation: loading .5s linear infinite;
+}
+@-webkit-keyframes loading {
+	17% {
+		border-bottom-right-radius: 3px;
+	}
+
+	25% {
+		transform: translateY(9px) rotate(22.5deg);
+	}
+
+	50% {
+		transform: translateY(18px) scale(1, 0.9) rotate(45deg);
+		border-bottom-right-radius: 40px;
+	}
+
+	75% {
+		transform: translateY(9px) rotate(67.5deg);
+	}
+
+	100% {
+		transform: translateY(0) rotate(90deg);
+	}
+}
+@keyframes loading {
+	17% {
+		border-bottom-right-radius: 3px;
+	}
+
+	25% {
+		transform: translateY(9px) rotate(22.5deg);
+	}
+
+	50% {
+		transform: translateY(18px) scale(1, 0.9) rotate(45deg);
+		border-bottom-right-radius: 40px;
+	}
+
+	75% {
+		transform: translateY(9px) rotate(67.5deg);
+	}
+
+	100% {
+		transform: translateY(0) rotate(90deg);
+	}
+}
+@-webkit-keyframes shadow {
+
+	0%,
+	100% {
+		transform: scale(1, 1);
+	}
+
+	50% {
+		transform: scale(1.2, 1);
+	}
+}
+@keyframes shadow {
+
+	0%,
+	100% {
+		transform: scale(1, 1);
+	}
+
+	50% {
+		transform: scale(1.2, 1);
+	}
+}

+ 140 - 0
admin/css/other/console1.css

@@ -0,0 +1,140 @@
+.top-panel {
+	border-radius: 4px;
+	text-align: center;
+}
+
+.top-panel>.layui-card-body {
+	height: 60px;
+}
+
+.top-panel-number {
+	line-height: 60px;
+	font-size: 30px;
+	border-right: 1px solid #eceff9;
+}
+
+.top-panel-tips {
+	padding-left: 8px;
+	padding-top: 16px;
+	line-height: 30px;
+	font-size: 12px;
+}
+
+.pear-container {
+	background-color: whitesmoke;
+	margin: 10px;
+}
+
+.card {
+	width: 100%;
+	height: 160px;
+	background-color: whitesmoke;
+	border-radius: 4px;
+}
+
+.card .header .avatar {
+	width: 28px;
+	height: 28px;
+	margin: 20px;
+	border-radius: 50px;
+}
+
+.card .header {
+	color: dimgray;
+}
+
+.card .body {
+	color: gray;
+}
+
+.card .body {
+	margin-left: 20px;
+	margin-right: 20px;
+}
+
+.card .footer {
+	margin-left: 20px;
+	margin-right: 20px;
+	margin-top: 20px;
+	font-size: 13px;
+	color: gray;
+	position: absolute;
+}
+
+.custom-tab .layui-tab-title {
+	border-bottom-width: 0px;
+	border-bottom-style: none;
+}
+
+.custom-tab .layui-tab-title li {
+	margin-left: 10px;
+}
+.list .list-item {
+	height: 32px;
+	line-height: 32px;
+	color: gray;
+	padding: 5px;
+	padding-left: 15px;
+	border-radius: 4px;
+	margin-top: 5.2px;
+}
+
+.list .list-item:hover {
+	background-color: whitesmoke;
+}
+
+.list .list-item .title {
+	font-size: 13px;
+	width: 100%;
+}
+
+.list .list-item .footer {
+	position: absolute;
+	right: 30px;
+	font-size: 12px;
+}
+
+.top-panel-tips i {
+	font-size: 33px;
+}
+
+.layuiadmin-card-status {
+	padding: 0 10px 10px;
+}
+
+.layuiadmin-card-status dd {
+	padding: 15px 0;
+	border-bottom: 1px solid #EEE;
+	display: -webkit-flex;
+	display: flex;
+}
+
+.layuiadmin-card-status dd div.layui-status-img,
+.layuiadmin-card-team .layui-team-img {
+	width: 32px;
+	height: 32px;
+	border-radius: 50%;
+	margin-right: 15px;
+}
+
+.layuiadmin-card-status dd div.layui-status-img a {
+	width: 100%;
+	height: 100%;
+	display: inline-block;
+	text-align: center;
+	line-height: 32px;
+}
+
+.layuiadmin-card-status dd div span {
+	color: #BBB;
+}
+
+.layuiadmin-card-status dd div a {
+	color: #01AAED;
+}
+
+.top-panel-tips svg {
+	margin-top: -12px;
+	width: 50px;
+	height: 50px;
+}

+ 18 - 0
admin/css/other/console2.css

@@ -0,0 +1,18 @@
+			.pear-container {background-color: whitesmoke;margin: 10px;}
+			.pear-card {width: 100%;height: 66px;background-color: #F8F8F8;display: inline-block;border-radius: 5px;text-align: center;margin-bottom: 3px;}
+            .pear-card:hover,.pear-card2:hover{box-shadow: 2px 0 8px 0 lightgray!important;}.pear-card2 {width: 100%;height: 90px;background-color: #F8F8F8;display: inline-block;border-radius: 5px;text-align: center;margin-bottom: 3px;}
+			.pear-card2 i {font-size: 30px;height: 90px;line-height: 90px;}
+			.pear-card i {font-size: 30px;height: 66px;line-height: 66px;}
+			.layui-col-md3 {text-align: center;}
+			.pear-card-title {margin-top: 3px;}
+			.person img {width: 90px;height: 90px;border-radius: 4px;margin-top: 8px;margin-left: 8px;}
+			.pear-card2 .count {color: #51A351;font-size: 30px;margin-top: 12px;}
+			.pear-card2 .title {color: gray;font-size: 14px;margin-top: 14px;}
+			.pear-card-status {padding: 0 10px 10px;}
+			.pear-card-status li {position: relative;padding: 10px 0;border-bottom: 1px solid #EEE;}
+			.pear-card-status li h3 {padding-bottom: 5px;font-weight: 700;}
+			.pear-card-status li p {padding-bottom: 10px;padding-top: 3px ;}
+			.pear-card-status li>span {color: #999;}
+			.pear-reply {position: absolute;right: 20px;}
+			.person .title{font-size: 17px;font-weight: 600;margin-left: 18px;margin-top: 16px;position: absolute;display: inline-block;}
+			.person .desc{font-size: 16px;font-weight: 600;margin-left: 115px;margin-top: -30px;position: absolute;display: inline-block;}

+ 6 - 0
admin/css/other/department.css

@@ -0,0 +1,6 @@
+.organizationTree {
+	width: 100% !important;
+	height: -webkit-calc(100vh - 130px);
+	height: -moz-calc(100vh - 130px);
+	height: calc(100vh - 130px);
+}

+ 76 - 0
admin/css/other/error.css

@@ -0,0 +1,76 @@
+* {
+	padding: 0;
+	margin: 0;
+	font-size: 0.38rem;
+}
+
+ul {
+	list-style: none;
+}
+
+a {
+	text-decoration: none;
+	-webkit-tap-highlight-color: transparent
+}
+
+.clearfix:after {
+	content: '';
+	width: 0;
+	height: 0;
+	display: block;
+	clear: both;
+}
+
+html {
+	height: 100%;
+	width: 100%;
+}
+
+body {
+	font-size: 0.28rem;
+	height: 100%;
+	width: 100%;
+	display: flex;
+	flex-direction: column;
+	position: relative;
+	background-color: white !important;
+}
+
+.content {
+	position: absolute;
+	top: 50%;
+	transform: translateY(-50%);
+	width: 100%;
+	text-align: center;
+}
+
+.content>img {
+	height: 300px;
+	max-width: 370px;
+	margin-right: 180px;
+}
+
+.content>* {
+	display: inline-block;
+}
+
+.content-r {
+	vertical-align: top;
+}
+
+.content-r>h1 {
+	font-size: 72px;
+	color: #434e59;
+	margin-bottom: 24px;
+	font-weight: 600;
+}
+
+.content-r>p {
+	font-size: 20px;
+	color: rgba(0, 0, 0, .45);
+	margin-bottom: 16px;
+}
+
+button {
+	margin-top: 20px;
+}

+ 531 - 0
admin/css/other/icon.css

@@ -0,0 +1,531 @@
+/* Logo 字体 */
+@font-face {
+  font-family: "iconfont logo";
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+  font-family: "iconfont logo";
+  font-size: 160px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+  position: relative;
+}
+
+.nav-tabs .nav-more {
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  height: 42px;
+  line-height: 42px;
+  color: #666;
+}
+
+#tabs {
+  border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+  cursor: pointer;
+  width: 100px;
+  height: 40px;
+  line-height: 40px;
+  text-align: center;
+  font-size: 16px;
+  border-bottom: 2px solid transparent;
+  position: relative;
+  z-index: 1;
+  margin-bottom: -1px;
+  color: #666;
+}
+
+
+#tabs .active {
+  border-bottom-color: #f00;
+  color: #222;
+}
+
+.tab-container .content {
+  display: none;
+}
+
+/* 页面布局 */
+.main {
+  padding: 30px 100px;
+  width: 960px;
+  margin: 0 auto;
+}
+
+.main .logo {
+  color: #333;
+  text-align: left;
+  margin-bottom: 30px;
+  line-height: 1;
+  height: 110px;
+  margin-top: -50px;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.main .logo a {
+  font-size: 160px;
+  color: #333;
+}
+
+.helps {
+  margin-top: 40px;
+}
+
+.helps pre {
+  padding: 20px;
+  margin: 10px 0;
+  border: solid 1px #e7e1cd;
+  background-color: #fffdef;
+  overflow: auto;
+}
+
+.icon_lists {
+  width: 100% !important;
+  overflow: hidden;
+  *zoom: 1;
+}
+
+.icon_lists li {
+  width: 100px;
+  margin-bottom: 10px;
+  margin-right: 20px;
+  text-align: center;
+  list-style: none !important;
+  cursor: default;
+}
+
+.icon_lists li .code-name {
+  line-height: 1.2;
+}
+
+.icon_lists .icon {
+  display: block;
+  height: 100px;
+  line-height: 100px;
+  font-size: 42px;
+  margin: 10px auto;
+  color: #333;
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
+  transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+  font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+  /* 通过设置 font-size 来改变图标大小 */
+  width: 1em;
+  /* 图标和文字相邻时,垂直对齐 */
+  vertical-align: -0.15em;
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
+  fill: currentColor;
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+      normalize.css 中也包含这行 */
+  overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+  color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+  color: #666;
+  font-size: 14px;
+  line-height: 1.8;
+}
+
+.highlight {
+  line-height: 1.5;
+}
+
+.markdown img {
+  vertical-align: middle;
+  max-width: 100%;
+}
+
+.markdown h1 {
+  color: #404040;
+  font-weight: 500;
+  line-height: 40px;
+  margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+  color: #404040;
+  margin: 1.6em 0 0.6em 0;
+  font-weight: 500;
+  clear: both;
+}
+
+.markdown h1 {
+  font-size: 28px;
+}
+
+.markdown h2 {
+  font-size: 22px;
+}
+
+.markdown h3 {
+  font-size: 16px;
+}
+
+.markdown h4 {
+  font-size: 14px;
+}
+
+.markdown h5 {
+  font-size: 12px;
+}
+
+.markdown h6 {
+  font-size: 12px;
+}
+
+.markdown hr {
+  height: 1px;
+  border: 0;
+  background: #e9e9e9;
+  margin: 16px 0;
+  clear: both;
+}
+
+.markdown p {
+  margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+  width: 80%;
+}
+
+.markdown ul>li {
+  list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+  margin: 0.6em 0;
+}
+
+.markdown ol>li {
+  list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+  margin-left: 20px;
+  padding-left: 4px;
+}
+
+.markdown code {
+  margin: 0 3px;
+  padding: 0 5px;
+  background: #eee;
+  border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+  font-weight: 600;
+}
+
+.markdown>table {
+  border-collapse: collapse;
+  border-spacing: 0px;
+  empty-cells: show;
+  border: 1px solid #e9e9e9;
+  width: 95%;
+  margin-bottom: 24px;
+}
+
+.markdown>table th {
+  white-space: nowrap;
+  color: #333;
+  font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+  border: 1px solid #e9e9e9;
+  padding: 8px 16px;
+  text-align: left;
+}
+
+.markdown>table th {
+  background: #F7F7F7;
+}
+
+.markdown blockquote {
+  font-size: 90%;
+  color: #999;
+  border-left: 4px solid #e9e9e9;
+  padding-left: 0.8em;
+  margin: 1em 0;
+}
+
+.markdown blockquote p {
+  margin: 0;
+}
+
+.markdown .anchor {
+  opacity: 0;
+  transition: opacity 0.3s ease;
+  margin-left: 8px;
+}
+
+.markdown .waiting {
+  color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+  opacity: 1;
+  display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+  clear: both;
+}
+
+
+.hljs {
+  display: block;
+  background: white;
+  padding: 0.5em;
+  color: #333333;
+  overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+  color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+  color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+  color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+  color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+  color: #63a35c;
+}
+
+.hljs-tag {
+  color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+  color: #795da3;
+}
+
+.hljs-addition {
+  color: #55a532;
+  background-color: #eaffea;
+}
+
+.hljs-deletion {
+  color: #bd2c00;
+  background-color: #ffecec;
+}
+
+.hljs-link {
+  text-decoration: underline;
+}
+
+code[class*="language-"],
+pre[class*="language-"] {
+  color: black;
+  background: none;
+  text-shadow: 0 1px white;
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+
+@media print {
+
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+  padding: 1em;
+  margin: .5em 0;
+  overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+  padding: .1em;
+  border-radius: .3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: slategray;
+}
+
+.token.punctuation {
+  color: #999;
+}
+
+.namespace {
+  opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+  color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+  color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+
+.token.function,
+.token.class-name {
+  color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: #e90;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}

+ 93 - 0
admin/css/other/login.css

@@ -0,0 +1,93 @@
+.layui-form {
+	width: 320px !important;
+	margin: auto !important;
+	margin-top: 160px !important;
+}
+
+.layui-form button {
+	width: 100% !important;
+	height: 44px !important;
+	line-height: 44px !important;
+	font-size: 16px !important;
+	background-color: #5FB878 !important;
+	font-weight: 550 !important;
+}
+
+.layui-form-checked[lay-skin=primary] i {
+	border-color: #5FB878 !important;
+	background-color: #5FB878 !important;
+	color: #fff !important;
+}
+
+.layui-tab-content {
+	margin-top: 15px !important;
+	padding-left: 0px !important;
+	padding-right: 0px !important;
+}
+
+.layui-form-item {
+	margin-top: 20px !important;
+}
+
+.layui-input {
+	height: 44px !important;
+	line-height: 44px !important;
+	padding-left: 15px !important;
+	border-radius: 3px !important;
+}
+
+.layui-input:focus {
+	box-shadow: 0px 0px 2px 1px #5FB878 !important;
+}
+
+.layui-form-danger:focus{
+	box-shadow: 0px 0px 2px 1px #f56c6c !important;
+}
+
+.logo {
+	width: 60px !important;
+	margin-top: 10px !important;
+	margin-bottom: 10px !important;
+	margin-left: 20px !important;
+}
+
+.title {
+	font-size: 30px !important;
+	font-weight: 550 !important;
+	margin-left: 20px !important;
+	color: #5FB878 !important;
+	display: inline-block !important;
+	height: 60px !important;
+	line-height: 60px !important;
+	margin-top: 10px !important;
+	position: absolute !important;
+}
+
+.desc {
+	width: 100% !important;
+	text-align: center !important;
+	color: gray !important;
+	height: 60px !important;
+	line-height: 60px !important;
+}
+
+body {
+	background-repeat:no-repeat;
+	background-color: whitesmoke;
+	background-size: 100%;
+	height: 100%;
+ }
+
+.code {
+	float: left;
+	margin-right: 13px;
+	margin: 0px !important;
+	border: #e6e6e6 1px solid;
+	display: inline-block!important;
+}
+
+.codeImage {
+	float: right;
+	height: 42px;
+	border: #e6e6e6 1px solid;
+}

+ 80 - 0
admin/css/other/person.css

@@ -0,0 +1,80 @@
+.pear-container {
+	background-color: whitesmoke;
+	margin: 10px;
+}
+.layui-body {
+	padding: 25px;
+}
+.text-center {
+	text-align: center;
+}
+.user-info-head {
+	width: 110px;
+	height: 110px;
+	line-height: 110px;
+	position: relative;
+	display: inline-block;
+	border-radius: 50%;
+	overflow: hidden;
+	cursor: pointer;
+	margin: 0 auto;
+}
+.layui-line-dash {
+	border-bottom: 1px dashed #ccc;
+	margin: 15px 0;
+}
+.comment {
+	position: absolute;
+	bottom: 3px;
+	right: 10px;
+	font-size: 12px;
+	color: dimgray;
+}
+.content {
+	padding-left: 13px;
+	font-size: 13px;
+	color: dimgray;
+}
+.title {
+	padding-left: 13.5px;
+}
+.layui-tab-title {
+	border-bottom: none;
+}
+.fl-item {
+	height: 30px;
+	font-size: 13.5;
+}
+.dot {
+	width: 10px;
+	height: 10px;
+	border-radius: 50px;
+	background-color: gray;
+	display: inline-block;
+	margin-right: 10px;
+}
+
+.list .list-item {
+	height: 32px;
+	line-height: 32px;
+	color: gray;
+	padding: 5px;
+	padding-left: 15px;
+	border-radius: 4px;
+	margin-top: 5.2px;
+}
+
+.list .list-item:hover {
+	background-color: whitesmoke;
+}
+
+.list .list-item .title {
+	font-size: 13px;
+	width: 100%;
+}
+
+.list .list-item .footer {
+	position: absolute;
+	right: 30px;
+	font-size: 12px;
+}

+ 39 - 0
admin/css/other/result.css

@@ -0,0 +1,39 @@
+.result {
+	text-align: center;
+
+}
+.result .success svg {
+	color: #32C682;
+	text-align: center;
+	margin-top: 40px;
+
+}
+.result .error svg {
+	color: #f56c6c;
+	text-align: center;
+	margin-top: 40px;
+
+}
+.result .title {
+	margin-top: 25px;
+
+}
+.result .desc {
+	margin-top: 25px;
+	width: 60%;
+	margin-left: 20%;
+	color: rgba(0, 0, 0, .45);
+}
+.result .content {
+	margin-top: 20px;
+	width: 80%;
+	border-radius: 10px;
+	background-color: whitesmoke;
+	height: 200px;
+	margin-left: 10%;
+}
+.result .action {
+	padding-top: 10px;
+	border-top: 1px whitesmoke solid;
+	margin-top: 25px;
+}

+ 59 - 0
admin/data/cpa_menu.json

@@ -0,0 +1,59 @@
+[
+  {
+    "id": 101,
+    "title": "总数据",
+    "icon": "layui-icon layui-icon-template-1",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/home/dashboard.html"
+  },
+  {
+    "id": 301,
+    "title": "代理列表",
+    "icon": "layui-icon layui-icon-user",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/agent/agent_list.html"
+  },
+  {
+    "id": "agent-dashboard",
+    "title": "提现管理",
+    "type": 0,
+    "icon": "layui-icon layui-icon-circle-dot",
+    "href": "",
+    "children": [
+      {
+        "id": 401,
+        "title": "立即提现",
+        "icon": "",
+        "type": 1,
+        "openType": "_iframe",
+        "href": "view/withdrawal/withdrawal_list.html"
+      },
+      {
+        "id": 402,
+        "title": "提现方式",
+        "icon": "",
+        "type": 1,
+        "openType": "_iframe",
+        "href": "view/withdraw/withdraw_list.html"
+      }
+    ]
+  },
+  {
+    "id": 501,
+    "title": "统计",
+    "icon": "layui-icon layui-icon-date",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/total/total.html"
+  },
+  {
+    "id": 601,
+    "title": "个人设置",
+    "icon": "layui-icon layui-icon-face-smile",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "/view/me/me_edit.html"
+  }
+]

+ 51 - 0
admin/data/cps_menu.json

@@ -0,0 +1,51 @@
+[
+  {
+    "id": 101,
+    "title": "总数据",
+    "icon": "layui-icon layui-icon-template-1",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/home/dashboard.html"
+  },
+  {
+    "id": 301,
+    "title": "代理列表",
+    "icon": "layui-icon layui-icon-user",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/agent/agent_list.html"
+  },
+  {
+    "id": "agent-dashboard",
+    "title": "提现管理",
+    "type": 0,
+    "icon": "layui-icon layui-icon-circle-dot",
+    "href": "",
+    "children": [
+      {
+        "id": 401,
+        "title": "立即提现",
+        "icon": "",
+        "type": 1,
+        "openType": "_iframe",
+        "href": "view/withdrawal/withdrawal_list.html"
+      },
+      {
+        "id": 402,
+        "title": "提现方式",
+        "icon": "",
+        "type": 1,
+        "openType": "_iframe",
+        "href": "view/withdraw/withdraw_list.html"
+      }
+    ]
+  },
+  {
+    "id": 601,
+    "title": "个人设置",
+    "icon": "layui-icon layui-icon-face-smile",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "/view/me/me_edit.html"
+  }
+]

+ 67 - 0
admin/data/menu.json

@@ -0,0 +1,67 @@
+[
+  {
+    "id": 101,
+    "title": "总数据",
+    "icon": "layui-icon layui-icon-template-1",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/home/dashboard.html"
+  },
+  {
+    "id": 201,
+    "title": "推广链接",
+    "icon": "layui-icon layui-icon-unlink",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/sponsored_links/sponsored_links.html"
+  },
+  {
+    "id": 301,
+    "title": "代理列表",
+    "icon": "layui-icon layui-icon-user",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/agent/agent_list.html"
+  },
+  {
+    "id": "agent-dashboard",
+    "title": "提现管理",
+    "type": 0,
+    "icon": "layui-icon layui-icon-circle-dot",
+    "href": "",
+    "children": [
+      {
+        "id": 401,
+        "title": "立即提现",
+        "icon": "",
+        "type": 1,
+        "openType": "_iframe",
+        "href": "view/withdrawal/withdrawal_list.html"
+      },
+      {
+        "id": 402,
+        "title": "提现方式",
+        "icon": "",
+        "type": 1,
+        "openType": "_iframe",
+        "href": "view/withdraw/withdraw_list.html"
+      }
+    ]
+  },
+  {
+    "id": 501,
+    "title": "统计",
+    "icon": "layui-icon layui-icon-date",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "view/total/total.html"
+  },
+  {
+    "id": 601,
+    "title": "个人设置",
+    "icon": "layui-icon layui-icon-face-smile",
+    "type": 1,
+    "openType": "_iframe",
+    "href": "/view/me/me_edit.html"
+  }
+]

+ 88 - 0
admin/data/message.json

@@ -0,0 +1,88 @@
+[{
+		"id": 1,
+		"title": "私信",
+		"children": [{
+			"id": 11,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条私人消息",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}, {
+			"id": 12,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条私人消息",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}]
+	},
+	{
+		"id": 2,
+		"title": "消息",
+		"children": [{
+			"id": 11,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条紧急任务",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}, {
+			"id": 12,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条紧急任务",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		},
+		{
+			"id": 11,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条紧急任务",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}, {
+			"id": 12,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条紧急任务",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		},
+		{
+			"id": 11,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条紧急任务",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}, {
+			"id": 12,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条紧急任务",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}]
+	},
+	{
+		"id": 3,
+		"title": "通知",
+		"children": [{
+			"id": 11,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条警告通知",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}, {
+			"id": 12,
+			"avatar":"admin/images/avatar.jpg",
+			"title": "收到一条警告通知",
+			"context": "这是消息内容。",
+			"form": "就眠仪式",
+			"time": "2019-02-15"
+		}]
+	}
+]

+ 508 - 0
admin/images/403.svg

@@ -0,0 +1,508 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="227px" height="269px" viewBox="0 0 227 269" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 9</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M0,131.5 C1.52216317e-15,101.788282 2.0023434,70.3064817 6.0070302,37.054599 L6.00703147,37.0545992 C8.23177711,18.5819983 23.2321456,4.27478563 41.7892683,2.9258328 C68.6224469,0.975277594 91.0407969,-6.24317082e-09 109.044318,0 C127.133265,6.27279111e-09 149.842798,0.984554771 177.17292,2.9536643 L177.17292,2.95366535 C195.745345,4.29179116 210.761581,18.6099912 212.981582,37.0977487 C216.993859,70.5112465 218.999998,102.082949 219,131.812857 C219.000002,161.472158 217.003381,192.843579 213.010137,225.927119 L213.010136,225.927119 C210.780269,244.401296 195.772997,258.705423 177.213148,260.046888 C149.974602,262.015629 127.477504,263 109.721856,263 C91.927568,263 69.2911098,262.01134 41.8124813,260.034021 L41.8124814,260.03402 C23.2430488,258.697792 8.22697111,244.385384 6.00173205,225.9014 C2.00057735,192.665746 1.52149174e-15,161.198612 0,131.5 Z" id="path-1"></path>
+        <filter x="-4.5%" y="-1.4%" width="106.2%" height="104.4%" filterUnits="objectBoundingBox" id="filter-2">
+            <feMorphology radius="0.81" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
+            <feOffset dx="-6" dy="4" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <path d="M39.654321,130.992298 C39.654321,110.09311 40.5351746,89.1940983 42.2968819,68.2952631 L42.2968835,68.2952632 C43.2666685,56.7908671 52.197293,47.5570778 63.6629191,46.2039222 C78.8424188,44.4124609 94.0195118,43.5167302 109.194198,43.5167302 C124.360772,43.5167302 139.527341,44.4115034 154.693904,46.2010498 L154.693904,46.2010495 C166.164025,47.5544421 175.09671,56.7944422 176.061501,68.3037662 C177.833381,89.4411461 178.719321,110.482698 178.719321,131.428422 C178.719321,152.307984 177.838969,173.187319 176.078265,194.066429 L176.078265,194.066429 C175.10807,205.571375 166.17633,214.805149 154.709997,216.157282 C139.486491,217.95247 124.287302,218.850064 109.112431,218.850064 C93.9666716,218.850064 78.8209665,217.95591 63.6753158,216.167604 L63.6753156,216.167605 C52.2067135,214.813462 43.275345,205.574785 42.309801,194.06695 C40.539481,172.967394 39.654321,151.94251 39.654321,130.992298 Z" id="path-3"></path>
+        <filter x="-6.0%" y="-2.3%" width="108.6%" height="105.9%" filterUnits="objectBoundingBox" id="filter-4">
+            <feMorphology radius="0.81" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
+            <feOffset dx="-5" dy="3" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <path d="M161.510068,89.8583333 L176.8425,89.8583333 L176.8425,107.391667 L161.510068,107.391667 L161.510068,107.391667 C157.8829,107.391667 154.9425,104.451267 154.9425,100.824099 L154.9425,96.4259009 L154.9425,96.4259009 C154.9425,92.7987335 157.8829,89.8583333 161.510068,89.8583333 Z" id="path-5"></path>
+        <filter x="-13.7%" y="-5.7%" width="118.3%" height="117.1%" filterUnits="objectBoundingBox" id="filter-6">
+            <feOffset dx="-2" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <path d="M183.957568,89.8583333 L199.29,89.8583333 L199.29,107.391667 L183.957568,107.391667 L183.957568,107.391667 C180.3304,107.391667 177.39,104.451267 177.39,100.824099 L177.39,96.4259009 L177.39,96.4259009 C177.39,92.7987335 180.3304,89.8583333 183.957568,89.8583333 Z" id="path-7"></path>
+        <filter x="-2.3%" y="-2.9%" width="109.1%" height="111.4%" filterUnits="objectBoundingBox" id="filter-8">
+            <feOffset dx="1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-55.5%" y="-9.3%" width="177.5%" height="148.0%" filterUnits="objectBoundingBox" id="filter-9">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-55.5%" y="-9.3%" width="177.5%" height="148.0%" filterUnits="objectBoundingBox" id="filter-10">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <path d="M8.86493515,17.2480344 C8.4007802,16.9327578 8.09567896,16.3993146 8.09567896,15.7943295 C8.09567896,14.82567 8.87784133,14.0404164 9.84268751,14.0404164 C10.8075337,14.0404164 11.5896961,14.82567 11.5896961,15.7943295 C11.5896961,16.3993146 11.2845948,16.9327578 10.8204399,17.2480344 L11.7961308,19.984547 C11.9101195,20.3042502 11.743355,20.6558271 11.4236517,20.7698158 C11.3574028,20.7934365 11.2875908,20.8055099 11.2172568,20.8055099 L8.46811816,20.8055099 L8.46811816,20.8055099 C8.1287016,20.8055099 7.85355011,20.5303584 7.85355011,20.1909418 C7.85355011,20.1206079 7.86562345,20.0507959 7.8892442,19.984547 L8.86493515,17.2480344 Z" id="path-11"></path>
+        <filter x="-12.0%" y="-7.4%" width="124.1%" height="114.8%" filterUnits="objectBoundingBox" id="filter-12">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
+            <feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-13">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-14">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-15">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-16">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-17">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-18">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-19">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-20">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-21">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-22">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-23">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-24">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-25">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-26">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-27">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-28">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-44.4%" y="-20.0%" width="166.7%" height="160.0%" filterUnits="objectBoundingBox" id="filter-29">
+            <feOffset dx="-2" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <rect id="path-30" x="79.0833333" y="68.7939815" width="60.8333333" height="24.3518519"></rect>
+        <filter x="-2.5%" y="-2.1%" width="103.3%" height="108.2%" filterUnits="objectBoundingBox" id="filter-31">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <rect id="path-32" x="119.233333" y="71.2346165" width="18.2504951" height="19.5072939"></rect>
+        <path d="M6.69173423,0.214583333 L15.4541667,0.214583333 L15.4541667,30.8979167 L6.69173423,30.8979167 L6.69173423,30.8979167 C3.06456682,30.8979167 0.124166667,27.9575165 0.124166667,24.3303491 L0.124166667,6.7821509 L0.124166667,6.7821509 C0.124166667,3.15498349 3.06456682,0.214583333 6.69173423,0.214583333 Z" id="path-34"></path>
+        <filter x="-29.4%" y="-4.9%" width="139.1%" height="116.3%" filterUnits="objectBoundingBox" id="filter-35">
+            <feOffset dx="-3" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.866666667   0 0 0 0 0.890196078   0 0 0 0 0.909803922  0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-36">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-37">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <path d="M42.8291667,11.875589 L42.8291667,19.236911 C42.8291667,19.9264853 42.3373793,20.5354959 41.738915,20.595957 L17.6441667,22.6791667 L17.6441667,8.43333333 L41.738915,10.516543 C42.3410444,10.5773757 42.8291667,11.185286 42.8291667,11.875589 Z" id="path-38"></path>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-39">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-40">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <rect id="path-41" x="12.23" y="6.78958333" width="7.1175" height="17.5333333" rx="1.09459459"></rect>
+        <filter x="-42.1%" y="-5.7%" width="156.2%" height="117.1%" filterUnits="objectBoundingBox" id="filter-42">
+            <feOffset dx="-2" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <path d="M6.69173423,0.214583333 L15.4541667,0.214583333 L15.4541667,30.8979167 L6.69173423,30.8979167 L6.69173423,30.8979167 C3.06456682,30.8979167 0.124166667,27.9575165 0.124166667,24.3303491 L0.124166667,6.7821509 L0.124166667,6.7821509 C0.124166667,3.15498349 3.06456682,0.214583333 6.69173423,0.214583333 Z" id="path-43"></path>
+        <filter x="-29.4%" y="-4.9%" width="139.1%" height="116.3%" filterUnits="objectBoundingBox" id="filter-44">
+            <feOffset dx="-3" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.866666667   0 0 0 0 0.890196078   0 0 0 0 0.909803922  0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-45">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-46">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <path d="M42.8291667,11.875589 L42.8291667,19.236911 C42.8291667,19.9264853 42.3373793,20.5354959 41.738915,20.595957 L17.6441667,22.6791667 L17.6441667,8.43333333 L41.738915,10.516543 C42.3410444,10.5773757 42.8291667,11.185286 42.8291667,11.875589 Z" id="path-47"></path>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-48">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <filter x="-50.0%" y="-10.0%" width="160.0%" height="160.0%" filterUnits="objectBoundingBox" id="filter-49">
+            <feOffset dx="-1" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <rect id="path-50" x="12.23" y="6.78958333" width="7.1175" height="17.5333333" rx="1.09459459"></rect>
+        <filter x="-42.1%" y="-5.7%" width="156.2%" height="117.1%" filterUnits="objectBoundingBox" id="filter-51">
+            <feOffset dx="-2" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <path d="M24.5975819,18.9156325 C22.7107005,18.6906938 20.1873316,18.3702571 18.5998357,18.0903387 C15.7716385,17.5916513 10.2254435,16.2267099 10.2254435,16.2267099 L9.43228672,20.7249253 C9.43228672,20.7249253 15.1331234,21.2766981 17.950402,21.7734603 C19.3152185,22.0141143 21.3273422,22.4758916 23.0359088,22.887195 C22.0718328,24.3735021 20.9147108,26.1229174 20.0932954,27.2534987 C18.405278,29.5768553 14.7471849,33.9633914 14.7471849,33.9633914 L18.4424572,36.6481639 C18.4424572,36.6481639 21.4374695,31.7661671 23.1189701,29.4517801 C23.9598468,28.2944125 25.3148663,26.6203912 26.4570264,25.2388063 C27.4382453,26.7462318 28.6051214,28.5736505 29.3214044,29.8142891 C30.7573178,32.301364 33.2767374,37.4273633 33.2767374,37.4273633 L37.2324017,35.1435594 C37.2324017,35.1435594 33.990657,30.4217925 32.5602872,27.9443193 C31.8079686,26.6412654 30.764866,24.5861738 29.94691,22.9346427 C31.7349883,22.451283 33.9931664,21.8608332 35.4733174,21.5462174 C38.2823878,20.9491311 43.9360463,20.1370415 43.9360463,20.1370415 L42.9863873,15.669247 C42.9863873,15.669247 37.4939659,17.2932232 34.6957402,17.8880045 C33.1431973,18.2180076 30.6947576,18.5971515 28.8277097,18.8686298 C28.722602,16.9801623 28.6032977,14.4864013 28.6032977,12.8962937 C28.6032977,10.024467 28.984416,4.32551158 28.984416,4.32551158 L24.4168083,4.32551158 C24.4168083,4.32551158 24.8633581,10.0355541 24.8633581,12.8962937 C24.8633581,14.5048733 24.7214143,17.0240015 24.5975819,18.9156325 Z" id="path-52"></path>
+        <filter x="-14.6%" y="-6.2%" width="120.9%" height="121.4%" filterUnits="objectBoundingBox" id="filter-54">
+            <feMorphology radius="0.547297297" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
+            <feOffset dx="-3" dy="3" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
+            <feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"></feComposite>
+            <feColorMatrix values="0 0 0 0 0.639215686   0 0 0 0 0.694117647   0 0 0 0 0.749019608  0 0 0 0.3 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+        <ellipse id="path-55" cx="26.802716" cy="22.6705733" rx="4.38" ry="4.38333333"></ellipse>
+        <filter x="-34.2%" y="-11.4%" width="145.7%" height="134.2%" filterUnits="objectBoundingBox" id="filter-56">
+            <feOffset dx="-2" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feColorMatrix values="0 0 0 0 0.596078431   0 0 0 0 0.647058824   0 0 0 0 0.701960784  0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="403" transform="translate(-592.000000, -260.000000)">
+            <g id="Group-9" transform="translate(599.000000, 261.000000)">
+                <g id="Group-11">
+                    <g id="Rectangle-355">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
+                        <use stroke="#A3B1BF" stroke-width="1.62" fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-1"></use>
+                    </g>
+                    <g id="Rectangle-355">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
+                        <use stroke="#A3B1BF" stroke-width="1.62" fill-opacity="0.15" fill="#A3B1BF" fill-rule="evenodd" xlink:href="#path-3"></use>
+                    </g>
+                    <g id="Rectangle-357">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
+                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-5"></use>
+                        <path stroke="#A3B1BF" stroke-width="1.62" d="M176.0325,106.581667 L176.0325,90.6683333 L161.510068,90.6683333 C158.330251,90.6683333 155.7525,93.2460841 155.7525,96.4259009 L155.7525,100.824099 C155.7525,104.003916 158.330251,106.581667 161.510068,106.581667 L176.0325,106.581667 Z"></path>
+                    </g>
+                    <g id="Rectangle-357" transform="translate(188.340000, 98.625000) scale(-1, 1) translate(-188.340000, -98.625000) ">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
+                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-7"></use>
+                        <path stroke="#A3B1BF" stroke-width="1.62" d="M198.48,106.581667 L198.48,90.6683333 L183.957568,90.6683333 C180.777751,90.6683333 178.2,93.2460841 178.2,96.4259009 L178.2,100.824099 C178.2,104.003916 180.777751,106.581667 183.957568,106.581667 L198.48,106.581667 Z"></path>
+                    </g>
+                    <path d="M169.537821,109.198898 L179.520726,109.198898 L179.520726,106.316665 C179.657239,106.659699 174.968976,106.316665 172.419859,106.316665 L174.153055,100.243742 C171.605657,100.243742 169.537821,102.294522 169.537821,104.822572 L169.537821,109.198898 Z M181.404585,106.764356 L181.334952,105.82938 C178.493277,106.319657 175.877716,105.82938 172.088276,105.82938 L174.153055,98.0162037 C170.365914,98.0162037 167.291667,101.063519 167.291667,104.822572 L167.291667,106.764356 L166.869647,106.764356 L166.869647,106.764356 C165.758829,106.764356 164.858333,107.664852 164.858333,108.775669 L164.858333,108.775669 L164.858333,115.540394 C164.858333,119.983665 168.460316,123.585648 172.903588,123.585648 L176.279745,123.585648 C180.723017,123.585648 184.325,119.983665 184.325,115.540394 L184.325,108.775669 C184.325,107.664852 183.424504,106.764356 182.313686,106.764356 L181.404585,106.764356 Z" id="Shape" fill="#D4DBE2" fill-rule="nonzero"></path>
+                    <g id="Group-6" filter="url(#filter-9)" transform="translate(160.419753, 95.472603)">
+                        <ellipse id="Oval-191" stroke="#D9D9D9" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#D9D9D9" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-10)" transform="translate(189.259259, 95.472603)">
+                        <ellipse id="Oval-191" stroke="#D9D9D9" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#D9D9D9" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="lock" transform="translate(166.683333, 96.798611)">
+                        <path d="M2.43333333,9.34812925 L2.43333333,7.750693 C2.43333333,4.33901358 4.64933408,1.45058816 7.70555556,0.476293029 L7.70555556,4.05203095 C6.57838885,4.84048413 5.84,6.15673686 5.84,7.64734194 L5.84,9.34812925 L14.4830461,9.34812925 C14.4830461,8.8280509 14.4830461,8.25372782 14.4830461,7.64734194 C14.4830461,6.44285214 14.0009139,5.352206 13.2211113,4.56188949 L13.2211113,0.864048014 C15.7633754,2.09038625 17.52,4.7131478 17.52,7.750693 C17.52,8.30041562 17.52,8.83504216 17.52,9.3491485 C18.6008993,9.38327886 19.4666667,10.2702555 19.4666667,11.3594429 L19.4666667,18.3317768 C19.4666667,22.7750482 15.8646835,26.3770314 11.4214121,26.3770314 L8.04525456,26.3770314 C3.60198316,26.3770314 5.4414381e-16,22.7750482 0,18.3317768 L0,11.3594429 C-1.36035952e-16,10.248625 0.900495789,9.34812925 2.01131364,9.34812925 L2.01131364,9.34812925 L2.43333333,9.34812925 Z" id="Combined-Shape" stroke="#A3B1BF" stroke-width="1.62" fill="#F0F2F5"></path>
+                        <g id="Oval-1115">
+                            <use fill-opacity="0.3" fill="#A3B1BF" fill-rule="evenodd" xlink:href="#path-11"></use>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-12)" xlink:href="#path-11"></use>
+                        </g>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-13)" transform="translate(64.000000, 75.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-11" filter="url(#filter-14)" transform="translate(152.000000, 75.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-2" filter="url(#filter-15)" transform="translate(57.000000, 120.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-3" filter="url(#filter-16)" transform="translate(57.000000, 137.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-4" filter="url(#filter-17)" transform="translate(64.000000, 186.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-5" filter="url(#filter-18)" transform="translate(93.000000, 191.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-6" filter="url(#filter-19)" transform="translate(122.000000, 191.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-7" filter="url(#filter-20)" transform="translate(152.000000, 186.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-21)" transform="translate(160.419753, 95.472603)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F5F5F5" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-22)" transform="translate(189.259259, 95.472603)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-23)" transform="translate(25.000000, 38.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F7FAFC" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-8" filter="url(#filter-24)" transform="translate(25.000000, 218.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F7FAFC" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-9" filter="url(#filter-25)" transform="translate(106.000000, 237.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F7FAFC" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Group-6-Copy-10" filter="url(#filter-26)" transform="translate(185.000000, 219.000000)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F7FAFC" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-27)" transform="translate(14.419753, 129.698630)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F7FAFC" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-28)" transform="translate(105.444444, 20.715753)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F7FAFC" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Group-6" filter="url(#filter-29)" transform="translate(185.055000, 37.806250)">
+                        <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.64189189" fill="#F5F5F5" cx="4.38" cy="4.93125" rx="4.38" ry="4.38333333"></ellipse>
+                        <polygon id="Path-301" fill="#A3B1BF" points="4.0041131 9.13310534 7.56201455 8.23226901 2.34303487 0.44644438 0.446211571 3.63004005 0.788921826 7.80592737"></polygon>
+                    </g>
+                    <g id="Rectangle-373">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-31)" xlink:href="#path-30"></use>
+                        <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-30"></use>
+                        <rect stroke="#A3B1BF" stroke-width="2.43" x="80.2983333" y="70.0089815" width="58.4033333" height="21.9218519"></rect>
+                    </g>
+                    <mask id="mask-33" fill="white">
+                        <use xlink:href="#path-32"></use>
+                    </mask>
+                    <use id="Mask" fill-opacity="0.3" fill="#A3B1BF" xlink:href="#path-32"></use>
+                    <rect id="Rectangle-375" fill="#A3B1BF" x="114.366667" y="77.3171296" width="1.825" height="8.11728395" rx="0.9125"></rect>
+                    <rect id="Rectangle-375" fill="#A3B1BF" x="118.016667" y="72.6496914" width="2.43333333" height="16.2345679" rx="1.21666667"></rect>
+                    <g id="Group-4" transform="translate(25.000000, 88.000000)">
+                        <g id="Rectangle-369">
+                            <use fill="black" fill-opacity="1" filter="url(#filter-35)" xlink:href="#path-34"></use>
+                            <use fill="#EAEFF3" fill-rule="evenodd" xlink:href="#path-34"></use>
+                            <path stroke="#A3B1BF" stroke-width="1.62" d="M14.6441667,30.0879167 L14.6441667,1.02458333 L6.69173423,1.02458333 C3.51191747,1.02458333 0.934166667,3.60233414 0.934166667,6.7821509 L0.934166667,24.3303491 C0.934166667,27.5101659 3.51191747,30.0879167 6.69173423,30.0879167 L14.6441667,30.0879167 Z"></path>
+                        </g>
+                        <g id="Group-6" filter="url(#filter-36)" transform="translate(6.207500, 6.789583)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Group-6" filter="url(#filter-37)" transform="translate(6.543210, 19.181507)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Rectangle-371">
+                            <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-38"></use>
+                            <path stroke="#A3B1BF" stroke-width="1.62" d="M18.4541667,9.31638699 L18.4541667,21.7961161 L41.6574976,19.7900592 C41.8219325,19.7734468 42.0191667,19.5280875 42.0191667,19.236911 L42.0191667,11.875589 C42.0191667,11.5822335 41.824213,11.3392839 41.6691435,11.3235325 L18.4541667,9.31638699 Z"></path>
+                        </g>
+                        <g id="Group-6" filter="url(#filter-39)" transform="translate(23.000000, 13.000000)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Group-6-Copy" filter="url(#filter-40)" transform="translate(33.000000, 13.000000)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Rectangle-370">
+                            <use fill="black" fill-opacity="1" filter="url(#filter-42)" xlink:href="#path-41"></use>
+                            <use fill="#EAEFF3" fill-rule="evenodd" xlink:href="#path-41"></use>
+                            <rect stroke="#A3B1BF" stroke-width="1.62" x="13.04" y="7.59958333" width="5.4975" height="15.9133333" rx="1.09459459"></rect>
+                        </g>
+                        <path d="M13.59875,15.55625 L17.97875,15.55625" id="Line" stroke="#A3B1BF" stroke-width="2.18918919" stroke-linecap="square"></path>
+                    </g>
+                    <g id="Group-4-Copy" transform="translate(25.000000, 145.000000)">
+                        <g id="Rectangle-369">
+                            <use fill="black" fill-opacity="1" filter="url(#filter-44)" xlink:href="#path-43"></use>
+                            <use fill="#EAEFF3" fill-rule="evenodd" xlink:href="#path-43"></use>
+                            <path stroke="#A3B1BF" stroke-width="1.62" d="M14.6441667,30.0879167 L14.6441667,1.02458333 L6.69173423,1.02458333 C3.51191747,1.02458333 0.934166667,3.60233414 0.934166667,6.7821509 L0.934166667,24.3303491 C0.934166667,27.5101659 3.51191747,30.0879167 6.69173423,30.0879167 L14.6441667,30.0879167 Z"></path>
+                        </g>
+                        <g id="Group-6" filter="url(#filter-45)" transform="translate(6.207500, 6.789583)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Group-6" filter="url(#filter-46)" transform="translate(6.543210, 19.181507)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Rectangle-371">
+                            <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-47"></use>
+                            <path stroke="#A3B1BF" stroke-width="1.62" d="M18.4541667,9.31638699 L18.4541667,21.7961161 L41.6574976,19.7900592 C41.8219325,19.7734468 42.0191667,19.5280875 42.0191667,19.236911 L42.0191667,11.875589 C42.0191667,11.5822335 41.824213,11.3392839 41.6691435,11.3235325 L18.4541667,9.31638699 Z"></path>
+                        </g>
+                        <g id="Group-6" filter="url(#filter-48)" transform="translate(23.000000, 13.000000)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Group-6-Copy" filter="url(#filter-49)" transform="translate(33.000000, 13.000000)">
+                            <ellipse id="Oval-191" stroke="#A3B1BF" stroke-width="1.09459459" fill="#F7FAFC" cx="2.19" cy="2.73958333" rx="2.19" ry="2.19166667"></ellipse>
+                            <polygon id="Path-301" fill="#A3B1BF" points="3.78100727 4.39009284 1.17151744 0.497180523 0.223105786 2.08897836 0.101076918 4.39009284"></polygon>
+                        </g>
+                        <g id="Rectangle-370">
+                            <use fill="black" fill-opacity="1" filter="url(#filter-51)" xlink:href="#path-50"></use>
+                            <use fill="#EAEFF3" fill-rule="evenodd" xlink:href="#path-50"></use>
+                            <rect stroke="#A3B1BF" stroke-width="1.62" x="13.04" y="7.59958333" width="5.4975" height="15.9133333" rx="1.09459459"></rect>
+                        </g>
+                        <path d="M13.59875,15.55625 L17.97875,15.55625" id="Line" stroke="#A3B1BF" stroke-width="2.18918919" stroke-linecap="square"></path>
+                    </g>
+                </g>
+                <g id="Group-17" transform="translate(135.185185, 131.500000)">
+                    <path d="M22.4835494,46.23099 C10.0861375,46.23099 0.0360493827,36.1732534 0.0360493827,23.7664066 C0.0360493827,11.3595599 10.0861375,1.30182331 22.4835494,1.30182331 C34.8809613,1.30182331 44.9310494,11.3595599 44.9310494,23.7664066 C44.9310494,36.1732534 34.8809613,46.23099 22.4835494,46.23099 Z M22.4835494,39.65599 C31.2524505,39.65599 38.3610494,32.5419812 38.3610494,23.7664066 C38.3610494,14.9908321 31.2524505,7.87682331 22.4835494,7.87682331 C13.7146483,7.87682331 6.60604938,14.9908321 6.60604938,23.7664066 C6.60604938,32.5419812 13.7146483,39.65599 22.4835494,39.65599 Z" id="Oval-190" fill-opacity="0.3" fill="#A3B1BF"></path>
+                    <mask id="mask-53" fill="white">
+                        <use xlink:href="#path-52"></use>
+                    </mask>
+                    <g id="Mask">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-54)" xlink:href="#path-52"></use>
+                        <use stroke="#A3B1BF" stroke-width="1.09459459" fill="#A3B1BF" fill-rule="evenodd" xlink:href="#path-52"></use>
+                    </g>
+                    <g id="Group-7" transform="translate(0.360494, 0.078598)" fill="#98A5B3">
+                        <path d="M20.5636489,0.927088888 C22.1113303,0.589405992 23.7186545,0.411496914 25.3675,0.411496914 C37.7649119,0.411496914 47.815,10.4692335 47.815,22.8760802 C47.815,33.7386653 40.1110508,42.8005273 29.8728116,44.8880725 L27.4696515,38.6276265 C35.2448963,37.5983622 41.245,30.9384541 41.245,22.8760802 C41.245,14.1005057 34.1364011,6.98649691 25.3675,6.98649691 C22.0362626,6.98649691 18.9446369,8.01317718 16.3913275,9.76760576 L15.30877,6.94744709 L20.5636489,0.927088888 Z" id="Oval-190"></path>
+                    </g>
+                    <path d="M26.802716,45.1351566 C14.4053041,45.1351566 4.35521605,35.0774201 4.35521605,22.6705733 C4.35521605,10.2637265 14.4053041,0.20598998 26.802716,0.20598998 C39.200128,0.20598998 49.250216,10.2637265 49.250216,22.6705733 C49.250216,35.0774201 39.200128,45.1351566 26.802716,45.1351566 Z M26.802716,38.5601566 C35.5716172,38.5601566 42.680216,31.4461479 42.680216,22.6705733 C42.680216,13.8949988 35.5716172,6.78098998 26.802716,6.78098998 C18.0338149,6.78098998 10.925216,13.8949988 10.925216,22.6705733 C10.925216,31.4461479 18.0338149,38.5601566 26.802716,38.5601566 Z" id="Oval-190" fill="#A3B1BF"></path>
+                    <path d="M37.5685802,6.47400902 C37.5685802,6.47400902 40.3560433,8.0639828 43.0005786,12.4958138 C45.6451139,16.9276447 45.9870813,21.4863845 45.9870813,21.4863845" id="Line" stroke="#F7FAFC" stroke-width="1.62" stroke-linecap="round"></path>
+                    <g id="Oval-199">
+                        <use fill="black" fill-opacity="1" filter="url(#filter-56)" xlink:href="#path-55"></use>
+                        <use fill="#A3B1BF" fill-rule="evenodd" xlink:href="#path-55"></use>
+                    </g>
+                    <path d="M27.0403924,24.1861178 C28.3842853,24.1861178 29.4737257,23.0958483 29.4737257,21.7509326 C29.4737257,20.406017 28.3842853,19.3157475 27.0403924,19.3157475 C27.0403924,19.3157475 27.6699621,20.406017 27.6699621,21.7509326 C27.6699621,23.0958483 27.0403924,24.1861178 27.0403924,24.1861178 Z" id="Oval-199" fill="#F7FAFC" transform="translate(28.257059, 21.750933) rotate(-43.000000) translate(-28.257059, -21.750933) "></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 314 - 0
admin/images/404.svg

@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="423px" height="341px" viewBox="0 0 423 341" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
+    <title>Group 4</title>
+    <desc>Created with Sketch.</desc>
+    <defs></defs>
+    <g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="404" transform="translate(-484.000000, -221.000000)">
+            <g id="Group-4" transform="translate(464.000000, 222.000000)">
+                <g id="Group-5" transform="translate(75.417348, 0.163879)" stroke="#A3B1BF" stroke-width="1.62" opacity="0.6" stroke-linejoin="round" stroke-dasharray="12.15">
+                    <path d="M169.575185,288.890375 C103.647066,288.890375 50.2010204,235.455806 50.2010204,169.540425 C50.2010204,103.625045 103.647066,50.1904762 169.575185,50.1904762 C235.50394,50.1904762 288.94935,103.625045 288.94935,169.540425 C288.94935,235.455806 235.50394,288.890375 169.575185,288.890375 Z" id="Stroke-1"></path>
+                    <path d="M169.405699,338.555288 C76.0274364,338.555288 0.329411882,262.872619 0.329411882,169.513299 C0.329411882,76.1539786 76.0274364,0.471309613 169.405699,0.471309613 C262.783961,0.471309613 338.481985,76.1539786 338.481985,169.513299 C338.481985,262.872619 262.783961,338.555288 169.405699,338.555288 Z" id="Stroke-3"></path>
+                </g>
+                <polygon id="Fill-6" fill="#F5F5F5" transform="translate(106.914750, 199.432805) rotate(22.000000) translate(-106.914750, -199.432805) " points="97.7112298 198.803016 116.11827 190.231152 107.544667 208.634458"></polygon>
+                <polygon id="Stroke-7" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(106.914750, 199.432805) rotate(22.000000) translate(-106.914750, -199.432805) " points="97.7112298 198.803016 116.11827 190.231152 107.544667 208.634458"></polygon>
+                <polygon id="Fill-8" transform="translate(58.996118, 219.767028) rotate(22.000000) translate(-58.996118, -219.767028) " points="38.8543444 215.183828 54.4119879 199.629341 79.1378915 224.350228 63.580248 239.904716"></polygon>
+                <polygon id="Stroke-9" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(58.996118, 219.767028) rotate(22.000000) translate(-58.996118, -219.767028) " points="38.8543444 215.183828 54.4119879 199.629341 79.1378915 224.350228 63.580248 239.904716"></polygon>
+                <polygon id="Fill-10" fill="#F5F5F5" transform="translate(71.226096, 214.577614) rotate(22.000000) translate(-71.226096, -214.577614) " points="51.4642422 198.657893 55.3028278 194.820086 90.9879502 230.497335 87.1487294 234.335141"></polygon>
+                <polygon id="Stroke-11" stroke="#A3B1BF" stroke-width="1.62" fill="#F0F2F5" stroke-linejoin="round" transform="translate(71.226096, 214.577614) rotate(22.000000) translate(-71.226096, -214.577614) " points="51.4642422 198.657893 55.3028278 194.820086 90.9879502 230.497335 87.1487294 234.335141"></polygon>
+                <polygon id="Fill-12" transform="translate(84.698338, 273.903349) rotate(22.000000) translate(-84.698338, -273.903349) " points="56.0769883 259.690379 70.4821667 245.288122 113.319688 288.116319 98.9145099 302.518575"></polygon>
+                <polygon id="Stroke-13" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(84.698338, 273.903349) rotate(22.000000) translate(-84.698338, -273.903349) " points="56.0769883 259.690379 70.4821667 245.288122 113.319688 288.116319 98.9145099 302.518575"></polygon>
+                <polygon id="Fill-14" transform="translate(75.456149, 212.782520) rotate(22.000000) translate(-75.456149, -212.782520) " points="63.8911557 203.879723 66.5512281 201.22019 87.0211429 221.685318 84.3604352 224.34485"></polygon>
+                <polygon id="Stroke-15" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(75.456149, 212.782520) rotate(22.000000) translate(-75.456149, -212.782520) " points="63.8911557 203.879723 66.5512281 201.22019 87.0211429 221.685318 84.3604352 224.34485"></polygon>
+                <polygon id="Fill-16" fill="#F5F5F5" transform="translate(78.176142, 202.618192) rotate(22.000000) translate(-78.176142, -202.618192) " points="74.4026766 205.006817 80.5652518 198.845492 81.9496076 200.229567 75.7870324 206.390892"></polygon>
+                <polygon id="Stroke-17" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(78.176142, 202.618192) rotate(22.000000) translate(-78.176142, -202.618192) " points="74.4026766 205.006817 80.5652518 198.845492 81.9496076 200.229567 75.7870324 206.390892"></polygon>
+                <polygon id="Fill-18" fill="#F5F5F5" transform="translate(84.676979, 217.928886) rotate(22.000000) translate(-84.676979, -217.928886) " points="80.9035138 220.317511 87.066089 214.156186 88.4504448 215.540261 82.2878696 221.701586"></polygon>
+                <polygon id="Stroke-19" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(84.676979, 217.928886) rotate(22.000000) translate(-84.676979, -217.928886) " points="80.9035138 220.317511 87.066089 214.156186 88.4504448 215.540261 82.2878696 221.701586"></polygon>
+                <polygon id="Fill-20" transform="translate(70.238421, 242.404581) rotate(22.000000) translate(-70.238421, -242.404581) " points="67.8493111 238.631881 74.0118863 244.793206 72.6275305 246.177281 66.4649553 240.015956"></polygon>
+                <polygon id="Stroke-21" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(70.238421, 242.404581) rotate(22.000000) translate(-70.238421, -242.404581) " points="67.8493111 238.631881 74.0118863 244.793206 72.6275305 246.177281 66.4649553 240.015956"></polygon>
+                <polygon id="Fill-22" transform="translate(48.081755, 224.398789) rotate(22.000000) translate(-48.081755, -224.398789) " points="35.1127107 220.725179 36.3242602 211.432376 61.0507992 236.153899 51.756111 237.365203"></polygon>
+                <polygon id="Stroke-23" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(48.081755, 224.398789) rotate(22.000000) translate(-48.081755, -224.398789) " points="35.1127107 220.725179 36.3242602 211.432376 61.0507992 236.153899 51.756111 237.365203"></polygon>
+                <polygon id="Fill-24" transform="translate(38.612968, 228.416820) rotate(22.000000) translate(-38.612968, -228.416820) " points="32.9179858 217.470622 26.2496982 216.056058 50.9762371 240.777581 49.5613861 234.110647"></polygon>
+                <polygon id="Stroke-25" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(38.612968, 228.416820) rotate(22.000000) translate(-38.612968, -228.416820) " points="32.9179858 217.470622 26.2496982 216.056058 50.9762371 240.777581 49.5613861 234.110647"></polygon>
+                <polygon id="Fill-26" transform="translate(31.086342, 221.523909) rotate(22.000000) translate(-31.086342, -221.523909) " points="32.6469986 217.297684 26.8592604 218.37941 34.2314793 225.750133 35.3134242 219.963569"></polygon>
+                <polygon id="Stroke-27" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(31.086342, 221.523909) rotate(22.000000) translate(-31.086342, -221.523909) " points="32.6469986 217.297684 26.8592604 218.37941 34.2314793 225.750133 35.3134242 219.963569"></polygon>
+                <polygon id="Fill-28" transform="translate(38.344372, 238.617819) rotate(22.000000) translate(-38.344372, -238.617819) " points="39.9050284 234.391595 34.1172902 235.47332 41.4895091 242.844044 42.571454 237.05748"></polygon>
+                <polygon id="Stroke-29" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(38.344372, 238.617819) rotate(22.000000) translate(-38.344372, -238.617819) " points="39.9050284 234.391595 34.1172902 235.47332 41.4895091 242.844044 42.571454 237.05748"></polygon>
+                <polygon id="Fill-30" fill="#F0F2F5" transform="translate(75.352798, 203.766862) rotate(22.000000) translate(-75.352798, -203.766862) " points="71.4417859 201.708217 73.2937351 199.856644 79.2638092 205.824871 77.4118601 207.67708"></polygon>
+                <polygon id="Stroke-31" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(75.352798, 203.766862) rotate(22.000000) translate(-75.352798, -203.766862) " points="71.4417859 201.708217 73.2937351 199.856644 79.2638092 205.824871 77.4118601 207.67708"></polygon>
+                <polygon id="Fill-32" fill="#F0F2F5" transform="translate(81.871541, 219.119730) rotate(22.000000) translate(-81.871541, -219.119730) " points="77.9605297 217.061085 79.8124789 215.209512 85.7825531 221.177739 83.9306039 223.029948"></polygon>
+                <polygon id="Stroke-33" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(81.871541, 219.119730) rotate(22.000000) translate(-81.871541, -219.119730) " points="77.9605297 217.061085 79.8124789 215.209512 85.7825531 221.177739 83.9306039 223.029948"></polygon>
+                <polygon id="Fill-34" transform="translate(68.034935, 237.215417) rotate(22.000000) translate(-68.034935, -237.215417) " points="65.1594898 237.106164 67.9256601 234.340555 70.9103796 237.324669 68.1442092 240.090278"></polygon>
+                <polygon id="Stroke-35" stroke="#A3B1BF" stroke-width="1.62" fill="#F5F5F5" stroke-linejoin="round" transform="translate(68.034935, 237.215417) rotate(22.000000) translate(-68.034935, -237.215417) " points="65.1594898 237.106164 67.9256601 234.340555 70.9103796 237.324669 68.1442092 240.090278"></polygon>
+                <path d="M90.2556147,213.065319 C79.2271463,202.039088 74.6433339,188.153875 78.4889079,179.512775 C79.1248602,178.084237 80.8319571,175.429786 84.5339495,179.131027 C88.2353065,182.832268 120.560237,215.150007 123.931865,218.52095 C127.303492,221.891894 125.245065,224.192545 123.817508,224.827733 C115.174655,228.675068 101.284718,224.092186 90.2556147,213.065319 Z" id="Fill-36" fill="#F5F5F5" transform="translate(101.453924, 201.708917) rotate(22.000000) translate(-101.453924, -201.708917) "></path>
+                <path d="M90.2556147,213.065319 C79.2271463,202.039088 74.6433339,188.153875 78.4889079,179.512775 C79.1248602,178.084237 80.8319571,175.429786 84.5339495,179.131027 C88.2353065,182.832268 120.560237,215.150007 123.931865,218.52095 C127.303492,221.891894 125.245065,224.192545 123.817508,224.827733 C115.174655,228.675068 101.284718,224.092186 90.2556147,213.065319 Z" id="Stroke-38" stroke="#A3B1BF" stroke-width="1.62" fill="#F0F2F5" stroke-linejoin="round" transform="translate(101.453924, 201.708917) rotate(22.000000) translate(-101.453924, -201.708917) "></path>
+                <polygon id="Fill-40" fill="#F0F2F5" transform="translate(86.633853, 208.038961) rotate(22.000000) translate(-86.633853, -208.038961) " points="77.9716233 201.230061 79.8235724 199.378488 95.2960835 214.84786 93.4441343 216.699433"></polygon>
+                <polygon id="Stroke-42" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(86.633853, 208.038961) rotate(22.000000) translate(-86.633853, -208.038961) " points="77.9716233 201.230061 79.8235724 199.378488 95.2960835 214.84786 93.4441343 216.699433"></polygon>
+                <path d="M121.635514,196.068815 C120.517356,197.186746 118.704797,197.186746 117.586639,196.068815 C116.469116,194.950884 116.469116,193.138692 117.586639,192.020761 C118.704797,190.903465 120.517356,190.903465 121.635514,192.020761 C122.753672,193.138692 122.753672,194.950884 121.635514,196.068815" id="Fill-44" fill="#A3B1BF" transform="translate(119.611315, 194.045026) rotate(22.000000) translate(-119.611315, -194.045026) "></path>
+                <polygon id="Fill-46" fill-opacity="0.6" fill="#A3B1BF" transform="translate(81.250567, 248.056422) rotate(22.000000) translate(-81.250567, -248.056422) " points="81.2505672 249.672341 79.6343206 248.056422 81.2505672 246.440503 82.8668137 248.056422"></polygon>
+                <polygon id="Stroke-48" transform="translate(81.250567, 248.056422) rotate(22.000000) translate(-81.250567, -248.056422) " points="81.2505672 249.672341 79.6343206 248.056422 81.2505672 246.440503 82.8668137 248.056422"></polygon>
+                <polygon id="Fill-50" fill-opacity="0.6" fill="#A3B1BF" transform="translate(82.702196, 251.475282) rotate(22.000000) translate(-82.702196, -251.475282) " points="82.7021965 253.091201 81.0859499 251.475282 82.7021965 249.859363 84.318443 251.475282"></polygon>
+                <polygon id="Stroke-52" transform="translate(82.702196, 251.475282) rotate(22.000000) translate(-82.702196, -251.475282) " points="82.7021965 253.091201 81.0859499 251.475282 82.7021965 249.859363 84.318443 251.475282"></polygon>
+                <polygon id="Fill-54" fill-opacity="0.6" fill="#A3B1BF" transform="translate(84.153791, 254.894059) rotate(22.000000) translate(-84.153791, -254.894059) " points="84.1537906 256.509978 82.5375441 254.894059 84.1537906 253.278141 85.7700372 254.894059"></polygon>
+                <polygon id="Stroke-56" transform="translate(84.153791, 254.894059) rotate(22.000000) translate(-84.153791, -254.894059) " points="84.1537906 256.509978 82.5375441 254.894059 84.1537906 253.278141 85.7700372 254.894059"></polygon>
+                <polygon id="Fill-58" fill-opacity="0.6" fill="#A3B1BF" transform="translate(85.605385, 258.312837) rotate(22.000000) translate(-85.605385, -258.312837) " points="85.6053848 259.928756 83.9891383 258.312837 85.6053848 256.696918 87.2216313 258.312837"></polygon>
+                <polygon id="Stroke-60" transform="translate(85.605385, 258.312837) rotate(22.000000) translate(-85.605385, -258.312837) " points="85.6053848 259.928756 83.9891383 258.312837 85.6053848 256.696918 87.2216313 258.312837"></polygon>
+                <polygon id="Fill-62" fill-opacity="0.6" fill="#A3B1BF" transform="translate(78.094482, 249.395723) rotate(22.000000) translate(-78.094482, -249.395723) " points="78.0944819 251.011642 76.4782353 249.395723 78.0944819 247.779804 79.7107284 249.395723"></polygon>
+                <polygon id="Stroke-64" transform="translate(78.094482, 249.395723) rotate(22.000000) translate(-78.094482, -249.395723) " points="78.0944819 251.011642 76.4782353 249.395723 78.0944819 247.779804 79.7107284 249.395723"></polygon>
+                <polygon id="Fill-66" fill-opacity="0.6" fill="#A3B1BF" transform="translate(79.546052, 252.814559) rotate(22.000000) translate(-79.546052, -252.814559) " points="79.5460522 254.430478 77.9298057 252.814559 79.5460522 251.198641 81.1622988 252.814559"></polygon>
+                <polygon id="Stroke-68" transform="translate(79.546052, 252.814559) rotate(22.000000) translate(-79.546052, -252.814559) " points="79.5460522 254.430478 77.9298057 252.814559 79.5460522 251.198641 81.1622988 252.814559"></polygon>
+                <polygon id="Fill-70" fill-opacity="0.6" fill="#A3B1BF" transform="translate(80.997705, 256.233360) rotate(22.000000) translate(-80.997705, -256.233360) " points="80.9977053 257.849279 79.3814588 256.23336 80.9977053 254.617442 82.6139518 256.23336"></polygon>
+                <polygon id="Stroke-72" transform="translate(80.997705, 256.233360) rotate(22.000000) translate(-80.997705, -256.233360) " points="79.3814588 256.23336 80.9977053 254.617442 82.6139518 256.23336 80.9977053 257.849279"></polygon>
+                <polygon id="Fill-74" fill-opacity="0.6" fill="#A3B1BF" transform="translate(82.449276, 259.652197) rotate(22.000000) translate(-82.449276, -259.652197) " points="82.4492757 261.268115 80.8330292 259.652197 82.4492757 258.036278 84.0655222 259.652197"></polygon>
+                <polygon id="Stroke-76" transform="translate(82.449276, 259.652197) rotate(22.000000) translate(-82.449276, -259.652197) " points="82.4492757 261.268115 80.8330292 259.652197 82.4492757 258.036278 84.0655222 259.652197"></polygon>
+                <polygon id="Fill-78" fill-opacity="0.6" fill="#A3B1BF" transform="translate(74.938373, 250.735083) rotate(22.000000) translate(-74.938373, -250.735083) " points="74.9383727 252.351002 73.3221262 250.735083 74.9383727 249.119164 76.5546193 250.735083"></polygon>
+                <polygon id="Stroke-80" transform="translate(74.938373, 250.735083) rotate(22.000000) translate(-74.938373, -250.735083) " points="74.9383727 252.351002 73.3221262 250.735083 74.9383727 249.119164 76.5546193 250.735083"></polygon>
+                <polygon id="Fill-82" fill-opacity="0.6" fill="#A3B1BF" transform="translate(76.389967, 254.153860) rotate(22.000000) translate(-76.389967, -254.153860) " points="76.3899669 255.769779 74.7737204 254.15386 76.3899669 252.537942 78.0062134 254.15386"></polygon>
+                <polygon id="Stroke-84" transform="translate(76.389967, 254.153860) rotate(22.000000) translate(-76.389967, -254.153860) " points="76.3899669 255.769779 74.7737204 254.15386 76.3899669 252.537942 78.0062134 254.15386"></polygon>
+                <polygon id="Fill-86" fill-opacity="0.6" fill="#A3B1BF" transform="translate(77.841620, 257.572661) rotate(22.000000) translate(-77.841620, -257.572661) " points="77.84162 259.18858 76.2253735 257.572661 77.84162 255.956743 79.4578665 257.572661"></polygon>
+                <polygon id="Stroke-88" transform="translate(77.841620, 257.572661) rotate(22.000000) translate(-77.841620, -257.572661) " points="77.84162 259.18858 76.2253735 257.572661 77.84162 255.956743 79.4578665 257.572661"></polygon>
+                <polygon id="Fill-90" fill-opacity="0.6" fill="#A3B1BF" transform="translate(79.293190, 260.991498) rotate(22.000000) translate(-79.293190, -260.991498) " points="79.2931904 262.607416 77.6769438 260.991498 79.2931904 259.375579 80.9094369 260.991498"></polygon>
+                <polygon id="Stroke-92" transform="translate(79.293190, 260.991498) rotate(22.000000) translate(-79.293190, -260.991498) " points="79.2931904 262.607416 77.6769438 260.991498 79.2931904 259.375579 80.9094369 260.991498"></polygon>
+                <polygon id="Fill-94" fill-opacity="0.6" fill="#A3B1BF" transform="translate(71.782287, 252.074384) rotate(22.000000) translate(-71.782287, -252.074384) " points="71.7822874 253.690302 70.1660409 252.074384 71.7822874 250.458465 73.3985339 252.074384"></polygon>
+                <polygon id="Stroke-96" transform="translate(71.782287, 252.074384) rotate(22.000000) translate(-71.782287, -252.074384) " points="71.7822874 253.690302 70.1660409 252.074384 71.7822874 250.458465 73.3985339 252.074384"></polygon>
+                <polygon id="Fill-98" fill-opacity="0.6" fill="#A3B1BF" transform="translate(73.233882, 255.493161) rotate(22.000000) translate(-73.233882, -255.493161) " points="73.2338816 257.10908 71.6176351 255.493161 73.2338816 253.877242 74.8501281 255.493161"></polygon>
+                <polygon id="Stroke-100" transform="translate(73.233882, 255.493161) rotate(22.000000) translate(-73.233882, -255.493161) " points="73.2338816 257.10908 71.6176351 255.493161 73.2338816 253.877242 74.8501281 255.493161"></polygon>
+                <polygon id="Fill-102" fill-opacity="0.6" fill="#A3B1BF" transform="translate(74.685535, 258.911962) rotate(22.000000) translate(-74.685535, -258.911962) " points="74.6855347 260.527881 73.0692881 258.911962 74.6855347 257.296044 76.3017812 258.911962"></polygon>
+                <polygon id="Stroke-104" transform="translate(74.685535, 258.911962) rotate(22.000000) translate(-74.685535, -258.911962) " points="74.6855347 260.527881 73.0692881 258.911962 74.6855347 257.296044 76.3017812 258.911962"></polygon>
+                <polygon id="Fill-106" fill-opacity="0.6" fill="#A3B1BF" transform="translate(76.137105, 262.330799) rotate(22.000000) translate(-76.137105, -262.330799) " points="76.137105 263.946717 74.5208585 262.330799 76.137105 260.71488 77.7533516 262.330799"></polygon>
+                <polygon id="Stroke-108" transform="translate(76.137105, 262.330799) rotate(22.000000) translate(-76.137105, -262.330799) " points="76.137105 263.946717 74.5208585 262.330799 76.137105 260.71488 77.7533516 262.330799"></polygon>
+                <polygon id="Fill-110" fill-opacity="0.6" fill="#A3B1BF" transform="translate(68.626202, 253.413685) rotate(22.000000) translate(-68.626202, -253.413685) " points="68.6262021 255.029603 67.0099556 253.413685 68.6262021 251.797766 70.2424486 253.413685"></polygon>
+                <polygon id="Stroke-112" transform="translate(68.626202, 253.413685) rotate(22.000000) translate(-68.626202, -253.413685) " points="68.6262021 255.029603 67.0099556 253.413685 68.6262021 251.797766 70.2424486 253.413685"></polygon>
+                <polygon id="Fill-114" fill-opacity="0.6" fill="#A3B1BF" transform="translate(70.077796, 256.832462) rotate(22.000000) translate(-70.077796, -256.832462) " points="70.0777963 258.448381 68.4615497 256.832462 70.0777963 255.216543 71.6940428 256.832462"></polygon>
+                <polygon id="Stroke-116" transform="translate(70.077796, 256.832462) rotate(22.000000) translate(-70.077796, -256.832462) " points="70.0777963 258.448381 68.4615497 256.832462 70.0777963 255.216543 71.6940428 256.832462"></polygon>
+                <polygon id="Fill-118" fill-opacity="0.6" fill="#A3B1BF" transform="translate(71.529426, 260.251322) rotate(22.000000) translate(-71.529426, -260.251322) " points="71.5294256 261.867241 69.913179 260.251322 71.5294256 258.635403 73.1456721 260.251322"></polygon>
+                <polygon id="Stroke-120" transform="translate(71.529426, 260.251322) rotate(22.000000) translate(-71.529426, -260.251322) " points="71.5294256 261.867241 69.913179 260.251322 71.5294256 258.635403 73.1456721 260.251322"></polygon>
+                <polygon id="Fill-122" fill-opacity="0.6" fill="#A3B1BF" transform="translate(72.981020, 263.670099) rotate(22.000000) translate(-72.981020, -263.670099) " points="72.9810197 265.286018 71.3647732 263.670099 72.9810197 262.054181 74.5972663 263.670099"></polygon>
+                <polygon id="Stroke-124" transform="translate(72.981020, 263.670099) rotate(22.000000) translate(-72.981020, -263.670099) " points="72.9810197 265.286018 71.3647732 263.670099 72.9810197 262.054181 74.5972663 263.670099"></polygon>
+                <polygon id="Fill-126" fill-opacity="0.6" fill="#A3B1BF" transform="translate(88.852907, 265.961362) rotate(22.000000) translate(-88.852907, -265.961362) " points="88.8529067 267.577281 87.2366602 265.961362 88.8529067 264.345443 90.4691533 265.961362"></polygon>
+                <polygon id="Stroke-128" transform="translate(88.852907, 265.961362) rotate(22.000000) translate(-88.852907, -265.961362) " points="88.8529067 267.577281 87.2366602 265.961362 88.8529067 264.345443 90.4691533 265.961362"></polygon>
+                <polygon id="Fill-130" fill-opacity="0.6" fill="#A3B1BF" transform="translate(90.304501, 269.380139) rotate(22.000000) translate(-90.304501, -269.380139) " points="90.3045009 270.996058 88.6882544 269.380139 90.3045009 267.764221 91.9207474 269.380139"></polygon>
+                <polygon id="Stroke-132" transform="translate(90.304501, 269.380139) rotate(22.000000) translate(-90.304501, -269.380139) " points="90.3045009 270.996058 88.6882544 269.380139 90.3045009 267.764221 91.9207474 269.380139"></polygon>
+                <polygon id="Fill-134" fill-opacity="0.6" fill="#A3B1BF" transform="translate(91.756130, 272.798999) rotate(22.000000) translate(-91.756130, -272.798999) " points="91.7561302 274.414918 90.1398837 272.798999 91.7561302 271.183081 93.3723767 272.798999"></polygon>
+                <polygon id="Stroke-136" transform="translate(91.756130, 272.798999) rotate(22.000000) translate(-91.756130, -272.798999) " points="91.7561302 274.414918 90.1398837 272.798999 91.7561302 271.183081 93.3723767 272.798999"></polygon>
+                <polygon id="Fill-138" fill-opacity="0.6" fill="#A3B1BF" transform="translate(93.207724, 276.217777) rotate(22.000000) translate(-93.207724, -276.217777) " points="93.2077244 277.833695 91.5914778 276.217777 93.2077244 274.601858 94.8239709 276.217777"></polygon>
+                <polygon id="Stroke-140" transform="translate(93.207724, 276.217777) rotate(22.000000) translate(-93.207724, -276.217777) " points="93.2077244 277.833695 91.5914778 276.217777 93.2077244 274.601858 94.8239709 276.217777"></polygon>
+                <polygon id="Fill-142" fill-opacity="0.6" fill="#A3B1BF" transform="translate(85.696821, 267.300663) rotate(22.000000) translate(-85.696821, -267.300663) " points="85.6968214 268.916582 84.0805749 267.300663 85.6968214 265.684744 87.313068 267.300663"></polygon>
+                <polygon id="Stroke-144" transform="translate(85.696821, 267.300663) rotate(22.000000) translate(-85.696821, -267.300663) " points="85.6968214 268.916582 84.0805749 267.300663 85.6968214 265.684744 87.313068 267.300663"></polygon>
+                <polygon id="Fill-146" fill-opacity="0.6" fill="#A3B1BF" transform="translate(87.148416, 270.719440) rotate(22.000000) translate(-87.148416, -270.719440) " points="87.1484156 272.335359 85.5321691 270.71944 87.1484156 269.103521 88.7646621 270.71944"></polygon>
+                <polygon id="Stroke-148" transform="translate(87.148416, 270.719440) rotate(22.000000) translate(-87.148416, -270.719440) " points="87.1484156 272.335359 85.5321691 270.71944 87.1484156 269.103521 88.7646621 270.71944"></polygon>
+                <polygon id="Fill-150" fill-opacity="0.6" fill="#A3B1BF" transform="translate(88.599986, 274.138276) rotate(22.000000) translate(-88.599986, -274.138276) " points="88.599986 275.754195 86.9837394 274.138276 88.599986 272.522358 90.2162325 274.138276"></polygon>
+                <polygon id="Stroke-152" transform="translate(88.599986, 274.138276) rotate(22.000000) translate(-88.599986, -274.138276) " points="88.599986 275.754195 86.9837394 274.138276 88.599986 272.522358 90.2162325 274.138276"></polygon>
+                <polygon id="Fill-154" fill-opacity="0.6" fill="#A3B1BF" transform="translate(90.051639, 277.557078) rotate(22.000000) translate(-90.051639, -277.557078) " points="90.0516391 279.172996 88.4353925 277.557078 90.0516391 275.941159 91.6678856 277.557078"></polygon>
+                <polygon id="Stroke-156" transform="translate(90.051639, 277.557078) rotate(22.000000) translate(-90.051639, -277.557078) " points="90.0516391 279.172996 88.4353925 277.557078 90.0516391 275.941159 91.6678856 277.557078"></polygon>
+                <polygon id="Fill-158" fill-opacity="0.6" fill="#A3B1BF" transform="translate(82.540736, 268.639964) rotate(22.000000) translate(-82.540736, -268.639964) " points="82.5407361 270.255882 80.9244896 268.639964 82.5407361 267.024045 84.1569826 268.639964"></polygon>
+                <polygon id="Stroke-160" transform="translate(82.540736, 268.639964) rotate(22.000000) translate(-82.540736, -268.639964) " points="82.5407361 270.255882 80.9244896 268.639964 82.5407361 267.024045 84.1569826 268.639964"></polygon>
+                <polygon id="Fill-162" fill-opacity="0.6" fill="#A3B1BF" transform="translate(83.992306, 272.058800) rotate(22.000000) translate(-83.992306, -272.058800) " points="83.9923065 273.674719 82.3760599 272.0588 83.9923065 270.442881 85.608553 272.0588"></polygon>
+                <polygon id="Stroke-164" transform="translate(83.992306, 272.058800) rotate(22.000000) translate(-83.992306, -272.058800) " points="83.9923065 273.674719 82.3760599 272.0588 83.9923065 270.442881 85.608553 272.0588"></polygon>
+                <polygon id="Fill-166" fill-opacity="0.6" fill="#A3B1BF" transform="translate(85.443901, 275.477577) rotate(22.000000) translate(-85.443901, -275.477577) " points="85.4439007 277.093496 83.8276541 275.477577 85.4439007 273.861659 87.0601472 275.477577"></polygon>
+                <polygon id="Stroke-168" transform="translate(85.443901, 275.477577) rotate(22.000000) translate(-85.443901, -275.477577) " points="85.4439007 277.093496 83.8276541 275.477577 85.4439007 273.861659 87.0601472 275.477577"></polygon>
+                <polygon id="Fill-170" fill-opacity="0.6" fill="#A3B1BF" transform="translate(86.895554, 278.896378) rotate(22.000000) translate(-86.895554, -278.896378) " points="86.8955537 280.512297 85.2793072 278.896378 86.8955537 277.28046 88.5118003 278.896378"></polygon>
+                <polygon id="Stroke-172" transform="translate(86.895554, 278.896378) rotate(22.000000) translate(-86.895554, -278.896378) " points="86.8955537 280.512297 85.2793072 278.896378 86.8955537 277.28046 88.5118003 278.896378"></polygon>
+                <polygon id="Fill-174" fill-opacity="0.6" fill="#A3B1BF" transform="translate(79.384651, 269.979265) rotate(22.000000) translate(-79.384651, -269.979265) " points="79.3846508 271.595183 77.7684043 269.979265 79.3846508 268.363346 81.0008973 269.979265"></polygon>
+                <polygon id="Stroke-176" transform="translate(79.384651, 269.979265) rotate(22.000000) translate(-79.384651, -269.979265) " points="79.3846508 271.595183 77.7684043 269.979265 79.3846508 268.363346 81.0008973 269.979265"></polygon>
+                <polygon id="Fill-178" fill-opacity="0.6" fill="#A3B1BF" transform="translate(80.836221, 273.398101) rotate(22.000000) translate(-80.836221, -273.398101) " points="80.8362212 275.01402 79.2199746 273.398101 80.8362212 271.782182 82.4524677 273.398101"></polygon>
+                <polygon id="Stroke-180" transform="translate(80.836221, 273.398101) rotate(22.000000) translate(-80.836221, -273.398101) " points="80.8362212 275.01402 79.2199746 273.398101 80.8362212 271.782182 82.4524677 273.398101"></polygon>
+                <polygon id="Fill-182" fill-opacity="0.6" fill="#A3B1BF" transform="translate(82.287815, 276.816878) rotate(22.000000) translate(-82.287815, -276.816878) " points="82.2878153 278.432797 80.6715688 276.816878 82.2878153 275.20096 83.9040619 276.816878"></polygon>
+                <polygon id="Stroke-184" transform="translate(82.287815, 276.816878) rotate(22.000000) translate(-82.287815, -276.816878) " points="82.2878153 278.432797 80.6715688 276.816878 82.2878153 275.20096 83.9040619 276.816878"></polygon>
+                <polygon id="Fill-186" fill-opacity="0.6" fill="#A3B1BF" transform="translate(83.739445, 280.235738) rotate(22.000000) translate(-83.739445, -280.235738) " points="83.7394446 281.851657 82.1231981 280.235738 83.7394446 278.61982 85.3556912 280.235738"></polygon>
+                <polygon id="Stroke-188" transform="translate(83.739445, 280.235738) rotate(22.000000) translate(-83.739445, -280.235738) " points="83.7394446 281.851657 82.1231981 280.235738 83.7394446 278.61982 85.3556912 280.235738"></polygon>
+                <polygon id="Fill-190" fill-opacity="0.6" fill="#A3B1BF" transform="translate(76.228483, 271.318601) rotate(22.000000) translate(-76.228483, -271.318601) " points="76.2284828 272.934519 74.6122362 271.318601 76.2284828 269.702682 77.8447293 271.318601"></polygon>
+                <polygon id="Stroke-192" transform="translate(76.228483, 271.318601) rotate(22.000000) translate(-76.228483, -271.318601) " points="76.2284828 272.934519 74.6122362 271.318601 76.2284828 269.702682 77.8447293 271.318601"></polygon>
+                <polygon id="Fill-194" fill-opacity="0.6" fill="#A3B1BF" transform="translate(77.680136, 274.737402) rotate(22.000000) translate(-77.680136, -274.737402) " points="77.6801358 276.353321 76.0638893 274.737402 77.6801358 273.121483 79.2963824 274.737402"></polygon>
+                <polygon id="Stroke-196" transform="translate(77.680136, 274.737402) rotate(22.000000) translate(-77.680136, -274.737402) " points="77.6801358 276.353321 76.0638893 274.737402 77.6801358 273.121483 79.2963824 274.737402"></polygon>
+                <polygon id="Fill-198" fill-opacity="0.6" fill="#A3B1BF" transform="translate(79.131730, 278.156179) rotate(22.000000) translate(-79.131730, -278.156179) " points="79.13173 279.772098 77.5154835 278.156179 79.13173 276.540261 80.7479765 278.156179"></polygon>
+                <polygon id="Stroke-200" transform="translate(79.131730, 278.156179) rotate(22.000000) translate(-79.131730, -278.156179) " points="79.13173 279.772098 77.5154835 278.156179 79.13173 276.540261 80.7479765 278.156179"></polygon>
+                <polygon id="Fill-202" fill-opacity="0.6" fill="#A3B1BF" transform="translate(80.583359, 281.575039) rotate(22.000000) translate(-80.583359, -281.575039) " points="80.5833593 283.190958 78.9671128 281.575039 80.5833593 279.959121 82.1996058 281.575039"></polygon>
+                <polygon id="Stroke-204" transform="translate(80.583359, 281.575039) rotate(22.000000) translate(-80.583359, -281.575039) " points="80.5833593 283.190958 78.9671128 281.575039 80.5833593 279.959121 82.1996058 281.575039"></polygon>
+                <polygon id="Fill-206" fill-opacity="0.6" fill="#A3B1BF" transform="translate(96.455246, 283.866302) rotate(22.000000) translate(-96.455246, -283.866302) " points="96.4552463 285.48222 94.8389998 283.866302 96.4552463 282.250383 98.0714929 283.866302"></polygon>
+                <polygon id="Stroke-208" transform="translate(96.455246, 283.866302) rotate(22.000000) translate(-96.455246, -283.866302) " points="96.4552463 285.48222 94.8389998 283.866302 96.4552463 282.250383 98.0714929 283.866302"></polygon>
+                <polygon id="Fill-210" fill-opacity="0.6" fill="#A3B1BF" transform="translate(97.906840, 287.285079) rotate(22.000000) translate(-97.906840, -287.285079) " points="97.9068405 288.900998 96.290594 287.285079 97.9068405 285.66916 99.523087 287.285079"></polygon>
+                <polygon id="Stroke-212" transform="translate(97.906840, 287.285079) rotate(22.000000) translate(-97.906840, -287.285079) " points="97.9068405 288.900998 96.290594 287.285079 97.9068405 285.66916 99.523087 287.285079"></polygon>
+                <polygon id="Fill-214" fill-opacity="0.6" fill="#A3B1BF" transform="translate(99.358435, 290.703856) rotate(22.000000) translate(-99.358435, -290.703856) " points="99.3584347 292.319775 97.7421881 290.703856 99.3584347 289.087938 100.974681 290.703856"></polygon>
+                <polygon id="Stroke-216" transform="translate(99.358435, 290.703856) rotate(22.000000) translate(-99.358435, -290.703856) " points="99.3584347 292.319775 97.7421881 290.703856 99.3584347 289.087938 100.974681 290.703856"></polygon>
+                <polygon id="Fill-218" fill-opacity="0.6" fill="#A3B1BF" transform="translate(100.810064, 294.122716) rotate(22.000000) translate(-100.810064, -294.122716) " points="100.810064 295.738635 99.1938174 294.122716 100.810064 292.506798 102.42631 294.122716"></polygon>
+                <polygon id="Stroke-220" transform="translate(100.810064, 294.122716) rotate(22.000000) translate(-100.810064, -294.122716) " points="100.810064 295.738635 99.1938174 294.122716 100.810064 292.506798 102.42631 294.122716"></polygon>
+                <polygon id="Fill-222" fill-opacity="0.6" fill="#A3B1BF" transform="translate(93.299102, 285.205579) rotate(22.000000) translate(-93.299102, -285.205579) " points="93.2991021 286.821497 91.6828556 285.205579 93.2991021 283.58966 94.9153486 285.205579"></polygon>
+                <polygon id="Stroke-224" transform="translate(93.299102, 285.205579) rotate(22.000000) translate(-93.299102, -285.205579) " points="93.2991021 286.821497 91.6828556 285.205579 93.2991021 283.58966 94.9153486 285.205579"></polygon>
+                <polygon id="Fill-226" fill-opacity="0.6" fill="#A3B1BF" transform="translate(94.750755, 288.624380) rotate(22.000000) translate(-94.750755, -288.624380) " points="94.7507552 290.240299 93.1345086 288.62438 94.7507552 287.008461 96.3670017 288.62438"></polygon>
+                <polygon id="Stroke-228" transform="translate(94.750755, 288.624380) rotate(22.000000) translate(-94.750755, -288.624380) " points="94.7507552 290.240299 93.1345086 288.62438 94.7507552 287.008461 96.3670017 288.62438"></polygon>
+                <polygon id="Fill-230" fill-opacity="0.6" fill="#A3B1BF" transform="translate(96.202326, 292.043216) rotate(22.000000) translate(-96.202326, -292.043216) " points="96.2023255 293.659135 94.586079 292.043216 96.2023255 290.427297 97.8185721 292.043216"></polygon>
+                <polygon id="Stroke-232" transform="translate(96.202326, 292.043216) rotate(22.000000) translate(-96.202326, -292.043216) " points="96.2023255 293.659135 94.586079 292.043216 96.2023255 290.427297 97.8185721 292.043216"></polygon>
+                <polygon id="Fill-234" fill-opacity="0.6" fill="#A3B1BF" transform="translate(97.653979, 295.462017) rotate(22.000000) translate(-97.653979, -295.462017) " points="97.6539786 297.077936 96.0377321 295.462017 97.6539786 293.846099 99.2702252 295.462017"></polygon>
+                <polygon id="Stroke-236" transform="translate(97.653979, 295.462017) rotate(22.000000) translate(-97.653979, -295.462017) " points="97.6539786 297.077936 96.0377321 295.462017 97.6539786 293.846099 99.2702252 295.462017"></polygon>
+                <polygon id="Fill-238" fill-opacity="0.6" fill="#A3B1BF" transform="translate(90.143017, 286.544880) rotate(22.000000) translate(-90.143017, -286.544880) " points="90.1430168 288.160798 88.5267702 286.54488 90.1430168 284.928961 91.7592633 286.54488"></polygon>
+                <polygon id="Stroke-240" transform="translate(90.143017, 286.544880) rotate(22.000000) translate(-90.143017, -286.544880) " points="90.1430168 288.160798 88.5267702 286.54488 90.1430168 284.928961 91.7592633 286.54488"></polygon>
+                <polygon id="Fill-242" fill-opacity="0.6" fill="#A3B1BF" transform="translate(91.594670, 289.963681) rotate(22.000000) translate(-91.594670, -289.963681) " points="91.5946698 291.5796 89.9784233 289.963681 91.5946698 288.347762 93.2109164 289.963681"></polygon>
+                <polygon id="Stroke-244" transform="translate(91.594670, 289.963681) rotate(22.000000) translate(-91.594670, -289.963681) " points="91.5946698 291.5796 89.9784233 289.963681 91.5946698 288.347762 93.2109164 289.963681"></polygon>
+                <polygon id="Fill-246" fill-opacity="0.6" fill="#A3B1BF" transform="translate(93.046240, 293.382517) rotate(22.000000) translate(-93.046240, -293.382517) " points="93.0462402 294.998436 91.4299937 293.382517 93.0462402 291.766598 94.6624868 293.382517"></polygon>
+                <polygon id="Stroke-248" transform="translate(93.046240, 293.382517) rotate(22.000000) translate(-93.046240, -293.382517) " points="93.0462402 294.998436 91.4299937 293.382517 93.0462402 291.766598 94.6624868 293.382517"></polygon>
+                <polygon id="Fill-250" fill-opacity="0.6" fill="#A3B1BF" transform="translate(94.497893, 296.801318) rotate(22.000000) translate(-94.497893, -296.801318) " points="94.4978933 298.417237 92.8816468 296.801318 94.4978933 295.1854 96.1141398 296.801318"></polygon>
+                <polygon id="Stroke-252" transform="translate(94.497893, 296.801318) rotate(22.000000) translate(-94.497893, -296.801318) " points="94.4978933 298.417237 92.8816468 296.801318 94.4978933 295.1854 96.1141398 296.801318"></polygon>
+                <polygon id="Fill-254" fill-opacity="0.6" fill="#A3B1BF" transform="translate(86.986931, 287.884181) rotate(22.000000) translate(-86.986931, -287.884181) " points="86.9869315 289.500099 85.3706849 287.884181 86.9869315 286.268262 88.603178 287.884181"></polygon>
+                <polygon id="Stroke-256" transform="translate(86.986931, 287.884181) rotate(22.000000) translate(-86.986931, -287.884181) " points="86.9869315 289.500099 85.3706849 287.884181 86.9869315 286.268262 88.603178 287.884181"></polygon>
+                <polygon id="Fill-258" fill-opacity="0.6" fill="#A3B1BF" transform="translate(88.438585, 291.302982) rotate(22.000000) translate(-88.438585, -291.302982) " points="88.4385845 292.9189 86.822338 291.302982 88.4385845 289.687063 90.0548311 291.302982"></polygon>
+                <polygon id="Stroke-260" transform="translate(88.438585, 291.302982) rotate(22.000000) translate(-88.438585, -291.302982) " points="88.4385845 292.9189 86.822338 291.302982 88.4385845 289.687063 90.0548311 291.302982"></polygon>
+                <polygon id="Fill-262" fill-opacity="0.6" fill="#A3B1BF" transform="translate(89.890155, 294.721818) rotate(22.000000) translate(-89.890155, -294.721818) " points="89.8901549 296.337737 88.2739084 294.721818 89.8901549 293.105899 91.5064014 294.721818"></polygon>
+                <polygon id="Stroke-264" transform="translate(89.890155, 294.721818) rotate(22.000000) translate(-89.890155, -294.721818) " points="89.8901549 296.337737 88.2739084 294.721818 89.8901549 293.105899 91.5064014 294.721818"></polygon>
+                <polygon id="Fill-266" fill-opacity="0.6" fill="#A3B1BF" transform="translate(91.341749, 298.140595) rotate(22.000000) translate(-91.341749, -298.140595) " points="91.3417491 299.756514 89.7255025 298.140595 91.3417491 296.524677 92.9579956 298.140595"></polygon>
+                <polygon id="Stroke-268" transform="translate(91.341749, 298.140595) rotate(22.000000) translate(-91.341749, -298.140595) " points="91.3417491 299.756514 89.7255025 298.140595 91.3417491 296.524677 92.9579956 298.140595"></polygon>
+                <polygon id="Fill-270" fill-opacity="0.6" fill="#A3B1BF" transform="translate(83.830846, 289.223482) rotate(22.000000) translate(-83.830846, -289.223482) " points="83.8308461 290.8394 82.2145996 289.223482 83.8308461 287.607563 85.4470927 289.223482"></polygon>
+                <polygon id="Stroke-272" transform="translate(83.830846, 289.223482) rotate(22.000000) translate(-83.830846, -289.223482) " points="82.2145996 289.223482 83.8308461 287.607563 85.4470927 289.223482 83.8308461 290.8394"></polygon>
+                <polygon id="Fill-274" fill-opacity="0.6" fill="#A3B1BF" transform="translate(85.282417, 292.642318) rotate(22.000000) translate(-85.282417, -292.642318) " points="85.2824165 294.258236 83.66617 292.642318 85.2824165 291.026399 86.898663 292.642318"></polygon>
+                <polygon id="Stroke-276" transform="translate(85.282417, 292.642318) rotate(22.000000) translate(-85.282417, -292.642318) " points="85.2824165 294.258236 83.66617 292.642318 85.2824165 291.026399 86.898663 292.642318"></polygon>
+                <polygon id="Fill-278" fill-opacity="0.6" fill="#A3B1BF" transform="translate(86.734070, 296.061119) rotate(22.000000) translate(-86.734070, -296.061119) " points="86.7340696 297.677038 85.1178231 296.061119 86.7340696 294.4452 88.3503161 296.061119"></polygon>
+                <polygon id="Stroke-280" transform="translate(86.734070, 296.061119) rotate(22.000000) translate(-86.734070, -296.061119) " points="86.7340696 297.677038 85.1178231 296.061119 86.7340696 294.4452 88.3503161 296.061119"></polygon>
+                <polygon id="Fill-282" fill-opacity="0.6" fill="#A3B1BF" transform="translate(88.185664, 299.479896) rotate(22.000000) translate(-88.185664, -299.479896) " points="88.1856638 301.095815 86.5694172 299.479896 88.1856638 297.863978 89.8019103 299.479896"></polygon>
+                <polygon id="Stroke-284" transform="translate(88.185664, 299.479896) rotate(22.000000) translate(-88.185664, -299.479896) " points="88.1856638 301.095815 86.5694172 299.479896 88.1856638 297.863978 89.8019103 299.479896"></polygon>
+                <polygon id="Fill-286" transform="translate(37.779995, 163.402514) rotate(22.000000) translate(-37.779995, -163.402514) " points="51.9961666 192.018058 66.401345 177.615802 23.5644587 134.78697 9.15864501 149.189862"></polygon>
+                <polygon id="Fill-290" transform="translate(50.400318, 195.682118) rotate(22.000000) translate(-50.400318, -195.682118) " points="54.1737837 198.070743 48.0112085 191.909418 46.6268527 193.293493 52.7894279 199.454818"></polygon>
+                <polygon id="Stroke-292" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(50.400318, 195.682118) rotate(22.000000) translate(-50.400318, -195.682118) " points="54.1737837 198.070743 48.0112085 191.909418 46.6268527 193.293493 52.7894279 199.454818"></polygon>
+                <polygon id="Fill-294" fill-opacity="0.8" fill="#A3B1BF" transform="translate(52.603532, 200.871447) rotate(22.000000) translate(-52.603532, -200.871447) " points="52.712807 203.746308 55.4789773 200.980699 52.4942579 197.996585 49.7280876 200.762195"></polygon>
+                <polygon id="Stroke-296" stroke="#A3B1BF" stroke-width="1.62" fill="#FFFFFF" stroke-linejoin="round" transform="translate(52.603532, 200.871447) rotate(22.000000) translate(-52.603532, -200.871447) " points="52.712807 203.746308 55.4789773 200.980699 52.4942579 197.996585 49.7280876 200.762195"></polygon>
+                <polygon id="Fill-298" fill-opacity="0.8" fill="#A3B1BF" transform="translate(53.983257, 183.836778) rotate(22.000000) translate(-53.983257, -183.836778) " points="52.3670108 183.836778 53.9832574 185.452697 55.5995039 183.836778 53.9832574 182.22086"></polygon>
+                <polygon id="Stroke-300" transform="translate(53.983257, 183.836778) rotate(22.000000) translate(-53.983257, -183.836778) " points="52.3670108 183.836778 53.9832574 185.452697 55.5995039 183.836778 53.9832574 182.22086"></polygon>
+                <polygon id="Fill-302" fill-opacity="0.8" fill="#A3B1BF" transform="translate(52.531663, 180.418001) rotate(22.000000) translate(-52.531663, -180.418001) " points="50.9154167 180.418001 52.5316632 182.03392 54.1479097 180.418001 52.5316632 178.802082"></polygon>
+                <polygon id="Stroke-304" transform="translate(52.531663, 180.418001) rotate(22.000000) translate(-52.531663, -180.418001) " points="50.9154167 180.418001 52.5316632 182.03392 54.1479097 180.418001 52.5316632 178.802082"></polygon>
+                <polygon id="Fill-306" fill-opacity="0.8" fill="#A3B1BF" transform="translate(51.080034, 176.999141) rotate(22.000000) translate(-51.080034, -176.999141) " points="49.4637874 176.999141 51.0800339 178.61506 52.6962805 176.999141 51.0800339 175.383222"></polygon>
+                <polygon id="Stroke-308" transform="translate(51.080034, 176.999141) rotate(22.000000) translate(-51.080034, -176.999141) " points="49.4637874 176.999141 51.0800339 178.61506 52.6962805 176.999141 51.0800339 175.383222"></polygon>
+                <polygon id="Fill-310" fill-opacity="0.8" fill="#A3B1BF" transform="translate(49.628440, 173.580364) rotate(22.000000) translate(-49.628440, -173.580364) " points="48.0121932 173.580364 49.6284397 175.196282 51.2446863 173.580364 49.6284397 171.964445"></polygon>
+                <polygon id="Stroke-312" transform="translate(49.628440, 173.580364) rotate(22.000000) translate(-49.628440, -173.580364) " points="48.0121932 173.580364 49.6284397 175.196282 51.2446863 173.580364 49.6284397 171.964445"></polygon>
+                <polygon id="Fill-314" fill-opacity="0.8" fill="#A3B1BF" transform="translate(50.827172, 185.176079) rotate(22.000000) translate(-50.827172, -185.176079) " points="49.2109255 185.176079 50.8271721 186.791998 52.4434186 185.176079 50.8271721 183.560161"></polygon>
+                <polygon id="Stroke-316" transform="translate(50.827172, 185.176079) rotate(22.000000) translate(-50.827172, -185.176079) " points="49.2109255 185.176079 50.8271721 186.791998 52.4434186 185.176079 50.8271721 183.560161"></polygon>
+                <polygon id="Fill-318" fill-opacity="0.8" fill="#A3B1BF" transform="translate(49.375578, 181.757302) rotate(22.000000) translate(-49.375578, -181.757302) " points="47.7593313 181.757302 49.3755779 183.373221 50.9918244 181.757302 49.3755779 180.141383"></polygon>
+                <polygon id="Stroke-320" transform="translate(49.375578, 181.757302) rotate(22.000000) translate(-49.375578, -181.757302) " points="47.7593313 181.757302 49.3755779 183.373221 50.9918244 181.757302 49.3755779 180.141383"></polygon>
+                <polygon id="Fill-322" fill-opacity="0.8" fill="#A3B1BF" transform="translate(47.923949, 178.338442) rotate(22.000000) translate(-47.923949, -178.338442) " points="46.3077021 178.338442 47.9239486 179.954361 49.5401951 178.338442 47.9239486 176.722523"></polygon>
+                <polygon id="Stroke-324" transform="translate(47.923949, 178.338442) rotate(22.000000) translate(-47.923949, -178.338442) " points="46.3077021 178.338442 47.9239486 179.954361 49.5401951 178.338442 47.9239486 176.722523"></polygon>
+                <polygon id="Fill-326" fill-opacity="0.8" fill="#A3B1BF" transform="translate(46.472354, 174.919665) rotate(22.000000) translate(-46.472354, -174.919665) " points="44.8561079 174.919665 46.4723544 176.535583 48.088601 174.919665 46.4723544 173.303746"></polygon>
+                <polygon id="Stroke-328" transform="translate(46.472354, 174.919665) rotate(22.000000) translate(-46.472354, -174.919665) " points="44.8561079 174.919665 46.4723544 176.535583 48.088601 174.919665 46.4723544 173.303746"></polygon>
+                <polygon id="Fill-330" fill-opacity="0.8" fill="#A3B1BF" transform="translate(47.671087, 186.515380) rotate(22.000000) translate(-47.671087, -186.515380) " points="46.0548402 186.51538 47.6710867 188.131299 49.2873333 186.51538 47.6710867 184.899461"></polygon>
+                <polygon id="Stroke-332" transform="translate(47.671087, 186.515380) rotate(22.000000) translate(-47.671087, -186.515380) " points="46.0548402 186.51538 47.6710867 188.131299 49.2873333 186.51538 47.6710867 184.899461"></polygon>
+                <polygon id="Fill-334" fill-opacity="0.8" fill="#A3B1BF" transform="translate(46.219493, 183.096603) rotate(22.000000) translate(-46.219493, -183.096603) " points="44.603246 183.096603 46.2194926 184.712521 47.8357391 183.096603 46.2194926 181.480684"></polygon>
+                <polygon id="Stroke-336" transform="translate(46.219493, 183.096603) rotate(22.000000) translate(-46.219493, -183.096603) " points="44.603246 183.096603 46.2194926 184.712521 47.8357391 183.096603 46.2194926 181.480684"></polygon>
+                <polygon id="Fill-338" fill-opacity="0.8" fill="#A3B1BF" transform="translate(44.767839, 179.677802) rotate(22.000000) translate(-44.767839, -179.677802) " points="43.1515929 179.677802 44.7678395 181.29372 46.384086 179.677802 44.7678395 178.061883"></polygon>
+                <polygon id="Stroke-340" transform="translate(44.767839, 179.677802) rotate(22.000000) translate(-44.767839, -179.677802) " points="43.1515929 179.677802 44.7678395 181.29372 46.384086 179.677802 44.7678395 178.061883"></polygon>
+                <polygon id="Fill-342" fill-opacity="0.8" fill="#A3B1BF" transform="translate(43.316269, 176.258965) rotate(22.000000) translate(-43.316269, -176.258965) " points="41.7000226 176.258965 43.3162691 177.874884 44.9325156 176.258965 43.3162691 174.643047"></polygon>
+                <polygon id="Stroke-344" transform="translate(43.316269, 176.258965) rotate(22.000000) translate(-43.316269, -176.258965) " points="41.7000226 176.258965 43.3162691 177.874884 44.9325156 176.258965 43.3162691 174.643047"></polygon>
+                <polygon id="Fill-346" fill-opacity="0.8" fill="#A3B1BF" transform="translate(44.514978, 187.854740) rotate(22.000000) translate(-44.514978, -187.854740) " points="42.8987311 187.85474 44.5149776 189.470659 46.1312242 187.85474 44.5149776 186.238821"></polygon>
+                <polygon id="Stroke-348" transform="translate(44.514978, 187.854740) rotate(22.000000) translate(-44.514978, -187.854740) " points="42.8987311 187.85474 44.5149776 189.470659 46.1312242 187.85474 44.5149776 186.238821"></polygon>
+                <polygon id="Fill-350" fill-opacity="0.8" fill="#A3B1BF" transform="translate(43.063348, 184.435880) rotate(22.000000) translate(-43.063348, -184.435880) " points="41.4471018 184.43588 43.0633483 186.051799 44.6795949 184.43588 43.0633483 182.819961"></polygon>
+                <polygon id="Stroke-352" transform="translate(43.063348, 184.435880) rotate(22.000000) translate(-43.063348, -184.435880) " points="41.4471018 184.43588 43.0633483 186.051799 44.6795949 184.43588 43.0633483 182.819961"></polygon>
+                <polygon id="Fill-354" fill-opacity="0.8" fill="#A3B1BF" transform="translate(41.611754, 181.017103) rotate(22.000000) translate(-41.611754, -181.017103) " points="39.9955076 181.017103 41.6117542 182.633021 43.2280007 181.017103 41.6117542 179.401184"></polygon>
+                <polygon id="Stroke-356" transform="translate(41.611754, 181.017103) rotate(22.000000) translate(-41.611754, -181.017103) " points="39.9955076 181.017103 41.6117542 182.633021 43.2280007 181.017103 41.6117542 179.401184"></polygon>
+                <polygon id="Fill-358" fill-opacity="0.8" fill="#A3B1BF" transform="translate(40.160184, 177.598266) rotate(22.000000) translate(-40.160184, -177.598266) " points="38.5439373 177.598266 40.1601838 179.214185 41.7764303 177.598266 40.1601838 175.982348"></polygon>
+                <polygon id="Stroke-360" transform="translate(40.160184, 177.598266) rotate(22.000000) translate(-40.160184, -177.598266) " points="38.5439373 177.598266 40.1601838 179.214185 41.7764303 177.598266 40.1601838 175.982348"></polygon>
+                <polygon id="Fill-362" fill-opacity="0.8" fill="#A3B1BF" transform="translate(41.358892, 189.194041) rotate(22.000000) translate(-41.358892, -189.194041) " points="39.7426458 189.194041 41.3588923 190.80996 42.9751388 189.194041 41.3588923 187.578122"></polygon>
+                <polygon id="Stroke-364" transform="translate(41.358892, 189.194041) rotate(22.000000) translate(-41.358892, -189.194041) " points="39.7426458 189.194041 41.3588923 190.80996 42.9751388 189.194041 41.3588923 187.578122"></polygon>
+                <polygon id="Fill-366" fill-opacity="0.8" fill="#A3B1BF" transform="translate(39.907263, 185.775181) rotate(22.000000) translate(-39.907263, -185.775181) " points="38.2910165 185.775181 39.907263 187.3911 41.5235095 185.775181 39.907263 184.159262"></polygon>
+                <polygon id="Stroke-368" transform="translate(39.907263, 185.775181) rotate(22.000000) translate(-39.907263, -185.775181) " points="38.2910165 185.775181 39.907263 187.3911 41.5235095 185.775181 39.907263 184.159262"></polygon>
+                <polygon id="Fill-370" fill-opacity="0.8" fill="#A3B1BF" transform="translate(38.455669, 182.356404) rotate(22.000000) translate(-38.455669, -182.356404) " points="36.8394223 182.356404 38.4556688 183.972322 40.0719154 182.356404 38.4556688 180.740485"></polygon>
+                <polygon id="Stroke-372" transform="translate(38.455669, 182.356404) rotate(22.000000) translate(-38.455669, -182.356404) " points="36.8394223 182.356404 38.4556688 183.972322 40.0719154 182.356404 38.4556688 180.740485"></polygon>
+                <polygon id="Fill-374" fill-opacity="0.8" fill="#A3B1BF" transform="translate(37.004016, 178.937602) rotate(22.000000) translate(-37.004016, -178.937602) " points="35.3877692 178.937602 37.0040158 180.553521 38.6202623 178.937602 37.0040158 177.321684"></polygon>
+                <polygon id="Stroke-376" transform="translate(37.004016, 178.937602) rotate(22.000000) translate(-37.004016, -178.937602) " points="35.3877692 178.937602 37.0040158 180.553521 38.6202623 178.937602 37.0040158 177.321684"></polygon>
+                <polygon id="Fill-378" fill-opacity="0.8" fill="#A3B1BF" transform="translate(46.380894, 165.931897) rotate(22.000000) translate(-46.380894, -165.931897) " points="44.7646475 165.931897 46.380894 167.547816 47.9971405 165.931897 46.380894 164.315979"></polygon>
+                <polygon id="Stroke-380" transform="translate(46.380894, 165.931897) rotate(22.000000) translate(-46.380894, -165.931897) " points="44.7646475 165.931897 46.380894 167.547816 47.9971405 165.931897 46.380894 164.315979"></polygon>
+                <polygon id="Fill-382" fill-opacity="0.8" fill="#A3B1BF" transform="translate(44.929324, 162.513061) rotate(22.000000) translate(-44.929324, -162.513061) " points="43.3130771 162.513061 44.9293236 164.12898 46.5455702 162.513061 44.9293236 160.897143"></polygon>
+                <polygon id="Stroke-384" transform="translate(44.929324, 162.513061) rotate(22.000000) translate(-44.929324, -162.513061) " points="43.3130771 162.513061 44.9293236 164.12898 46.5455702 162.513061 44.9293236 160.897143"></polygon>
+                <polygon id="Fill-386" fill-opacity="0.8" fill="#A3B1BF" transform="translate(43.477729, 159.094284) rotate(22.000000) translate(-43.477729, -159.094284) " points="41.8614829 159.094284 43.4777295 160.710203 45.093976 159.094284 43.4777295 157.478365"></polygon>
+                <polygon id="Stroke-388" transform="translate(43.477729, 159.094284) rotate(22.000000) translate(-43.477729, -159.094284) " points="41.8614829 159.094284 43.4777295 160.710203 45.093976 159.094284 43.4777295 157.478365"></polygon>
+                <polygon id="Fill-390" fill-opacity="0.8" fill="#A3B1BF" transform="translate(42.026100, 155.675424) rotate(22.000000) translate(-42.026100, -155.675424) " points="40.4098536 155.675424 42.0261002 157.291342 43.6423467 155.675424 42.0261002 154.059505"></polygon>
+                <polygon id="Stroke-392" transform="translate(42.026100, 155.675424) rotate(22.000000) translate(-42.026100, -155.675424) " points="40.4098536 155.675424 42.0261002 157.291342 43.6423467 155.675424 42.0261002 154.059505"></polygon>
+                <polygon id="Fill-394" fill-opacity="0.8" fill="#A3B1BF" transform="translate(43.224809, 167.271198) rotate(22.000000) translate(-43.224809, -167.271198) " points="41.6085622 167.271198 43.2248087 168.887117 44.8410552 167.271198 43.2248087 165.65528"></polygon>
+                <polygon id="Stroke-396" transform="translate(43.224809, 167.271198) rotate(22.000000) translate(-43.224809, -167.271198) " points="41.6085622 167.271198 43.2248087 168.887117 44.8410552 167.271198 43.2248087 165.65528"></polygon>
+                <polygon id="Fill-398" fill-opacity="0.8" fill="#A3B1BF" transform="translate(41.773238, 163.852362) rotate(22.000000) translate(-41.773238, -163.852362) " points="40.1569918 163.852362 41.7732383 165.468281 43.3894848 163.852362 41.7732383 162.236443"></polygon>
+                <polygon id="Stroke-400" transform="translate(41.773238, 163.852362) rotate(22.000000) translate(-41.773238, -163.852362) " points="40.1569918 163.852362 41.7732383 165.468281 43.3894848 163.852362 41.7732383 162.236443"></polygon>
+                <polygon id="Fill-402" fill-opacity="0.8" fill="#A3B1BF" transform="translate(40.321585, 160.433561) rotate(22.000000) translate(-40.321585, -160.433561) " points="38.7053387 160.433561 40.3215852 162.04948 41.9378318 160.433561 40.3215852 158.817642"></polygon>
+                <polygon id="Stroke-404" transform="translate(40.321585, 160.433561) rotate(22.000000) translate(-40.321585, -160.433561) " points="38.7053387 160.433561 40.3215852 162.04948 41.9378318 160.433561 40.3215852 158.817642"></polygon>
+                <polygon id="Fill-406" fill-opacity="0.8" fill="#A3B1BF" transform="translate(38.869991, 157.014784) rotate(22.000000) translate(-38.869991, -157.014784) " points="37.2537445 157.014784 38.8699911 158.630702 40.4862376 157.014784 38.8699911 155.398865"></polygon>
+                <polygon id="Stroke-408" transform="translate(38.869991, 157.014784) rotate(22.000000) translate(-38.869991, -157.014784) " points="37.2537445 157.014784 38.8699911 158.630702 40.4862376 157.014784 38.8699911 155.398865"></polygon>
+                <polygon id="Fill-410" fill-opacity="0.8" fill="#A3B1BF" transform="translate(40.068723, 168.610499) rotate(22.000000) translate(-40.068723, -168.610499) " points="38.4524768 168.610499 40.0687234 170.226418 41.6849699 168.610499 40.0687234 166.994581"></polygon>
+                <polygon id="Stroke-412" transform="translate(40.068723, 168.610499) rotate(22.000000) translate(-40.068723, -168.610499) " points="38.4524768 168.610499 40.0687234 170.226418 41.6849699 168.610499 40.0687234 166.994581"></polygon>
+                <polygon id="Fill-414" fill-opacity="0.8" fill="#A3B1BF" transform="translate(38.617129, 165.191722) rotate(22.000000) translate(-38.617129, -165.191722) " points="37.0008827 165.191722 38.6171292 166.807641 40.2333757 165.191722 38.6171292 163.575803"></polygon>
+                <polygon id="Stroke-416" transform="translate(38.617129, 165.191722) rotate(22.000000) translate(-38.617129, -165.191722) " points="37.0008827 165.191722 38.6171292 166.807641 40.2333757 165.191722 38.6171292 163.575803"></polygon>
+                <polygon id="Fill-418" fill-opacity="0.8" fill="#A3B1BF" transform="translate(37.165500, 161.772862) rotate(22.000000) translate(-37.165500, -161.772862) " points="35.5492534 161.772862 37.1654999 163.388781 38.7817464 161.772862 37.1654999 160.156943"></polygon>
+                <polygon id="Stroke-420" transform="translate(37.165500, 161.772862) rotate(22.000000) translate(-37.165500, -161.772862) " points="35.5492534 161.772862 37.1654999 163.388781 38.7817464 161.772862 37.1654999 160.156943"></polygon>
+                <polygon id="Fill-422" fill-opacity="0.8" fill="#A3B1BF" transform="translate(35.713906, 158.354085) rotate(22.000000) translate(-35.713906, -158.354085) " points="34.0976592 158.354085 35.7139057 159.970003 37.3301523 158.354085 35.7139057 156.738166"></polygon>
+                <polygon id="Stroke-424" transform="translate(35.713906, 158.354085) rotate(22.000000) translate(-35.713906, -158.354085) " points="34.0976592 158.354085 35.7139057 159.970003 37.3301523 158.354085 35.7139057 156.738166"></polygon>
+                <polygon id="Fill-426" fill-opacity="0.8" fill="#A3B1BF" transform="translate(36.912638, 169.949800) rotate(22.000000) translate(-36.912638, -169.949800) " points="35.2963915 169.9498 36.912638 171.565719 38.5288846 169.9498 36.912638 168.333882"></polygon>
+                <polygon id="Stroke-428" transform="translate(36.912638, 169.949800) rotate(22.000000) translate(-36.912638, -169.949800) " points="35.2963915 169.9498 36.912638 171.565719 38.5288846 169.9498 36.912638 168.333882"></polygon>
+                <polygon id="Fill-430" fill-opacity="0.8" fill="#A3B1BF" transform="translate(35.461068, 166.530964) rotate(22.000000) translate(-35.461068, -166.530964) " points="33.8448211 166.530964 35.4610677 168.146883 37.0773142 166.530964 35.4610677 164.915045"></polygon>
+                <polygon id="Stroke-432" transform="translate(35.461068, 166.530964) rotate(22.000000) translate(-35.461068, -166.530964) " points="33.8448211 166.530964 35.4610677 168.146883 37.0773142 166.530964 35.4610677 164.915045"></polygon>
+                <polygon id="Fill-434" fill-opacity="0.8" fill="#A3B1BF" transform="translate(34.009415, 163.112163) rotate(22.000000) translate(-34.009415, -163.112163) " points="32.3931681 163.112163 34.0094146 164.728081 35.6256611 163.112163 34.0094146 161.496244"></polygon>
+                <polygon id="Stroke-436" transform="translate(34.009415, 163.112163) rotate(22.000000) translate(-34.009415, -163.112163) " points="32.3931681 163.112163 34.0094146 164.728081 35.6256611 163.112163 34.0094146 161.496244"></polygon>
+                <polygon id="Fill-438" fill-opacity="0.8" fill="#A3B1BF" transform="translate(32.557820, 159.693385) rotate(22.000000) translate(-32.557820, -159.693385) " points="30.9415739 159.693385 32.5578204 161.309304 34.174067 159.693385 32.5578204 158.077467"></polygon>
+                <polygon id="Stroke-440" transform="translate(32.557820, 159.693385) rotate(22.000000) translate(-32.557820, -159.693385) " points="30.9415739 159.693385 32.5578204 161.309304 34.174067 159.693385 32.5578204 158.077467"></polygon>
+                <polygon id="Fill-442" fill-opacity="0.8" fill="#A3B1BF" transform="translate(33.756553, 171.289101) rotate(22.000000) translate(-33.756553, -171.289101) " points="32.1403062 171.289101 33.7565527 172.90502 35.3727993 171.289101 33.7565527 169.673182"></polygon>
+                <polygon id="Stroke-444" transform="translate(33.756553, 171.289101) rotate(22.000000) translate(-33.756553, -171.289101) " points="32.1403062 171.289101 33.7565527 172.90502 35.3727993 171.289101 33.7565527 169.673182"></polygon>
+                <polygon id="Fill-446" fill-opacity="0.8" fill="#A3B1BF" transform="translate(32.304959, 167.870324) rotate(22.000000) translate(-32.304959, -167.870324) " points="30.688712 167.870324 32.3049586 169.486242 33.9212051 167.870324 32.3049586 166.254405"></polygon>
+                <polygon id="Stroke-448" transform="translate(32.304959, 167.870324) rotate(22.000000) translate(-32.304959, -167.870324) " points="30.688712 167.870324 32.3049586 169.486242 33.9212051 167.870324 32.3049586 166.254405"></polygon>
+                <polygon id="Fill-450" fill-opacity="0.8" fill="#A3B1BF" transform="translate(30.853329, 164.451464) rotate(22.000000) translate(-30.853329, -164.451464) " points="29.2370827 164.451464 30.8533293 166.067382 32.4695758 164.451464 30.8533293 162.835545"></polygon>
+                <polygon id="Stroke-452" transform="translate(30.853329, 164.451464) rotate(22.000000) translate(-30.853329, -164.451464) " points="29.2370827 164.451464 30.8533293 166.067382 32.4695758 164.451464 30.8533293 162.835545"></polygon>
+                <polygon id="Fill-454" fill-opacity="0.8" fill="#A3B1BF" transform="translate(29.401735, 161.032686) rotate(22.000000) translate(-29.401735, -161.032686) " points="27.7854886 161.032686 29.4017351 162.648605 31.0179816 161.032686 29.4017351 159.416768"></polygon>
+                <polygon id="Stroke-456" transform="translate(29.401735, 161.032686) rotate(22.000000) translate(-29.401735, -161.032686) " points="27.7854886 161.032686 29.4017351 162.648605 31.0179816 161.032686 29.4017351 159.416768"></polygon>
+                <polygon id="Fill-458" fill-opacity="0.8" fill="#A3B1BF" transform="translate(38.778613, 148.026981) rotate(22.000000) translate(-38.778613, -148.026981) " points="37.1623668 148.026981 38.7786133 149.6429 40.3948599 148.026981 38.7786133 146.411063"></polygon>
+                <polygon id="Stroke-460" transform="translate(38.778613, 148.026981) rotate(22.000000) translate(-38.778613, -148.026981) " points="37.1623668 148.026981 38.7786133 149.6429 40.3948599 148.026981 38.7786133 146.411063"></polygon>
+                <polygon id="Fill-462" fill-opacity="0.8" fill="#A3B1BF" transform="translate(37.326984, 144.608121) rotate(22.000000) translate(-37.326984, -144.608121) " points="35.7107375 144.608121 37.3269841 146.22404 38.9432306 144.608121 37.3269841 142.992203"></polygon>
+                <polygon id="Stroke-464" transform="translate(37.326984, 144.608121) rotate(22.000000) translate(-37.326984, -144.608121) " points="35.7107375 144.608121 37.3269841 146.22404 38.9432306 144.608121 37.3269841 142.992203"></polygon>
+                <polygon id="Fill-466" fill-opacity="0.8" fill="#A3B1BF" transform="translate(35.875390, 141.189344) rotate(22.000000) translate(-35.875390, -141.189344) " points="34.2591433 141.189344 35.8753899 142.805263 37.4916364 141.189344 35.8753899 139.573425"></polygon>
+                <polygon id="Stroke-468" transform="translate(35.875390, 141.189344) rotate(22.000000) translate(-35.875390, -141.189344) " points="34.2591433 141.189344 35.8753899 142.805263 37.4916364 141.189344 35.8753899 139.573425"></polygon>
+                <polygon id="Fill-470" fill-opacity="0.8" fill="#A3B1BF" transform="translate(34.423796, 137.770567) rotate(22.000000) translate(-34.423796, -137.770567) " points="32.8075492 137.770567 34.4237957 139.386485 36.0400422 137.770567 34.4237957 136.154648"></polygon>
+                <polygon id="Stroke-472" fill="#B2BECA" transform="translate(34.423796, 137.770567) rotate(22.000000) translate(-34.423796, -137.770567) " points="34.4237957 139.386485 36.0400422 137.770567 34.4237957 136.154648 32.8075492 137.770567"></polygon>
+                <polygon id="Fill-474" fill-opacity="0.8" fill="#A3B1BF" transform="translate(35.622528, 149.366282) rotate(22.000000) translate(-35.622528, -149.366282) " points="34.0062815 149.366282 35.622528 150.982201 37.2387746 149.366282 35.622528 147.750364"></polygon>
+                <polygon id="Stroke-476" transform="translate(35.622528, 149.366282) rotate(22.000000) translate(-35.622528, -149.366282) " points="34.0062815 149.366282 35.622528 150.982201 37.2387746 149.366282 35.622528 147.750364"></polygon>
+                <polygon id="Fill-478" fill-opacity="0.8" fill="#A3B1BF" transform="translate(34.170875, 145.947481) rotate(22.000000) translate(-34.170875, -145.947481) " points="32.5546284 145.947481 34.1708749 147.5634 35.7871215 145.947481 34.1708749 144.331563"></polygon>
+                <polygon id="Stroke-480" transform="translate(34.170875, 145.947481) rotate(22.000000) translate(-34.170875, -145.947481) " points="32.5546284 145.947481 34.1708749 147.5634 35.7871215 145.947481 34.1708749 144.331563"></polygon>
+                <polygon id="Fill-482" fill-opacity="0.8" fill="#A3B1BF" transform="translate(32.719305, 142.528645) rotate(22.000000) translate(-32.719305, -142.528645) " points="31.103058 142.528645 32.7193046 144.144564 34.3355511 142.528645 32.7193046 140.912726"></polygon>
+                <polygon id="Stroke-484" transform="translate(32.719305, 142.528645) rotate(22.000000) translate(-32.719305, -142.528645) " points="31.103058 142.528645 32.7193046 144.144564 34.3355511 142.528645 32.7193046 140.912726"></polygon>
+                <polygon id="Fill-486" fill-opacity="0.8" fill="#A3B1BF" transform="translate(31.267651, 139.109844) rotate(22.000000) translate(-31.267651, -139.109844) " points="29.651405 139.109844 31.2676515 140.725763 32.883898 139.109844 31.2676515 137.493925"></polygon>
+                <polygon id="Stroke-488" transform="translate(31.267651, 139.109844) rotate(22.000000) translate(-31.267651, -139.109844) " points="29.651405 139.109844 31.2676515 140.725763 32.883898 139.109844 31.2676515 137.493925"></polygon>
+                <polygon id="Fill-490" fill-opacity="0.8" fill="#A3B1BF" transform="translate(32.466384, 150.705559) rotate(22.000000) translate(-32.466384, -150.705559) " points="30.8501373 150.705559 32.4663838 152.321478 34.0826303 150.705559 32.4663838 149.089641"></polygon>
+                <polygon id="Stroke-492" transform="translate(32.466384, 150.705559) rotate(22.000000) translate(-32.466384, -150.705559) " points="30.8501373 150.705559 32.4663838 152.321478 34.0826303 150.705559 32.4663838 149.089641"></polygon>
+                <polygon id="Fill-494" fill-opacity="0.8" fill="#A3B1BF" transform="translate(31.014790, 147.286782) rotate(22.000000) translate(-31.014790, -147.286782) " points="29.3985431 147.286782 31.0147896 148.902701 32.6310362 147.286782 31.0147896 145.670863"></polygon>
+                <polygon id="Stroke-496" transform="translate(31.014790, 147.286782) rotate(22.000000) translate(-31.014790, -147.286782) " points="29.3985431 147.286782 31.0147896 148.902701 32.6310362 147.286782 31.0147896 145.670863"></polygon>
+                <polygon id="Fill-498" fill-opacity="0.8" fill="#A3B1BF" transform="translate(29.563219, 143.867946) rotate(22.000000) translate(-29.563219, -143.867946) " points="27.9469727 143.867946 29.5632192 145.483865 31.1794658 143.867946 29.5632192 142.252027"></polygon>
+                <polygon id="Stroke-500" transform="translate(29.563219, 143.867946) rotate(22.000000) translate(-29.563219, -143.867946) " points="27.9469727 143.867946 29.5632192 145.483865 31.1794658 143.867946 29.5632192 142.252027"></polygon>
+                <polygon id="Fill-502" fill-opacity="0.8" fill="#A3B1BF" transform="translate(28.111566, 140.449145) rotate(22.000000) translate(-28.111566, -140.449145) " points="26.4953196 140.449145 28.1115662 142.065063 29.7278127 140.449145 28.1115662 138.833226"></polygon>
+                <polygon id="Stroke-504" transform="translate(28.111566, 140.449145) rotate(22.000000) translate(-28.111566, -140.449145) " points="26.4953196 140.449145 28.1115662 142.065063 29.7278127 140.449145 28.1115662 138.833226"></polygon>
+                <polygon id="Fill-506" fill-opacity="0.8" fill="#A3B1BF" transform="translate(29.310298, 152.044860) rotate(22.000000) translate(-29.310298, -152.044860) " points="27.6940519 152.04486 29.3102985 153.660779 30.926545 152.04486 29.3102985 150.428942"></polygon>
+                <polygon id="Stroke-508" transform="translate(29.310298, 152.044860) rotate(22.000000) translate(-29.310298, -152.044860) " points="27.6940519 152.04486 29.3102985 153.660779 30.926545 152.04486 29.3102985 150.428942"></polygon>
+                <polygon id="Fill-510" fill-opacity="0.8" fill="#A3B1BF" transform="translate(27.858704, 148.626083) rotate(22.000000) translate(-27.858704, -148.626083) " points="26.2424578 148.626083 27.8587043 150.242002 29.4749508 148.626083 27.8587043 147.010164"></polygon>
+                <polygon id="Stroke-512" transform="translate(27.858704, 148.626083) rotate(22.000000) translate(-27.858704, -148.626083) " points="26.2424578 148.626083 27.8587043 150.242002 29.4749508 148.626083 27.8587043 147.010164"></polygon>
+                <polygon id="Fill-514" fill-opacity="0.8" fill="#A3B1BF" transform="translate(26.407134, 145.207247) rotate(22.000000) translate(-26.407134, -145.207247) " points="24.7908874 145.207247 26.4071339 146.823166 28.0233805 145.207247 26.4071339 143.591328"></polygon>
+                <polygon id="Stroke-516" transform="translate(26.407134, 145.207247) rotate(22.000000) translate(-26.407134, -145.207247) " points="24.7908874 145.207247 26.4071339 146.823166 28.0233805 145.207247 26.4071339 143.591328"></polygon>
+                <polygon id="Fill-518" fill-opacity="0.8" fill="#A3B1BF" transform="translate(24.955481, 141.788446) rotate(22.000000) translate(-24.955481, -141.788446) " points="23.3392343 141.788446 24.9554808 143.404364 26.5717274 141.788446 24.9554808 140.172527"></polygon>
+                <polygon id="Stroke-520" transform="translate(24.955481, 141.788446) rotate(22.000000) translate(-24.955481, -141.788446) " points="23.3392343 141.788446 24.9554808 143.404364 26.5717274 141.788446 24.9554808 140.172527"></polygon>
+                <polygon id="Fill-522" fill-opacity="0.8" fill="#A3B1BF" transform="translate(26.154213, 153.384161) rotate(22.000000) translate(-26.154213, -153.384161) " points="24.5379666 153.384161 26.1542132 155.00008 27.7704597 153.384161 26.1542132 151.768243"></polygon>
+                <polygon id="Stroke-524" transform="translate(26.154213, 153.384161) rotate(22.000000) translate(-26.154213, -153.384161) " points="24.5379666 153.384161 26.1542132 155.00008 27.7704597 153.384161 26.1542132 151.768243"></polygon>
+                <polygon id="Fill-526" fill-opacity="0.8" fill="#A3B1BF" transform="translate(24.702619, 149.965384) rotate(22.000000) translate(-24.702619, -149.965384) " points="23.0863724 149.965384 24.702619 151.581303 26.3188655 149.965384 24.702619 148.349465"></polygon>
+                <polygon id="Stroke-528" transform="translate(24.702619, 149.965384) rotate(22.000000) translate(-24.702619, -149.965384) " points="23.0863724 149.965384 24.702619 151.581303 26.3188655 149.965384 24.702619 148.349465"></polygon>
+                <polygon id="Fill-530" fill-opacity="0.8" fill="#A3B1BF" transform="translate(23.250966, 146.546583) rotate(22.000000) translate(-23.250966, -146.546583) " points="21.6347194 146.546583 23.2509659 148.162502 24.8672124 146.546583 23.2509659 144.930664"></polygon>
+                <polygon id="Stroke-532" transform="translate(23.250966, 146.546583) rotate(22.000000) translate(-23.250966, -146.546583) " points="21.6347194 146.546583 23.2509659 148.162502 24.8672124 146.546583 23.2509659 144.930664"></polygon>
+                <polygon id="Fill-534" fill-opacity="0.8" fill="#A3B1BF" transform="translate(21.799396, 143.127747) rotate(22.000000) translate(-21.799396, -143.127747) " points="20.183149 143.127747 21.7993955 144.743665 23.4156421 143.127747 21.7993955 141.511828"></polygon>
+                <polygon id="Stroke-536" transform="translate(21.799396, 143.127747) rotate(22.000000) translate(-21.799396, -143.127747) " points="20.183149 143.127747 21.7993955 144.743665 23.4156421 143.127747 21.7993955 141.511828"></polygon>
+                <path d="M129.314819,189.942425 C126.372666,187.000233 124.490222,184.112668 125.110927,183.492089 C125.731631,182.87151 128.619783,184.753573 131.562571,187.695129 C134.504724,190.637321 136.387169,193.524886 135.766464,194.145465 C135.145759,194.766044 132.257608,192.883981 129.314819,189.942425 Z" id="Fill-538" fill="#F5F5F5" transform="translate(130.438695, 188.818777) rotate(22.000000) translate(-130.438695, -188.818777) "></path>
+                <path d="M129.314819,189.942425 C126.372666,187.000233 124.490222,184.112668 125.110927,183.492089 C125.731631,182.87151 128.619783,184.753573 131.562571,187.695129 C134.504724,190.637321 136.387169,193.524886 135.766464,194.145465 C135.145759,194.766044 132.257608,192.883981 129.314819,189.942425 Z" id="Stroke-540" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(130.438695, 188.818777) rotate(22.000000) translate(-130.438695, -188.818777) "></path>
+                <path d="M136.083433,187.715086 C130.20421,181.837055 126.443133,176.067006 127.683272,174.827118 C128.92341,173.587231 134.69463,177.347545 140.573854,183.225576 C146.453713,189.104243 150.21479,194.874292 148.974651,196.114179 C147.734513,197.354066 141.963293,193.593752 136.083433,187.715086 Z" id="Fill-542" fill="#F5F5F5" transform="translate(138.328961, 185.470648) rotate(22.000000) translate(-138.328961, -185.470648) "></path>
+                <path d="M136.083433,187.715086 C130.20421,181.837055 126.443133,176.067006 127.683272,174.827118 C128.92341,173.587231 134.69463,177.347545 140.573854,183.225576 C146.453713,189.104243 150.21479,194.874292 148.974651,196.114179 C147.734513,197.354066 141.963293,193.593752 136.083433,187.715086 Z" id="Stroke-544" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(138.328961, 185.470648) rotate(22.000000) translate(-138.328961, -185.470648) "></path>
+                <path d="M146.697288,183.650834 C138.818086,175.773231 133.777481,168.04045 135.43947,166.378798 C137.101459,164.717146 144.835809,169.756729 152.715011,177.634332 C160.594213,185.511936 165.634818,193.244716 163.972829,194.906369 C162.310839,196.568021 154.57649,191.528438 146.697288,183.650834 Z" id="Fill-546" fill-opacity="0.35" fill="#F5F5F5" transform="translate(149.706149, 180.642583) rotate(22.000000) translate(-149.706149, -180.642583) "></path>
+                <path d="M146.697288,183.650834 C138.818086,175.773231 133.777481,168.04045 135.43947,166.378798 C137.101459,164.717146 144.835809,169.756729 152.715011,177.634332 C160.594213,185.511936 165.634818,193.244716 163.972829,194.906369 C162.310839,196.568021 154.57649,191.528438 146.697288,183.650834 Z" id="Stroke-548" stroke="#A3B1BF" stroke-width="1.62" stroke-linejoin="round" transform="translate(149.706149, 180.642583) rotate(22.000000) translate(-149.706149, -180.642583) "></path>
+                <path d="M65.2279553,90.2345285 C62.4548336,90.0320836 60.4105231,89.3345405 60.4105231,88.5051511 C60.4105231,87.676673 62.4503446,86.9797514 65.2188187,86.7764428 C65.4149139,84.0068366 66.0879499,81.9659221 66.8880741,81.9659221 C67.6881984,81.9659221 68.3612344,84.0068366 68.5573295,86.7764428 C71.3258036,86.9797514 73.3656251,87.676673 73.3656251,88.5051511 C73.3656251,89.3345405 71.3213146,90.0320836 68.548193,90.2345285 C68.3410329,92.9408238 67.6762073,94.9210242 66.8880741,94.9210242 C66.0999409,94.9210242 65.4351154,92.9408238 65.2279553,90.2345285 Z" id="Oval-80-Copy-3" fill-opacity="0.4" fill="#A3B1BF" opacity="0.85" transform="translate(66.888074, 88.443473) rotate(-340.000000) translate(-66.888074, -88.443473) "></path>
+                <path d="M118.775569,329.140492 L118.424988,329.526146 C117.522244,330.5192 115.985396,330.592411 114.992341,329.689667 C114.596934,329.330218 114.331035,328.850456 114.235803,328.324641 L114.143075,327.812647 L113.669257,327.599091 C112.445737,327.047635 111.900921,325.608734 112.452377,324.385214 C112.672015,323.8979 113.046204,323.496601 113.516991,323.243469 L113.97521,322.997095 L114.032158,322.478985 C114.178786,321.144967 115.379087,320.182398 116.713105,320.329026 C117.24418,320.387399 117.741214,320.61917 118.127299,320.988476 L118.503957,321.348765 L119.01334,321.242962 C120.327346,320.970031 121.613813,321.813989 121.886744,323.127995 C121.995449,323.651349 121.928561,324.195943 121.696437,324.677436 L121.470742,325.145594 L121.728812,325.597409 C122.394441,326.762759 121.989337,328.247061 120.823987,328.91269 C120.359975,329.177726 119.82154,329.282421 119.292023,329.21057 L118.775569,329.140492 Z" id="Star-1-Copy-16" fill-opacity="0.4" fill="#A3B1BF"></path>
+                <path d="M432.83752,120.004816 L432.837087,120.005044 L432.837087,120.005044 C432.092472,120.396429 431.171561,120.110079 430.780176,119.365464 C430.624337,119.068978 430.570573,118.729391 430.627206,118.399266 L430.627206,118.399266 L430.627206,118.399266 L430.627206,118.399266 C430.024845,117.812233 430.01242,116.848039 430.599453,116.245678 C430.833262,116.005765 431.139652,115.849637 431.471171,115.801474 L431.471471,115.801431 L431.471471,115.801431 L431.471471,115.801431 C431.843891,115.046982 432.757399,114.737288 433.511848,115.109709 C433.812195,115.25797 434.055308,115.501083 434.20357,115.801431 L434.20357,115.801431 L434.203869,115.801474 L434.203869,115.801474 C435.036229,115.922398 435.612963,116.695187 435.492039,117.527547 C435.443876,117.859067 435.287748,118.165457 435.047835,118.399266 L435.047835,118.399266 L435.047835,118.399266 L435.047835,118.399266 C435.190066,119.228364 434.63325,120.015783 433.804152,120.158014 C433.474027,120.214647 433.134439,120.160883 432.837954,120.005044 L432.83752,120.004816 Z" id="Star-1-Copy-18" fill-opacity="0.4" fill="#A3B1BF" transform="translate(432.837619, 117.566125) rotate(-3.000000) translate(-432.837619, -117.566125) "></path>
+                <path d="M99.7727703,38.762372 L99.0266308,39.1545584 L99.0266308,39.1545584 C97.8386845,39.7789675 96.36948,39.3221304 95.7450708,38.134184 C95.4964477,37.6611755 95.4106732,37.1194035 95.5010241,36.5927278 L95.6433921,35.7628333 L95.0407812,35.1755563 L95.0407812,35.1755563 C94.0796578,34.2388893 94.059832,32.7004261 94.996499,31.7393027 C95.369563,31.3564979 95.8584376,31.1073808 96.3874089,31.0305329 L97.2206742,30.9094778 L97.5937913,30.1536188 L97.5937913,30.1536188 C98.1878378,28.950202 99.6449697,28.4562097 100.848387,29.0502562 C101.327469,29.2867472 101.715258,29.6745363 101.951749,30.1536188 L102.324866,30.9094778 L103.158132,31.0305329 L103.158132,31.0305329 C104.486241,31.223478 105.406474,32.4565366 105.213529,33.7846464 C105.136681,34.3136177 104.887564,34.8024923 104.504759,35.1755563 L103.902148,35.7628333 L104.044516,36.5927278 L104.044516,36.5927278 C104.27143,37.9154575 103.383095,39.1716915 102.060366,39.398605 C101.53369,39.4889559 100.991918,39.4031814 100.51891,39.1545584 L99.7727703,38.762372 Z" id="Star-1-Copy-19" fill-opacity="0.4" fill="#A3B1BF" transform="translate(99.772928, 34.116388) rotate(19.000000) translate(-99.772928, -34.116388) "></path>
+                <path d="M396.631073,305.744172 L396.098125,305.608596 C394.797498,305.277731 394.01135,303.955146 394.342215,302.654518 C394.473956,302.136643 394.772729,301.676633 395.192288,301.345694 L395.623376,301.00566 L395.587617,300.458372 C395.500116,299.119176 396.514815,297.962609 397.854012,297.875108 C398.387399,297.840257 398.917395,297.982247 399.361919,298.279089 L399.818473,298.583965 L400.329362,298.380373 C401.576068,297.883555 402.989473,298.491459 403.486291,299.738164 C403.684076,300.23448 403.712777,300.782145 403.567956,301.296416 L403.418882,301.825788 L403.76981,302.247972 C404.627682,303.280038 404.486471,304.812135 403.454406,305.670007 C403.043346,306.011688 402.531095,306.208301 401.996987,306.229395 L401.44896,306.251039 L401.15585,306.715309 C400.439401,307.850123 398.938655,308.189275 397.80384,307.472826 C397.351988,307.187555 397.006767,306.761296 396.821614,306.260029 L396.631073,305.744172 Z" id="Star-1-Copy-20" fill-opacity="0.4" fill="#A3B1BF"></path>
+                <path d="M439.755536,146.347757 L439.755103,146.347984 L439.755103,146.347984 C439.010488,146.739369 438.089577,146.45302 437.698192,145.708405 C437.542353,145.411919 437.488589,145.072331 437.545222,144.742206 L437.545222,144.742206 L437.545222,144.742206 L437.545222,144.742206 C436.942861,144.155173 436.930436,143.190979 437.517469,142.588619 C437.751277,142.348705 438.057668,142.192577 438.389187,142.144415 L438.389487,142.144371 L438.389487,142.144371 L438.389487,142.144371 C438.761907,141.389923 439.675415,141.080228 440.429864,141.452649 C440.730211,141.600911 440.973324,141.844024 441.121586,142.144371 L441.121586,142.144371 L441.121885,142.144415 L441.121885,142.144415 C441.954245,142.265338 442.530978,143.038128 442.410055,143.870488 C442.361892,144.202007 442.205764,144.508398 441.965851,144.742206 L441.965851,144.742206 L441.965851,144.742206 L441.965851,144.742206 C442.108082,145.571305 441.551266,146.358723 440.722168,146.500955 C440.392043,146.557588 440.052455,146.503823 439.755969,146.347984 L439.755536,146.347757 Z" id="Star-1-Copy-21" fill-opacity="0.4" fill="#A3B1BF" transform="translate(439.755635, 143.909066) rotate(-12.000000) translate(-439.755635, -143.909066) "></path>
+                <path d="M244.621971,220.61341 C277.15945,220.61341 303.536288,194.242112 303.536288,161.711467 C303.536288,129.180822 277.15945,102.809524 244.621971,102.809524 C212.084491,102.809524 185.707653,129.180822 185.707653,161.711467 C185.707653,194.242112 212.084491,220.61341 244.621971,220.61341 Z" id="Oval-8-Copy-2" fill-opacity="0.66" fill="#A3B1BF"></path>
+                <path d="M245.345696,141.060063 C241.146656,141.060063 237.880736,142.342349 235.547936,144.906921 C233.215136,147.354921 232.107056,150.618921 232.107056,154.698921 L236.714336,154.698921 C236.714336,151.842921 237.355856,149.628063 238.638896,147.996063 C240.038576,146.072635 242.196416,145.140063 245.112416,145.140063 C247.561856,145.140063 249.486416,145.781206 250.827776,147.180063 C252.110816,148.462349 252.810656,150.269206 252.810656,152.600635 C252.810656,154.232635 252.227456,155.748063 251.061056,157.205206 C250.711136,157.671492 250.011296,158.370921 249.078176,159.303492 C245.928896,162.101206 244.004336,164.316063 243.187856,166.064635 C242.488016,167.521778 242.138096,169.212063 242.138096,171.135492 L242.138096,172.476063 L246.803696,172.476063 L246.803696,171.135492 C246.803696,169.561778 247.153616,168.162921 247.911776,166.880635 C248.494976,165.831492 249.369776,164.782349 250.652816,163.674921 C253.218896,161.401778 254.793536,159.886349 255.376736,159.186921 C256.834736,157.263492 257.592896,154.990349 257.592896,152.367492 C257.592896,148.870349 256.484816,146.130921 254.326976,144.149206 C252.052496,142.050921 249.078176,141.060063 245.345696,141.060063 Z M244.470896,176.556063 C243.479456,176.556063 242.662976,176.847492 241.963136,177.546921 C241.263296,178.188063 240.971696,179.004063 240.971696,179.994921 C240.971696,180.985778 241.263296,181.801778 241.963136,182.501206 C242.662976,183.142349 243.479456,183.492063 244.470896,183.492063 C245.462336,183.492063 246.278816,183.142349 246.978656,182.501206 C247.678496,181.860063 248.028416,181.044063 248.028416,179.994921 C248.028416,179.004063 247.678496,178.188063 247.036976,177.546921 C246.337136,176.847492 245.462336,176.556063 244.470896,176.556063 Z" id="?" fill="#FFFFFF"></path>
+                <path d="M223.261662,133.139924 C229.077338,129.782947 239.631808,125.828273 236.274126,120.013819 C232.916444,114.199364 220.565868,115.043746 214.750193,118.400722 C208.934517,121.757699 202.729834,131.623951 206.087516,137.438405 C209.445198,143.252859 217.445986,136.4969 223.261662,133.139924" id="Oval-8-Copy-2" fill="#FAFAFA"></path>
+                <path d="M249.679003,119.820589 C252.365149,119.820589 254.5427,117.643495 254.5427,114.957913 C254.5427,112.272332 252.365149,110.095238 249.679003,110.095238 C246.992857,110.095238 244.815306,112.272332 244.815306,114.957913 C244.815306,117.643495 246.992857,119.820589 249.679003,119.820589 Z" id="Oval-10-Copy" fill="#FAFAFA"></path>
+                <path d="M421.5,321.5 L423,323" id="Line-2" stroke="#979797" stroke-linecap="square"></path>
+            </g>
+        </g>
+    </g>
+</svg>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 191 - 0
admin/images/500.svg


BIN
admin/images/act.jpg


BIN
admin/images/avatar.jpg


+ 33 - 0
admin/images/background.svg

@@ -0,0 +1,33 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" width="100%" height="100%" viewBox="0 0 1400 800">
+
+  <rect x="1300" y="400" rx="40" ry="40" width="300" height="300" stroke="rgb(129, 201, 149)" fill="rgb(129, 201, 149)">
+    <animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="0 1450 550" to="360 1450 550" repeatCount="indefinite"/>
+  </rect>
+
+  <path d="M 100 350 A 150 150 0 1 1 400 350 Q400 370 380 370 L 250 370 L 120 370 Q100 370 100 350" stroke="rgb(253, 214, 99)" fill="rgb(253, 214, 99)">
+    <animateMotion path="M 800 -200 L 800 -300 L 800 -200" dur="20s" begin="0s" repeatCount="indefinite"/>
+    <animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="30s" type="rotate" values="0 210 530 ; -30 210 530 ; 0 210 530" keyTimes="0 ; 0.5 ; 1" repeatCount="indefinite"/>
+  </path>
+
+  <circle cx="200" cy="150" r="20" stroke="#1a73e8" fill="#1a73e8">
+    <animateMotion path="M 0 0 L 40 20 Z" dur="5s" repeatCount="indefinite"/>
+  </circle>
+
+  <!-- 三角形 -->
+  <path d="M 165 580 L 270 580 Q275 578 270 570 L 223 483 Q220 480 217 483 L 165 570 Q160 578 165 580" stroke="rgb(238, 103, 92)" fill="rgb(238, 103, 92)">
+    <animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="0 210 530" to="360 210 530" repeatCount="indefinite"/>
+  </path>
+
+  <circle cx="1200" cy="600" r="30" stroke="rgb(241, 243, 244)" fill="rgb(241, 243, 244)">
+    <animateMotion path="M 0 0 L -20 40 Z" dur="9s" repeatCount="indefinite"/>
+  </circle>
+
+  <path d="M 100 350 A 40 40 0 1 1 180 350 L 180 430 A 40 40 0 1 1 100 430 Z" stroke="rgb(241, 243, 244)" fill="rgb(241, 243, 244)">
+    <animateMotion path="M 140 390 L 180 360 L 140 390" dur="20s" begin="0s" repeatCount="indefinite"/>
+    <animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="30s" type="rotate" values="0 140 390; -60 140 390; 0 140 390" keyTimes="0 ; 0.5 ; 1" repeatCount="indefinite"/>
+  </path>
+
+  <rect x="400" y="600" rx="40" ry="40" width="100" height="100" stroke="rgb(129, 201, 149)" fill="rgb(129, 201, 149)">
+    <animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="-30 550 750" to="330 550 750" repeatCount="indefinite"/>
+  </rect>
+</svg>

BIN
admin/images/captcha.gif


BIN
admin/images/logo.png


BIN
admin/images/show.png


+ 627 - 0
app/app.js

@@ -0,0 +1,627 @@
+window.rootUrl = window.location.protocol + '//' + window.location.host;
+window._AUTH_INFO_ = "AUTH_MANAGER";
+window._CONFIG_ = {};   // 后台管理配置.
+window._UPLOAD_TOKEN_ = 'GAkucH8';  // 上传通信token
+window._UPLOAD_SERVER_CONFIG_ = {}; // 上传服务器配置信息.
+window._PLUP_PATH_ = rootUrl + 'app/assets/js/plupload-2.3.7/';   // Plupload 引用资源相对路径.
+window._PLUP_SERVER_URI_ = ''; // Plupload服务端URI,有配置以来,预先空字符串.
+window._PLUP_FILE_FIELD_NAME_ = 'upload_files';    // 上传文件的表单字段名
+window._AES_KEY_ = 'Iz9IhtcyKbYJynAd'; // AES加密的key
+
+
+layui.extend({
+	mhttp: "{/}"+ rootUrl +"/app/modules/mhttp",			// ajax请求组件
+	madmin: "{/}"+ rootUrl +"/app/modules/madmin",			// admin组件
+});
+
+
+String.prototype.trim = function (char, type) {
+    if (char) {
+        if (type == 'left') {
+            return this.replace(new RegExp('^\\'+char+'+', 'g'), '');
+        } else if (type == 'right') {
+            return this.replace(new RegExp('\\'+char+'+$', 'g'), '');
+        }
+        return this.replace(new RegExp('^\\'+char+'+|\\'+char+'+$', 'g'), '');
+    }
+    return this.replace(/^\s+|\s+$/g, '');
+};
+String.prototype.rtrim = function (s) {
+    return this.trim(s, 'right');
+};
+String.prototype.ltrim = function (s) {
+    return this.trim(s, 'left');
+};
+
+/**
+ * 获取应用环境.
+ * @returns 
+ */
+function getAppEnv()
+{
+	var appEnv = 'prod';
+	var hostAndPort = window.location.host;
+	var devReg = /(127\.0\.0\.1|localhost)/;
+	var qaReg = /(test)/;
+	// 设置应用所在环境.
+	if (devReg.test(hostAndPort)) {
+		appEnv = 'dev';
+	} else if (qaReg.test(hostAndPort)) {
+		appEnv = 'test';
+	} else {
+		appEnv = 'prod';
+	}
+
+	return appEnv;
+}
+
+/**
+ * 获取应用配置.
+ * @returns 
+ */
+function getAppConfigPath()
+{
+    var path = 'config/ignore/pear.config.yml';
+    var url = window.location.protocol + '//' + window.location.host + '/' + path;
+	return url;
+}
+
+/**
+ * 格式化时长,格式00:00:00
+ * @param {*} duration 
+ * @returns 
+ */
+function formatDuration(duration)
+{
+    duration = parseFloat(duration);
+    var hour = 60 * 60;
+    var pHour = duration / hour;
+    var strHour = '0';
+    if (pHour > 0) {
+        strHour = parseInt(pHour).toString()
+    }
+	strHour = strHour.padStart(2, '0');
+    var pMinute = parseInt(duration % hour / 60);
+    var strMinute = pMinute.toString().padStart(2, '0');
+    var pSecond = parseInt(duration % hour % 60);
+    var strSecond = pSecond.toString().padStart(2, '0');
+
+    var result = strHour + ":" + strMinute + ":" + strSecond;
+
+    return result;
+}
+
+function httpRequestPostData(data)
+{
+    return {
+        "data": data,
+        "handshake": ""
+    };
+}
+
+function httpRequestPagesParseData(res)
+{
+    let total = 0;
+    if (res.data.total){
+        total = res.data.total;
+    }
+    return {
+        "code": res.code,
+        "msg": res.message,
+        "data" : res.data.data,
+        "count": total
+    };
+}
+
+function cbRespnseRedirectLogin(data)
+{
+    localStorage.removeItem(window._AUTH_INFO_);
+    layer.alert('['+ data.code +']' + data.msg + ', 请重新登陆', {
+        title: '错误信息',
+        icon: 2,
+        closeBtn: 1,
+        shade: 0.5,
+        shadeClose: false,
+        end: function () {
+            parent.location.href = window.rootUrl + '/login.html';
+        }
+    });
+}
+
+
+function cbRespnse401(data)
+{
+    // refreshToken();
+    localStorage.removeItem(window._AUTH_INFO_);
+    layer.alert('['+ data.code +']' + data.msg + ', 请重新登陆', {
+        title: '错误信息',
+        icon: 2,
+        closeBtn: 1,
+        shade: 0.5,
+        shadeClose: false,
+        end: function () {
+            parent.location.href = window.rootUrl + '/login.html';
+        }
+    });
+    
+}
+
+
+function cbRespnseReloadPage(data, message)
+{
+    // localStorage.removeItem(window._AUTH_INFO_);
+    layer.alert('请求异常,请联系客服!', {
+        title: '错误信息',
+        icon: 2,
+        closeBtn: 1,
+        shade: 0.5,
+        shadeClose: false,
+        end: function () {
+            // parent.location.reload();
+        }
+    });
+}
+
+function getMyDetail()
+{
+    var info = localStorage.getItem(window._AUTH_INFO_);
+    return JSON.parse(info);
+}
+
+function getMyUid()
+{
+    var detail = getMyDetail();
+    if (detail) {
+        return detail.manager_uid;
+    } else {
+        return '';
+    }
+}
+
+function refreshToken()
+{
+    layui.use(['mhttp', 'popup'], function () {
+        var mhttp = layui.mhttp;
+        var popup = layui.popup;
+
+        var postData = {
+            "manager_uid": getMyUid(),
+            "old_token": mhttp.ajax.getToken()
+        };
+        var ret = mhttp.ajax({
+            url: "/auth/refresh/token",
+            data : postData,
+            // 同步.
+            async: false
+        });
+
+        ret.then((data) => {
+            if (data.code == 200) {
+                // 设置token
+                mhttp.ajax.setToken(data.data.token);
+            } else {
+                console.log('刷新token');
+                // 错误提示.
+                popup.failure('['+ data.code +']' + data.message);
+            }
+        });
+    });
+}
+
+function threadBizCodeNoParams(code, func)
+{
+    // if (code == 401) {
+    //     func.call(null);
+    // }
+}
+
+
+/**
+ * 格式化为相对协议.
+ * @param {*} url 
+ * @returns 
+ */
+ function slashesUrl(url)
+ {
+    var pattern = /^(http|https)\:\/\/(.*?)$/i;
+    var arr = url.match(pattern);
+    if (arr) {
+        return '//' + arr[2];
+    } else {
+        return url;
+    }
+ }
+
+/**
+ * 把buffer转b64
+ * 参考1:https://stackoverflow.com/questions/27375908/crypto-js-read-and-decrypt-file
+ * 擦靠2:https://gist.github.com/jonleighton/958841
+ * @param {*} arrayBuffer 
+ * @returns 
+ */
+function base64ArrayBuffer(arrayBuffer) {
+    var base64    = ''
+    var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+  
+    var bytes         = new Uint8Array(arrayBuffer)
+    var byteLength    = bytes.byteLength
+    var byteRemainder = byteLength % 3
+    var mainLength    = byteLength - byteRemainder
+  
+    var a, b, c, d
+    var chunk
+  
+    // Main loop deals with bytes in chunks of 3
+    for (var i = 0; i < mainLength; i = i + 3) {
+      // Combine the three bytes into a single integer
+      chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
+  
+      // Use bitmasks to extract 6-bit segments from the triplet
+      a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
+      b = (chunk & 258048)   >> 12 // 258048   = (2^6 - 1) << 12
+      c = (chunk & 4032)     >>  6 // 4032     = (2^6 - 1) << 6
+      d = chunk & 63               // 63       = 2^6 - 1
+  
+      // Convert the raw binary segments to the appropriate ASCII encoding
+      base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
+    }
+  
+    // Deal with the remaining bytes and padding
+    if (byteRemainder == 1) {
+      chunk = bytes[mainLength]
+  
+      a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2
+  
+      // Set the 4 least significant bits to zero
+      b = (chunk & 3)   << 4 // 3   = 2^2 - 1
+  
+      base64 += encodings[a] + encodings[b] + '=='
+    } else if (byteRemainder == 2) {
+      chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
+  
+      a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10
+      b = (chunk & 1008)  >>  4 // 1008  = (2^6 - 1) << 4
+  
+      // Set the 2 least significant bits to zero
+      c = (chunk & 15)    <<  2 // 15    = 2^4 - 1
+  
+      base64 += encodings[a] + encodings[b] + encodings[c] + '='
+    }
+    
+    return base64
+}
+
+/**
+ * 调试log,只有_DEBUG_全局变量为true才会输出.
+ */
+function debugLog()
+{
+    if (typeof(_DEBUG_) != 'undefined') {
+        if (_DEBUG_ == true) {
+            console.log(...arguments)
+        }
+    }
+}
+
+/**
+ * 获取自己的上传服务的url。
+ * @param {*} url 
+ * @returns 
+ */
+function getMyUploadUrl(url)
+{
+    return slashesUrl(window._CONFIG_.sysconfig.uploadServerBaseUrl + url);
+}
+
+/**
+ * 获取自己的后台API服务url
+ * @param {*} url 
+ * @returns 
+ */
+function getMyApiUrl(url)
+{
+    return slashesUrl(window._CONFIG_.sysconfig.apiServerBaseUrl + url);
+}
+
+
+/**
+ * 获取存储服务器组配置信息.
+ */
+ function getStorageServersConfig()
+ {
+    layui.use(['jquery', 'madmin', 'popup'], function () {
+        let $ = layui.jquery;
+        let madmin = layui.madmin;
+        let popup = layui.popup;
+        let config = madmin.getConfig();
+        window._PLUP_SERVER_URI_ = getMyUploadUrl('/uploader.php');   // 依赖 getConfig
+        $.ajax(
+            {
+                type:'GET',
+                url: getMyUploadUrl('/sg_server_config.php?upload_token='+ window._UPLOAD_TOKEN_),
+                data: {},
+                async: false,   // 注意,因为初始化,优先这里要同步.
+                dataType: 'json',
+                beforeSend : function() {
+                },
+                complete: function() {
+                },
+                error : function() {
+                    popup.failure('获取上传服务器请求出错');
+                },
+                success: function(s) {
+                    if (s.code == 200) {
+                        window._UPLOAD_SERVER_CONFIG_ = s.data;
+                    } else {
+                        popup.failure('['+ data.code +']' + data.message);
+                    }
+                }
+                
+            }
+        );
+    });
+ }
+
+
+ /**
+  * 拼接待解密的完整URL.
+  * @param {*} url 
+  * @param {*} convertSlashes 
+  * @returns 
+  */
+  function concatUrl(url, convertSlashes)
+  {
+     let baseUrl = '';
+     if (url.lastIndexOf('|') > -1) {
+         // 找到分隔符.
+         let arrData = url.split('|');
+         let flag = arrData[0];
+         let relativeUrl = arrData[1];
+         if (window._UPLOAD_SERVER_CONFIG_.servers.hasOwnProperty(flag)) {
+             baseUrl = window._UPLOAD_SERVER_CONFIG_.servers[flag]['url'];
+             var resultUrl = baseUrl + relativeUrl;
+             if (convertSlashes) {
+                 resultUrl = slashesUrl(resultUrl);
+             }
+             return resultUrl;
+         } else {
+             return '';
+         }
+     } else {
+         return '';
+     }
+  }
+ 
+ /**
+  * 在属性里获取url.
+  * @param {*} ele 
+  * @returns 
+  */
+ function getUrlInAttrs(ele)
+ {
+     return layui.use(['jquery'], function () {
+        let $ = layui.jquery;
+        let b64 = $(ele).attr('data-b64');
+        if (b64) {
+            return $(ele).attr('data-b64');
+        } else {
+            return '';
+        }
+     });
+ }
+
+/**
+ * 解密基于arrayBuffer数据.
+ * @param {*} buffers 
+ * @returns 
+ */
+function aes128ecbDecodeByBuffer(buffers)
+{
+    let encodedData = base64ArrayBuffer(buffers);   // 这个地方很重要!
+    let options = {
+        iv: '',
+        mode: CryptoJS.mode.ECB,
+        padding: CryptoJS.pad.Pkcs7
+    };
+    let keyObj = CryptoJS.enc.Utf8.parse(window._AES_KEY_);    // 必须是对象key
+    let decrypted = CryptoJS.AES.decrypt(encodedData, keyObj, options);
+
+    return decrypted;
+}
+
+/**
+ * 拼接dataURL.
+ * @param {*} b64 
+ * @returns 
+ */
+ function concatImageDataUrl(b64)
+ {
+     return "data:image/png;base64," + b64;
+ }
+
+/**
+ * 现代浏览器Fetch异步下载并解密图片.
+ * @param {*} url 
+ * @returns 
+ */
+function fetchImageFile(url)
+{
+    return fetch(url, {
+        method: 'GET'
+        // headers: {
+        //     Authorization: 'Bearer ' + token,
+        //     'Accept': 'application/json'
+        // }
+    }).then(
+        // 必须是arrayBuffer
+        response => {
+            if (response.ok) {
+                return response.arrayBuffer();
+            } else {
+                return Promise.reject({
+                    status: response.status,
+                    statusText: response.statusText
+                });
+            }
+        }
+    ).then(respRaw => {
+        let ext = getFileExt(url);
+        let strB64 = "";
+        if (ext == 'ceb') {
+            // 仅对ceb扩展名,进行解密.
+            let decrypted = aes128ecbDecodeByBuffer(respRaw);
+            strB64 = decrypted.toString(CryptoJS.enc.Base64);
+        } else {
+            strB64 = base64ArrayBuffer(respRaw);
+        }
+        let dataUrl = concatImageDataUrl(strB64);
+        return dataUrl;
+    }).catch(error => {
+    });
+    
+}
+
+/**
+ * 获取文件扩展名,不包括dot.
+ * @param {*} file 
+ * @returns 
+ */
+function getFileExt(file)
+{
+    let ext = file.substring(file.lastIndexOf('.') + 1);
+    return ext.toLowerCase();
+}
+
+
+/**
+ * 渲染datahref
+ * @param {*} ele 
+ * @param {*} dataHref
+ */
+ function renderDataHref(ele, dataHref)
+ {
+    layui.use(['jquery'], function () {
+        let $ = layui.jquery;
+        $(ele).attr('href', dataHref);
+    });
+ }
+
+/**
+ * 渲染data
+ * @param {*} ele
+ * @param {*} dataUrl
+ */
+ function renderDataUrl(ele, dataUrl)
+ {
+    layui.use(['jquery'], function () {
+        let $ = layui.jquery;
+        $(ele).attr('src', dataUrl);
+    });
+ }
+ 
+ /**
+  * 单个对象渲染图片(依赖jQuery)
+  * @param {*} ele 
+  */
+ function onceRender(ele)
+ {
+    layui.use(['jquery'], function () {
+        let $ = layui.jquery;
+        let originUrl = '';
+        let dataCebUrl = $(ele).attr('data-ceb-url');
+        let srcValue = $(ele).attr('src');
+        // 优先取data-ceb-url值,因为直接放src属性里的图片,会报404.
+        if (typeof(dataCebUrl) != 'undefined' && dataCebUrl != '') {
+            originUrl = dataCebUrl;
+        } else if (typeof(srcValue) != 'undefined' && srcValue != '') {
+            originUrl = srcValue;
+        }
+        if (originUrl.lastIndexOf('|') > -1) {
+            let b64Url = originUrl;
+            let convertSlashes = 1;
+            // let b64Url = $(ele).attr('data-b64');
+            let fullUrl = concatUrl(b64Url, convertSlashes);
+            if (fullUrl != '') {
+                // 备份一次原始图片地址
+                $(ele).attr('data-ceb-url', originUrl);
+                // 合法的才渲染.
+                let promiseResult = fetchImageFile(fullUrl);
+                promiseResult.then(dataUrl =>  {
+                    renderDataUrl(ele, dataUrl);
+                });
+            }
+        }
+    });
+ }
+
+/**
+ * 下载app地址处理
+ * @param ele
+ */
+function appDownloadRender(ele){
+    layui.use(['jquery'], function () {
+        let $ = layui.jquery;
+        let dataHref = $(ele).attr('href');
+        if (typeof(dataHref) == 'undefined' || dataHref === '') {
+            return false;
+        }
+        // 拆分
+        if (dataHref.lastIndexOf('|') > -1) {
+            let arrData = dataHref.split('|');
+            let flag = arrData[0];
+            let relativeUrl = arrData[1];
+            // 合并
+            if (window._UPLOAD_SERVER_CONFIG_.servers.hasOwnProperty(flag)) {
+                let baseUrl = window._UPLOAD_SERVER_CONFIG_.servers[flag]['url'];
+                var resultUrl = baseUrl + relativeUrl;
+                $(ele).attr('href',resultUrl);
+            }
+        }
+    });
+ }
+ /**
+  * 页面初始化dom加载完毕后渲染所有img标签.
+  */
+function onloadRender()
+{
+layui.use(['jquery'], function () {
+    let $ = layui.jquery;
+    $(function() {
+        $('img').each(function (index, ele) {
+            onceRender(ele);
+        });
+        //app下载地址修改
+        $('.app-download').each(function (index,ele){
+            appDownloadRender(ele);
+        });
+    });
+});
+}
+
+/**
+ * 获取同字段名数组的值.
+ * 因为layui表单获取同字段名数组时,无法正常给数组结构。
+ * @param {*} fieldName 
+ * @param {*} fieldItems 
+ * @returns 
+ */
+function getLayuiArrFieldValue(fieldName, fieldItems)
+{
+    let arrFields = [];
+    let arrData = [];
+    if (fieldItems && Object.keys(fieldItems).length > 0) {
+        for (const keyName in fieldItems) {
+            if (fieldItems.hasOwnProperty(keyName)) {
+                var strPattern = '^(' + fieldName +')\\[\\d+\\]$';
+                var reg = new RegExp(strPattern, 'i')
+                var result = keyName.match(reg);
+                if (result) {
+                    arrFields.push(result[0]);
+                    arrData.push(fieldItems[keyName]);
+                }
+            }
+        }
+    }
+
+    return arrData;
+}

+ 6191 - 0
app/assets/js/crypto/crypto-js.js

@@ -0,0 +1,6191 @@
+;(function (root, factory) {
+	if (typeof exports === "object") {
+		// CommonJS
+		module.exports = exports = factory();
+	}
+	else if (typeof define === "function" && define.amd) {
+		// AMD
+		define([], factory);
+	}
+	else {
+		// Global (browser)
+		root.CryptoJS = factory();
+	}
+}(this, function () {
+
+	/*globals window, global, require*/
+
+	/**
+	 * CryptoJS core components.
+	 */
+	var CryptoJS = CryptoJS || (function (Math, undefined) {
+
+	    var crypto;
+
+	    // Native crypto from window (Browser)
+	    if (typeof window !== 'undefined' && window.crypto) {
+	        crypto = window.crypto;
+	    }
+
+	    // Native crypto in web worker (Browser)
+	    if (typeof self !== 'undefined' && self.crypto) {
+	        crypto = self.crypto;
+	    }
+
+	    // Native crypto from worker
+	    if (typeof globalThis !== 'undefined' && globalThis.crypto) {
+	        crypto = globalThis.crypto;
+	    }
+
+	    // Native (experimental IE 11) crypto from window (Browser)
+	    if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
+	        crypto = window.msCrypto;
+	    }
+
+	    // Native crypto from global (NodeJS)
+	    if (!crypto && typeof global !== 'undefined' && global.crypto) {
+	        crypto = global.crypto;
+	    }
+
+	    // Native crypto import via require (NodeJS)
+	    if (!crypto && typeof require === 'function') {
+	        try {
+	            crypto = require('crypto');
+	        } catch (err) {}
+	    }
+
+	    /*
+	     * Cryptographically secure pseudorandom number generator
+	     *
+	     * As Math.random() is cryptographically not safe to use
+	     */
+	    var cryptoSecureRandomInt = function () {
+	        if (crypto) {
+	            // Use getRandomValues method (Browser)
+	            if (typeof crypto.getRandomValues === 'function') {
+	                try {
+	                    return crypto.getRandomValues(new Uint32Array(1))[0];
+	                } catch (err) {}
+	            }
+
+	            // Use randomBytes method (NodeJS)
+	            if (typeof crypto.randomBytes === 'function') {
+	                try {
+	                    return crypto.randomBytes(4).readInt32LE();
+	                } catch (err) {}
+	            }
+	        }
+
+	        throw new Error('Native crypto module could not be used to get secure random number.');
+	    };
+
+	    /*
+	     * Local polyfill of Object.create
+
+	     */
+	    var create = Object.create || (function () {
+	        function F() {}
+
+	        return function (obj) {
+	            var subtype;
+
+	            F.prototype = obj;
+
+	            subtype = new F();
+
+	            F.prototype = null;
+
+	            return subtype;
+	        };
+	    }());
+
+	    /**
+	     * CryptoJS namespace.
+	     */
+	    var C = {};
+
+	    /**
+	     * Library namespace.
+	     */
+	    var C_lib = C.lib = {};
+
+	    /**
+	     * Base object for prototypal inheritance.
+	     */
+	    var Base = C_lib.Base = (function () {
+
+
+	        return {
+	            /**
+	             * Creates a new object that inherits from this object.
+	             *
+	             * @param {Object} overrides Properties to copy into the new object.
+	             *
+	             * @return {Object} The new object.
+	             *
+	             * @static
+	             *
+	             * @example
+	             *
+	             *     var MyType = CryptoJS.lib.Base.extend({
+	             *         field: 'value',
+	             *
+	             *         method: function () {
+	             *         }
+	             *     });
+	             */
+	            extend: function (overrides) {
+	                // Spawn
+	                var subtype = create(this);
+
+	                // Augment
+	                if (overrides) {
+	                    subtype.mixIn(overrides);
+	                }
+
+	                // Create default initializer
+	                if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
+	                    subtype.init = function () {
+	                        subtype.$super.init.apply(this, arguments);
+	                    };
+	                }
+
+	                // Initializer's prototype is the subtype object
+	                subtype.init.prototype = subtype;
+
+	                // Reference supertype
+	                subtype.$super = this;
+
+	                return subtype;
+	            },
+
+	            /**
+	             * Extends this object and runs the init method.
+	             * Arguments to create() will be passed to init().
+	             *
+	             * @return {Object} The new object.
+	             *
+	             * @static
+	             *
+	             * @example
+	             *
+	             *     var instance = MyType.create();
+	             */
+	            create: function () {
+	                var instance = this.extend();
+	                instance.init.apply(instance, arguments);
+
+	                return instance;
+	            },
+
+	            /**
+	             * Initializes a newly created object.
+	             * Override this method to add some logic when your objects are created.
+	             *
+	             * @example
+	             *
+	             *     var MyType = CryptoJS.lib.Base.extend({
+	             *         init: function () {
+	             *             // ...
+	             *         }
+	             *     });
+	             */
+	            init: function () {
+	            },
+
+	            /**
+	             * Copies properties into this object.
+	             *
+	             * @param {Object} properties The properties to mix in.
+	             *
+	             * @example
+	             *
+	             *     MyType.mixIn({
+	             *         field: 'value'
+	             *     });
+	             */
+	            mixIn: function (properties) {
+	                for (var propertyName in properties) {
+	                    if (properties.hasOwnProperty(propertyName)) {
+	                        this[propertyName] = properties[propertyName];
+	                    }
+	                }
+
+	                // IE won't copy toString using the loop above
+	                if (properties.hasOwnProperty('toString')) {
+	                    this.toString = properties.toString;
+	                }
+	            },
+
+	            /**
+	             * Creates a copy of this object.
+	             *
+	             * @return {Object} The clone.
+	             *
+	             * @example
+	             *
+	             *     var clone = instance.clone();
+	             */
+	            clone: function () {
+	                return this.init.prototype.extend(this);
+	            }
+	        };
+	    }());
+
+	    /**
+	     * An array of 32-bit words.
+	     *
+	     * @property {Array} words The array of 32-bit words.
+	     * @property {number} sigBytes The number of significant bytes in this word array.
+	     */
+	    var WordArray = C_lib.WordArray = Base.extend({
+	        /**
+	         * Initializes a newly created word array.
+	         *
+	         * @param {Array} words (Optional) An array of 32-bit words.
+	         * @param {number} sigBytes (Optional) The number of significant bytes in the words.
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.lib.WordArray.create();
+	         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
+	         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
+	         */
+	        init: function (words, sigBytes) {
+	            words = this.words = words || [];
+
+	            if (sigBytes != undefined) {
+	                this.sigBytes = sigBytes;
+	            } else {
+	                this.sigBytes = words.length * 4;
+	            }
+	        },
+
+	        /**
+	         * Converts this word array to a string.
+	         *
+	         * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
+	         *
+	         * @return {string} The stringified word array.
+	         *
+	         * @example
+	         *
+	         *     var string = wordArray + '';
+	         *     var string = wordArray.toString();
+	         *     var string = wordArray.toString(CryptoJS.enc.Utf8);
+	         */
+	        toString: function (encoder) {
+	            return (encoder || Hex).stringify(this);
+	        },
+
+	        /**
+	         * Concatenates a word array to this word array.
+	         *
+	         * @param {WordArray} wordArray The word array to append.
+	         *
+	         * @return {WordArray} This word array.
+	         *
+	         * @example
+	         *
+	         *     wordArray1.concat(wordArray2);
+	         */
+	        concat: function (wordArray) {
+	            // Shortcuts
+	            var thisWords = this.words;
+	            var thatWords = wordArray.words;
+	            var thisSigBytes = this.sigBytes;
+	            var thatSigBytes = wordArray.sigBytes;
+
+	            // Clamp excess bits
+	            this.clamp();
+
+	            // Concat
+	            if (thisSigBytes % 4) {
+	                // Copy one byte at a time
+	                for (var i = 0; i < thatSigBytes; i++) {
+	                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
+	                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
+	                }
+	            } else {
+	                // Copy one word at a time
+	                for (var j = 0; j < thatSigBytes; j += 4) {
+	                    thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2];
+	                }
+	            }
+	            this.sigBytes += thatSigBytes;
+
+	            // Chainable
+	            return this;
+	        },
+
+	        /**
+	         * Removes insignificant bits.
+	         *
+	         * @example
+	         *
+	         *     wordArray.clamp();
+	         */
+	        clamp: function () {
+	            // Shortcuts
+	            var words = this.words;
+	            var sigBytes = this.sigBytes;
+
+	            // Clamp
+	            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
+	            words.length = Math.ceil(sigBytes / 4);
+	        },
+
+	        /**
+	         * Creates a copy of this word array.
+	         *
+	         * @return {WordArray} The clone.
+	         *
+	         * @example
+	         *
+	         *     var clone = wordArray.clone();
+	         */
+	        clone: function () {
+	            var clone = Base.clone.call(this);
+	            clone.words = this.words.slice(0);
+
+	            return clone;
+	        },
+
+	        /**
+	         * Creates a word array filled with random bytes.
+	         *
+	         * @param {number} nBytes The number of random bytes to generate.
+	         *
+	         * @return {WordArray} The random word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.lib.WordArray.random(16);
+	         */
+	        random: function (nBytes) {
+	            var words = [];
+
+	            for (var i = 0; i < nBytes; i += 4) {
+	                words.push(cryptoSecureRandomInt());
+	            }
+
+	            return new WordArray.init(words, nBytes);
+	        }
+	    });
+
+	    /**
+	     * Encoder namespace.
+	     */
+	    var C_enc = C.enc = {};
+
+	    /**
+	     * Hex encoding strategy.
+	     */
+	    var Hex = C_enc.Hex = {
+	        /**
+	         * Converts a word array to a hex string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @return {string} The hex string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);
+	         */
+	        stringify: function (wordArray) {
+	            // Shortcuts
+	            var words = wordArray.words;
+	            var sigBytes = wordArray.sigBytes;
+
+	            // Convert
+	            var hexChars = [];
+	            for (var i = 0; i < sigBytes; i++) {
+	                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
+	                hexChars.push((bite >>> 4).toString(16));
+	                hexChars.push((bite & 0x0f).toString(16));
+	            }
+
+	            return hexChars.join('');
+	        },
+
+	        /**
+	         * Converts a hex string to a word array.
+	         *
+	         * @param {string} hexStr The hex string.
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Hex.parse(hexString);
+	         */
+	        parse: function (hexStr) {
+	            // Shortcut
+	            var hexStrLength = hexStr.length;
+
+	            // Convert
+	            var words = [];
+	            for (var i = 0; i < hexStrLength; i += 2) {
+	                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
+	            }
+
+	            return new WordArray.init(words, hexStrLength / 2);
+	        }
+	    };
+
+	    /**
+	     * Latin1 encoding strategy.
+	     */
+	    var Latin1 = C_enc.Latin1 = {
+	        /**
+	         * Converts a word array to a Latin1 string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @return {string} The Latin1 string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
+	         */
+	        stringify: function (wordArray) {
+	            // Shortcuts
+	            var words = wordArray.words;
+	            var sigBytes = wordArray.sigBytes;
+
+	            // Convert
+	            var latin1Chars = [];
+	            for (var i = 0; i < sigBytes; i++) {
+	                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
+	                latin1Chars.push(String.fromCharCode(bite));
+	            }
+
+	            return latin1Chars.join('');
+	        },
+
+	        /**
+	         * Converts a Latin1 string to a word array.
+	         *
+	         * @param {string} latin1Str The Latin1 string.
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
+	         */
+	        parse: function (latin1Str) {
+	            // Shortcut
+	            var latin1StrLength = latin1Str.length;
+
+	            // Convert
+	            var words = [];
+	            for (var i = 0; i < latin1StrLength; i++) {
+	                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
+	            }
+
+	            return new WordArray.init(words, latin1StrLength);
+	        }
+	    };
+
+	    /**
+	     * UTF-8 encoding strategy.
+	     */
+	    var Utf8 = C_enc.Utf8 = {
+	        /**
+	         * Converts a word array to a UTF-8 string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @return {string} The UTF-8 string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
+	         */
+	        stringify: function (wordArray) {
+	            try {
+	                return decodeURIComponent(escape(Latin1.stringify(wordArray)));
+	            } catch (e) {
+	                throw new Error('Malformed UTF-8 data');
+	            }
+	        },
+
+	        /**
+	         * Converts a UTF-8 string to a word array.
+	         *
+	         * @param {string} utf8Str The UTF-8 string.
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
+	         */
+	        parse: function (utf8Str) {
+	            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
+	        }
+	    };
+
+	    /**
+	     * Abstract buffered block algorithm template.
+	     *
+	     * The property blockSize must be implemented in a concrete subtype.
+	     *
+	     * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
+	     */
+	    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
+	        /**
+	         * Resets this block algorithm's data buffer to its initial state.
+	         *
+	         * @example
+	         *
+	         *     bufferedBlockAlgorithm.reset();
+	         */
+	        reset: function () {
+	            // Initial values
+	            this._data = new WordArray.init();
+	            this._nDataBytes = 0;
+	        },
+
+	        /**
+	         * Adds new data to this block algorithm's buffer.
+	         *
+	         * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
+	         *
+	         * @example
+	         *
+	         *     bufferedBlockAlgorithm._append('data');
+	         *     bufferedBlockAlgorithm._append(wordArray);
+	         */
+	        _append: function (data) {
+	            // Convert string to WordArray, else assume WordArray already
+	            if (typeof data == 'string') {
+	                data = Utf8.parse(data);
+	            }
+
+	            // Append
+	            this._data.concat(data);
+	            this._nDataBytes += data.sigBytes;
+	        },
+
+	        /**
+	         * Processes available data blocks.
+	         *
+	         * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
+	         *
+	         * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
+	         *
+	         * @return {WordArray} The processed data.
+	         *
+	         * @example
+	         *
+	         *     var processedData = bufferedBlockAlgorithm._process();
+	         *     var processedData = bufferedBlockAlgorithm._process(!!'flush');
+	         */
+	        _process: function (doFlush) {
+	            var processedWords;
+
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+	            var dataSigBytes = data.sigBytes;
+	            var blockSize = this.blockSize;
+	            var blockSizeBytes = blockSize * 4;
+
+	            // Count blocks ready
+	            var nBlocksReady = dataSigBytes / blockSizeBytes;
+	            if (doFlush) {
+	                // Round up to include partial blocks
+	                nBlocksReady = Math.ceil(nBlocksReady);
+	            } else {
+	                // Round down to include only full blocks,
+	                // less the number of blocks that must remain in the buffer
+	                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
+	            }
+
+	            // Count words ready
+	            var nWordsReady = nBlocksReady * blockSize;
+
+	            // Count bytes ready
+	            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
+
+	            // Process blocks
+	            if (nWordsReady) {
+	                for (var offset = 0; offset < nWordsReady; offset += blockSize) {
+	                    // Perform concrete-algorithm logic
+	                    this._doProcessBlock(dataWords, offset);
+	                }
+
+	                // Remove processed words
+	                processedWords = dataWords.splice(0, nWordsReady);
+	                data.sigBytes -= nBytesReady;
+	            }
+
+	            // Return processed words
+	            return new WordArray.init(processedWords, nBytesReady);
+	        },
+
+	        /**
+	         * Creates a copy of this object.
+	         *
+	         * @return {Object} The clone.
+	         *
+	         * @example
+	         *
+	         *     var clone = bufferedBlockAlgorithm.clone();
+	         */
+	        clone: function () {
+	            var clone = Base.clone.call(this);
+	            clone._data = this._data.clone();
+
+	            return clone;
+	        },
+
+	        _minBufferSize: 0
+	    });
+
+	    /**
+	     * Abstract hasher template.
+	     *
+	     * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
+	     */
+	    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
+	        /**
+	         * Configuration options.
+	         */
+	        cfg: Base.extend(),
+
+	        /**
+	         * Initializes a newly created hasher.
+	         *
+	         * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
+	         *
+	         * @example
+	         *
+	         *     var hasher = CryptoJS.algo.SHA256.create();
+	         */
+	        init: function (cfg) {
+	            // Apply config defaults
+	            this.cfg = this.cfg.extend(cfg);
+
+	            // Set initial values
+	            this.reset();
+	        },
+
+	        /**
+	         * Resets this hasher to its initial state.
+	         *
+	         * @example
+	         *
+	         *     hasher.reset();
+	         */
+	        reset: function () {
+	            // Reset data buffer
+	            BufferedBlockAlgorithm.reset.call(this);
+
+	            // Perform concrete-hasher logic
+	            this._doReset();
+	        },
+
+	        /**
+	         * Updates this hasher with a message.
+	         *
+	         * @param {WordArray|string} messageUpdate The message to append.
+	         *
+	         * @return {Hasher} This hasher.
+	         *
+	         * @example
+	         *
+	         *     hasher.update('message');
+	         *     hasher.update(wordArray);
+	         */
+	        update: function (messageUpdate) {
+	            // Append
+	            this._append(messageUpdate);
+
+	            // Update the hash
+	            this._process();
+
+	            // Chainable
+	            return this;
+	        },
+
+	        /**
+	         * Finalizes the hash computation.
+	         * Note that the finalize operation is effectively a destructive, read-once operation.
+	         *
+	         * @param {WordArray|string} messageUpdate (Optional) A final message update.
+	         *
+	         * @return {WordArray} The hash.
+	         *
+	         * @example
+	         *
+	         *     var hash = hasher.finalize();
+	         *     var hash = hasher.finalize('message');
+	         *     var hash = hasher.finalize(wordArray);
+	         */
+	        finalize: function (messageUpdate) {
+	            // Final message update
+	            if (messageUpdate) {
+	                this._append(messageUpdate);
+	            }
+
+	            // Perform concrete-hasher logic
+	            var hash = this._doFinalize();
+
+	            return hash;
+	        },
+
+	        blockSize: 512/32,
+
+	        /**
+	         * Creates a shortcut function to a hasher's object interface.
+	         *
+	         * @param {Hasher} hasher The hasher to create a helper for.
+	         *
+	         * @return {Function} The shortcut function.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
+	         */
+	        _createHelper: function (hasher) {
+	            return function (message, cfg) {
+	                return new hasher.init(cfg).finalize(message);
+	            };
+	        },
+
+	        /**
+	         * Creates a shortcut function to the HMAC's object interface.
+	         *
+	         * @param {Hasher} hasher The hasher to use in this HMAC helper.
+	         *
+	         * @return {Function} The shortcut function.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
+	         */
+	        _createHmacHelper: function (hasher) {
+	            return function (message, key) {
+	                return new C_algo.HMAC.init(hasher, key).finalize(message);
+	            };
+	        }
+	    });
+
+	    /**
+	     * Algorithm namespace.
+	     */
+	    var C_algo = C.algo = {};
+
+	    return C;
+	}(Math));
+
+
+	(function (undefined) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var Base = C_lib.Base;
+	    var X32WordArray = C_lib.WordArray;
+
+	    /**
+	     * x64 namespace.
+	     */
+	    var C_x64 = C.x64 = {};
+
+	    /**
+	     * A 64-bit word.
+	     */
+	    var X64Word = C_x64.Word = Base.extend({
+	        /**
+	         * Initializes a newly created 64-bit word.
+	         *
+	         * @param {number} high The high 32 bits.
+	         * @param {number} low The low 32 bits.
+	         *
+	         * @example
+	         *
+	         *     var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607);
+	         */
+	        init: function (high, low) {
+	            this.high = high;
+	            this.low = low;
+	        }
+
+	        /**
+	         * Bitwise NOTs this word.
+	         *
+	         * @return {X64Word} A new x64-Word object after negating.
+	         *
+	         * @example
+	         *
+	         *     var negated = x64Word.not();
+	         */
+	        // not: function () {
+	            // var high = ~this.high;
+	            // var low = ~this.low;
+
+	            // return X64Word.create(high, low);
+	        // },
+
+	        /**
+	         * Bitwise ANDs this word with the passed word.
+	         *
+	         * @param {X64Word} word The x64-Word to AND with this word.
+	         *
+	         * @return {X64Word} A new x64-Word object after ANDing.
+	         *
+	         * @example
+	         *
+	         *     var anded = x64Word.and(anotherX64Word);
+	         */
+	        // and: function (word) {
+	            // var high = this.high & word.high;
+	            // var low = this.low & word.low;
+
+	            // return X64Word.create(high, low);
+	        // },
+
+	        /**
+	         * Bitwise ORs this word with the passed word.
+	         *
+	         * @param {X64Word} word The x64-Word to OR with this word.
+	         *
+	         * @return {X64Word} A new x64-Word object after ORing.
+	         *
+	         * @example
+	         *
+	         *     var ored = x64Word.or(anotherX64Word);
+	         */
+	        // or: function (word) {
+	            // var high = this.high | word.high;
+	            // var low = this.low | word.low;
+
+	            // return X64Word.create(high, low);
+	        // },
+
+	        /**
+	         * Bitwise XORs this word with the passed word.
+	         *
+	         * @param {X64Word} word The x64-Word to XOR with this word.
+	         *
+	         * @return {X64Word} A new x64-Word object after XORing.
+	         *
+	         * @example
+	         *
+	         *     var xored = x64Word.xor(anotherX64Word);
+	         */
+	        // xor: function (word) {
+	            // var high = this.high ^ word.high;
+	            // var low = this.low ^ word.low;
+
+	            // return X64Word.create(high, low);
+	        // },
+
+	        /**
+	         * Shifts this word n bits to the left.
+	         *
+	         * @param {number} n The number of bits to shift.
+	         *
+	         * @return {X64Word} A new x64-Word object after shifting.
+	         *
+	         * @example
+	         *
+	         *     var shifted = x64Word.shiftL(25);
+	         */
+	        // shiftL: function (n) {
+	            // if (n < 32) {
+	                // var high = (this.high << n) | (this.low >>> (32 - n));
+	                // var low = this.low << n;
+	            // } else {
+	                // var high = this.low << (n - 32);
+	                // var low = 0;
+	            // }
+
+	            // return X64Word.create(high, low);
+	        // },
+
+	        /**
+	         * Shifts this word n bits to the right.
+	         *
+	         * @param {number} n The number of bits to shift.
+	         *
+	         * @return {X64Word} A new x64-Word object after shifting.
+	         *
+	         * @example
+	         *
+	         *     var shifted = x64Word.shiftR(7);
+	         */
+	        // shiftR: function (n) {
+	            // if (n < 32) {
+	                // var low = (this.low >>> n) | (this.high << (32 - n));
+	                // var high = this.high >>> n;
+	            // } else {
+	                // var low = this.high >>> (n - 32);
+	                // var high = 0;
+	            // }
+
+	            // return X64Word.create(high, low);
+	        // },
+
+	        /**
+	         * Rotates this word n bits to the left.
+	         *
+	         * @param {number} n The number of bits to rotate.
+	         *
+	         * @return {X64Word} A new x64-Word object after rotating.
+	         *
+	         * @example
+	         *
+	         *     var rotated = x64Word.rotL(25);
+	         */
+	        // rotL: function (n) {
+	            // return this.shiftL(n).or(this.shiftR(64 - n));
+	        // },
+
+	        /**
+	         * Rotates this word n bits to the right.
+	         *
+	         * @param {number} n The number of bits to rotate.
+	         *
+	         * @return {X64Word} A new x64-Word object after rotating.
+	         *
+	         * @example
+	         *
+	         *     var rotated = x64Word.rotR(7);
+	         */
+	        // rotR: function (n) {
+	            // return this.shiftR(n).or(this.shiftL(64 - n));
+	        // },
+
+	        /**
+	         * Adds this word with the passed word.
+	         *
+	         * @param {X64Word} word The x64-Word to add with this word.
+	         *
+	         * @return {X64Word} A new x64-Word object after adding.
+	         *
+	         * @example
+	         *
+	         *     var added = x64Word.add(anotherX64Word);
+	         */
+	        // add: function (word) {
+	            // var low = (this.low + word.low) | 0;
+	            // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0;
+	            // var high = (this.high + word.high + carry) | 0;
+
+	            // return X64Word.create(high, low);
+	        // }
+	    });
+
+	    /**
+	     * An array of 64-bit words.
+	     *
+	     * @property {Array} words The array of CryptoJS.x64.Word objects.
+	     * @property {number} sigBytes The number of significant bytes in this word array.
+	     */
+	    var X64WordArray = C_x64.WordArray = Base.extend({
+	        /**
+	         * Initializes a newly created word array.
+	         *
+	         * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects.
+	         * @param {number} sigBytes (Optional) The number of significant bytes in the words.
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.x64.WordArray.create();
+	         *
+	         *     var wordArray = CryptoJS.x64.WordArray.create([
+	         *         CryptoJS.x64.Word.create(0x00010203, 0x04050607),
+	         *         CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
+	         *     ]);
+	         *
+	         *     var wordArray = CryptoJS.x64.WordArray.create([
+	         *         CryptoJS.x64.Word.create(0x00010203, 0x04050607),
+	         *         CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
+	         *     ], 10);
+	         */
+	        init: function (words, sigBytes) {
+	            words = this.words = words || [];
+
+	            if (sigBytes != undefined) {
+	                this.sigBytes = sigBytes;
+	            } else {
+	                this.sigBytes = words.length * 8;
+	            }
+	        },
+
+	        /**
+	         * Converts this 64-bit word array to a 32-bit word array.
+	         *
+	         * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array.
+	         *
+	         * @example
+	         *
+	         *     var x32WordArray = x64WordArray.toX32();
+	         */
+	        toX32: function () {
+	            // Shortcuts
+	            var x64Words = this.words;
+	            var x64WordsLength = x64Words.length;
+
+	            // Convert
+	            var x32Words = [];
+	            for (var i = 0; i < x64WordsLength; i++) {
+	                var x64Word = x64Words[i];
+	                x32Words.push(x64Word.high);
+	                x32Words.push(x64Word.low);
+	            }
+
+	            return X32WordArray.create(x32Words, this.sigBytes);
+	        },
+
+	        /**
+	         * Creates a copy of this word array.
+	         *
+	         * @return {X64WordArray} The clone.
+	         *
+	         * @example
+	         *
+	         *     var clone = x64WordArray.clone();
+	         */
+	        clone: function () {
+	            var clone = Base.clone.call(this);
+
+	            // Clone "words" array
+	            var words = clone.words = this.words.slice(0);
+
+	            // Clone each X64Word object
+	            var wordsLength = words.length;
+	            for (var i = 0; i < wordsLength; i++) {
+	                words[i] = words[i].clone();
+	            }
+
+	            return clone;
+	        }
+	    });
+	}());
+
+
+	(function () {
+	    // Check if typed arrays are supported
+	    if (typeof ArrayBuffer != 'function') {
+	        return;
+	    }
+
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+
+	    // Reference original init
+	    var superInit = WordArray.init;
+
+	    // Augment WordArray.init to handle typed arrays
+	    var subInit = WordArray.init = function (typedArray) {
+	        // Convert buffers to uint8
+	        if (typedArray instanceof ArrayBuffer) {
+	            typedArray = new Uint8Array(typedArray);
+	        }
+
+	        // Convert other array views to uint8
+	        if (
+	            typedArray instanceof Int8Array ||
+	            (typeof Uint8ClampedArray !== "undefined" && typedArray instanceof Uint8ClampedArray) ||
+	            typedArray instanceof Int16Array ||
+	            typedArray instanceof Uint16Array ||
+	            typedArray instanceof Int32Array ||
+	            typedArray instanceof Uint32Array ||
+	            typedArray instanceof Float32Array ||
+	            typedArray instanceof Float64Array
+	        ) {
+	            typedArray = new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength);
+	        }
+
+	        // Handle Uint8Array
+	        if (typedArray instanceof Uint8Array) {
+	            // Shortcut
+	            var typedArrayByteLength = typedArray.byteLength;
+
+	            // Extract bytes
+	            var words = [];
+	            for (var i = 0; i < typedArrayByteLength; i++) {
+	                words[i >>> 2] |= typedArray[i] << (24 - (i % 4) * 8);
+	            }
+
+	            // Initialize this word array
+	            superInit.call(this, words, typedArrayByteLength);
+	        } else {
+	            // Else call normal init
+	            superInit.apply(this, arguments);
+	        }
+	    };
+
+	    subInit.prototype = WordArray;
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var C_enc = C.enc;
+
+	    /**
+	     * UTF-16 BE encoding strategy.
+	     */
+	    var Utf16BE = C_enc.Utf16 = C_enc.Utf16BE = {
+	        /**
+	         * Converts a word array to a UTF-16 BE string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @return {string} The UTF-16 BE string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var utf16String = CryptoJS.enc.Utf16.stringify(wordArray);
+	         */
+	        stringify: function (wordArray) {
+	            // Shortcuts
+	            var words = wordArray.words;
+	            var sigBytes = wordArray.sigBytes;
+
+	            // Convert
+	            var utf16Chars = [];
+	            for (var i = 0; i < sigBytes; i += 2) {
+	                var codePoint = (words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff;
+	                utf16Chars.push(String.fromCharCode(codePoint));
+	            }
+
+	            return utf16Chars.join('');
+	        },
+
+	        /**
+	         * Converts a UTF-16 BE string to a word array.
+	         *
+	         * @param {string} utf16Str The UTF-16 BE string.
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Utf16.parse(utf16String);
+	         */
+	        parse: function (utf16Str) {
+	            // Shortcut
+	            var utf16StrLength = utf16Str.length;
+
+	            // Convert
+	            var words = [];
+	            for (var i = 0; i < utf16StrLength; i++) {
+	                words[i >>> 1] |= utf16Str.charCodeAt(i) << (16 - (i % 2) * 16);
+	            }
+
+	            return WordArray.create(words, utf16StrLength * 2);
+	        }
+	    };
+
+	    /**
+	     * UTF-16 LE encoding strategy.
+	     */
+	    C_enc.Utf16LE = {
+	        /**
+	         * Converts a word array to a UTF-16 LE string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @return {string} The UTF-16 LE string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var utf16Str = CryptoJS.enc.Utf16LE.stringify(wordArray);
+	         */
+	        stringify: function (wordArray) {
+	            // Shortcuts
+	            var words = wordArray.words;
+	            var sigBytes = wordArray.sigBytes;
+
+	            // Convert
+	            var utf16Chars = [];
+	            for (var i = 0; i < sigBytes; i += 2) {
+	                var codePoint = swapEndian((words[i >>> 2] >>> (16 - (i % 4) * 8)) & 0xffff);
+	                utf16Chars.push(String.fromCharCode(codePoint));
+	            }
+
+	            return utf16Chars.join('');
+	        },
+
+	        /**
+	         * Converts a UTF-16 LE string to a word array.
+	         *
+	         * @param {string} utf16Str The UTF-16 LE string.
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Utf16LE.parse(utf16Str);
+	         */
+	        parse: function (utf16Str) {
+	            // Shortcut
+	            var utf16StrLength = utf16Str.length;
+
+	            // Convert
+	            var words = [];
+	            for (var i = 0; i < utf16StrLength; i++) {
+	                words[i >>> 1] |= swapEndian(utf16Str.charCodeAt(i) << (16 - (i % 2) * 16));
+	            }
+
+	            return WordArray.create(words, utf16StrLength * 2);
+	        }
+	    };
+
+	    function swapEndian(word) {
+	        return ((word << 8) & 0xff00ff00) | ((word >>> 8) & 0x00ff00ff);
+	    }
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var C_enc = C.enc;
+
+	    /**
+	     * Base64 encoding strategy.
+	     */
+	    var Base64 = C_enc.Base64 = {
+	        /**
+	         * Converts a word array to a Base64 string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @return {string} The Base64 string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);
+	         */
+	        stringify: function (wordArray) {
+	            // Shortcuts
+	            var words = wordArray.words;
+	            var sigBytes = wordArray.sigBytes;
+	            var map = this._map;
+
+	            // Clamp excess bits
+	            wordArray.clamp();
+
+	            // Convert
+	            var base64Chars = [];
+	            for (var i = 0; i < sigBytes; i += 3) {
+	                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;
+	                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
+	                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
+
+	                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
+
+	                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
+	                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
+	                }
+	            }
+
+	            // Add padding
+	            var paddingChar = map.charAt(64);
+	            if (paddingChar) {
+	                while (base64Chars.length % 4) {
+	                    base64Chars.push(paddingChar);
+	                }
+	            }
+
+	            return base64Chars.join('');
+	        },
+
+	        /**
+	         * Converts a Base64 string to a word array.
+	         *
+	         * @param {string} base64Str The Base64 string.
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Base64.parse(base64String);
+	         */
+	        parse: function (base64Str) {
+	            // Shortcuts
+	            var base64StrLength = base64Str.length;
+	            var map = this._map;
+	            var reverseMap = this._reverseMap;
+
+	            if (!reverseMap) {
+	                    reverseMap = this._reverseMap = [];
+	                    for (var j = 0; j < map.length; j++) {
+	                        reverseMap[map.charCodeAt(j)] = j;
+	                    }
+	            }
+
+	            // Ignore padding
+	            var paddingChar = map.charAt(64);
+	            if (paddingChar) {
+	                var paddingIndex = base64Str.indexOf(paddingChar);
+	                if (paddingIndex !== -1) {
+	                    base64StrLength = paddingIndex;
+	                }
+	            }
+
+	            // Convert
+	            return parseLoop(base64Str, base64StrLength, reverseMap);
+
+	        },
+
+	        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
+	    };
+
+	    function parseLoop(base64Str, base64StrLength, reverseMap) {
+	      var words = [];
+	      var nBytes = 0;
+	      for (var i = 0; i < base64StrLength; i++) {
+	          if (i % 4) {
+	              var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
+	              var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
+	              var bitsCombined = bits1 | bits2;
+	              words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
+	              nBytes++;
+	          }
+	      }
+	      return WordArray.create(words, nBytes);
+	    }
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var C_enc = C.enc;
+
+	    /**
+	     * Base64url encoding strategy.
+	     */
+	    var Base64url = C_enc.Base64url = {
+	        /**
+	         * Converts a word array to a Base64url string.
+	         *
+	         * @param {WordArray} wordArray The word array.
+	         *
+	         * @param {boolean} urlSafe Whether to use url safe
+	         *
+	         * @return {string} The Base64url string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var base64String = CryptoJS.enc.Base64url.stringify(wordArray);
+	         */
+	        stringify: function (wordArray, urlSafe=true) {
+	            // Shortcuts
+	            var words = wordArray.words;
+	            var sigBytes = wordArray.sigBytes;
+	            var map = urlSafe ? this._safe_map : this._map;
+
+	            // Clamp excess bits
+	            wordArray.clamp();
+
+	            // Convert
+	            var base64Chars = [];
+	            for (var i = 0; i < sigBytes; i += 3) {
+	                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;
+	                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
+	                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
+
+	                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
+
+	                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
+	                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
+	                }
+	            }
+
+	            // Add padding
+	            var paddingChar = map.charAt(64);
+	            if (paddingChar) {
+	                while (base64Chars.length % 4) {
+	                    base64Chars.push(paddingChar);
+	                }
+	            }
+
+	            return base64Chars.join('');
+	        },
+
+	        /**
+	         * Converts a Base64url string to a word array.
+	         *
+	         * @param {string} base64Str The Base64url string.
+	         *
+	         * @param {boolean} urlSafe Whether to use url safe
+	         *
+	         * @return {WordArray} The word array.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var wordArray = CryptoJS.enc.Base64url.parse(base64String);
+	         */
+	        parse: function (base64Str, urlSafe=true) {
+	            // Shortcuts
+	            var base64StrLength = base64Str.length;
+	            var map = urlSafe ? this._safe_map : this._map;
+	            var reverseMap = this._reverseMap;
+
+	            if (!reverseMap) {
+	                reverseMap = this._reverseMap = [];
+	                for (var j = 0; j < map.length; j++) {
+	                    reverseMap[map.charCodeAt(j)] = j;
+	                }
+	            }
+
+	            // Ignore padding
+	            var paddingChar = map.charAt(64);
+	            if (paddingChar) {
+	                var paddingIndex = base64Str.indexOf(paddingChar);
+	                if (paddingIndex !== -1) {
+	                    base64StrLength = paddingIndex;
+	                }
+	            }
+
+	            // Convert
+	            return parseLoop(base64Str, base64StrLength, reverseMap);
+
+	        },
+
+	        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
+	        _safe_map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
+	    };
+
+	    function parseLoop(base64Str, base64StrLength, reverseMap) {
+	        var words = [];
+	        var nBytes = 0;
+	        for (var i = 0; i < base64StrLength; i++) {
+	            if (i % 4) {
+	                var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
+	                var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
+	                var bitsCombined = bits1 | bits2;
+	                words[nBytes >>> 2] |= bitsCombined << (24 - (nBytes % 4) * 8);
+	                nBytes++;
+	            }
+	        }
+	        return WordArray.create(words, nBytes);
+	    }
+	}());
+
+	(function (Math) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var Hasher = C_lib.Hasher;
+	    var C_algo = C.algo;
+
+	    // Constants table
+	    var T = [];
+
+	    // Compute constants
+	    (function () {
+	        for (var i = 0; i < 64; i++) {
+	            T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
+	        }
+	    }());
+
+	    /**
+	     * MD5 hash algorithm.
+	     */
+	    var MD5 = C_algo.MD5 = Hasher.extend({
+	        _doReset: function () {
+	            this._hash = new WordArray.init([
+	                0x67452301, 0xefcdab89,
+	                0x98badcfe, 0x10325476
+	            ]);
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Swap endian
+	            for (var i = 0; i < 16; i++) {
+	                // Shortcuts
+	                var offset_i = offset + i;
+	                var M_offset_i = M[offset_i];
+
+	                M[offset_i] = (
+	                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |
+	                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)
+	                );
+	            }
+
+	            // Shortcuts
+	            var H = this._hash.words;
+
+	            var M_offset_0  = M[offset + 0];
+	            var M_offset_1  = M[offset + 1];
+	            var M_offset_2  = M[offset + 2];
+	            var M_offset_3  = M[offset + 3];
+	            var M_offset_4  = M[offset + 4];
+	            var M_offset_5  = M[offset + 5];
+	            var M_offset_6  = M[offset + 6];
+	            var M_offset_7  = M[offset + 7];
+	            var M_offset_8  = M[offset + 8];
+	            var M_offset_9  = M[offset + 9];
+	            var M_offset_10 = M[offset + 10];
+	            var M_offset_11 = M[offset + 11];
+	            var M_offset_12 = M[offset + 12];
+	            var M_offset_13 = M[offset + 13];
+	            var M_offset_14 = M[offset + 14];
+	            var M_offset_15 = M[offset + 15];
+
+	            // Working varialbes
+	            var a = H[0];
+	            var b = H[1];
+	            var c = H[2];
+	            var d = H[3];
+
+	            // Computation
+	            a = FF(a, b, c, d, M_offset_0,  7,  T[0]);
+	            d = FF(d, a, b, c, M_offset_1,  12, T[1]);
+	            c = FF(c, d, a, b, M_offset_2,  17, T[2]);
+	            b = FF(b, c, d, a, M_offset_3,  22, T[3]);
+	            a = FF(a, b, c, d, M_offset_4,  7,  T[4]);
+	            d = FF(d, a, b, c, M_offset_5,  12, T[5]);
+	            c = FF(c, d, a, b, M_offset_6,  17, T[6]);
+	            b = FF(b, c, d, a, M_offset_7,  22, T[7]);
+	            a = FF(a, b, c, d, M_offset_8,  7,  T[8]);
+	            d = FF(d, a, b, c, M_offset_9,  12, T[9]);
+	            c = FF(c, d, a, b, M_offset_10, 17, T[10]);
+	            b = FF(b, c, d, a, M_offset_11, 22, T[11]);
+	            a = FF(a, b, c, d, M_offset_12, 7,  T[12]);
+	            d = FF(d, a, b, c, M_offset_13, 12, T[13]);
+	            c = FF(c, d, a, b, M_offset_14, 17, T[14]);
+	            b = FF(b, c, d, a, M_offset_15, 22, T[15]);
+
+	            a = GG(a, b, c, d, M_offset_1,  5,  T[16]);
+	            d = GG(d, a, b, c, M_offset_6,  9,  T[17]);
+	            c = GG(c, d, a, b, M_offset_11, 14, T[18]);
+	            b = GG(b, c, d, a, M_offset_0,  20, T[19]);
+	            a = GG(a, b, c, d, M_offset_5,  5,  T[20]);
+	            d = GG(d, a, b, c, M_offset_10, 9,  T[21]);
+	            c = GG(c, d, a, b, M_offset_15, 14, T[22]);
+	            b = GG(b, c, d, a, M_offset_4,  20, T[23]);
+	            a = GG(a, b, c, d, M_offset_9,  5,  T[24]);
+	            d = GG(d, a, b, c, M_offset_14, 9,  T[25]);
+	            c = GG(c, d, a, b, M_offset_3,  14, T[26]);
+	            b = GG(b, c, d, a, M_offset_8,  20, T[27]);
+	            a = GG(a, b, c, d, M_offset_13, 5,  T[28]);
+	            d = GG(d, a, b, c, M_offset_2,  9,  T[29]);
+	            c = GG(c, d, a, b, M_offset_7,  14, T[30]);
+	            b = GG(b, c, d, a, M_offset_12, 20, T[31]);
+
+	            a = HH(a, b, c, d, M_offset_5,  4,  T[32]);
+	            d = HH(d, a, b, c, M_offset_8,  11, T[33]);
+	            c = HH(c, d, a, b, M_offset_11, 16, T[34]);
+	            b = HH(b, c, d, a, M_offset_14, 23, T[35]);
+	            a = HH(a, b, c, d, M_offset_1,  4,  T[36]);
+	            d = HH(d, a, b, c, M_offset_4,  11, T[37]);
+	            c = HH(c, d, a, b, M_offset_7,  16, T[38]);
+	            b = HH(b, c, d, a, M_offset_10, 23, T[39]);
+	            a = HH(a, b, c, d, M_offset_13, 4,  T[40]);
+	            d = HH(d, a, b, c, M_offset_0,  11, T[41]);
+	            c = HH(c, d, a, b, M_offset_3,  16, T[42]);
+	            b = HH(b, c, d, a, M_offset_6,  23, T[43]);
+	            a = HH(a, b, c, d, M_offset_9,  4,  T[44]);
+	            d = HH(d, a, b, c, M_offset_12, 11, T[45]);
+	            c = HH(c, d, a, b, M_offset_15, 16, T[46]);
+	            b = HH(b, c, d, a, M_offset_2,  23, T[47]);
+
+	            a = II(a, b, c, d, M_offset_0,  6,  T[48]);
+	            d = II(d, a, b, c, M_offset_7,  10, T[49]);
+	            c = II(c, d, a, b, M_offset_14, 15, T[50]);
+	            b = II(b, c, d, a, M_offset_5,  21, T[51]);
+	            a = II(a, b, c, d, M_offset_12, 6,  T[52]);
+	            d = II(d, a, b, c, M_offset_3,  10, T[53]);
+	            c = II(c, d, a, b, M_offset_10, 15, T[54]);
+	            b = II(b, c, d, a, M_offset_1,  21, T[55]);
+	            a = II(a, b, c, d, M_offset_8,  6,  T[56]);
+	            d = II(d, a, b, c, M_offset_15, 10, T[57]);
+	            c = II(c, d, a, b, M_offset_6,  15, T[58]);
+	            b = II(b, c, d, a, M_offset_13, 21, T[59]);
+	            a = II(a, b, c, d, M_offset_4,  6,  T[60]);
+	            d = II(d, a, b, c, M_offset_11, 10, T[61]);
+	            c = II(c, d, a, b, M_offset_2,  15, T[62]);
+	            b = II(b, c, d, a, M_offset_9,  21, T[63]);
+
+	            // Intermediate hash value
+	            H[0] = (H[0] + a) | 0;
+	            H[1] = (H[1] + b) | 0;
+	            H[2] = (H[2] + c) | 0;
+	            H[3] = (H[3] + d) | 0;
+	        },
+
+	        _doFinalize: function () {
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+
+	            var nBitsTotal = this._nDataBytes * 8;
+	            var nBitsLeft = data.sigBytes * 8;
+
+	            // Add padding
+	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
+
+	            var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
+	            var nBitsTotalL = nBitsTotal;
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
+	                (((nBitsTotalH << 8)  | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
+	                (((nBitsTotalH << 24) | (nBitsTotalH >>> 8))  & 0xff00ff00)
+	            );
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
+	                (((nBitsTotalL << 8)  | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
+	                (((nBitsTotalL << 24) | (nBitsTotalL >>> 8))  & 0xff00ff00)
+	            );
+
+	            data.sigBytes = (dataWords.length + 1) * 4;
+
+	            // Hash final blocks
+	            this._process();
+
+	            // Shortcuts
+	            var hash = this._hash;
+	            var H = hash.words;
+
+	            // Swap endian
+	            for (var i = 0; i < 4; i++) {
+	                // Shortcut
+	                var H_i = H[i];
+
+	                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |
+	                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);
+	            }
+
+	            // Return final computed hash
+	            return hash;
+	        },
+
+	        clone: function () {
+	            var clone = Hasher.clone.call(this);
+	            clone._hash = this._hash.clone();
+
+	            return clone;
+	        }
+	    });
+
+	    function FF(a, b, c, d, x, s, t) {
+	        var n = a + ((b & c) | (~b & d)) + x + t;
+	        return ((n << s) | (n >>> (32 - s))) + b;
+	    }
+
+	    function GG(a, b, c, d, x, s, t) {
+	        var n = a + ((b & d) | (c & ~d)) + x + t;
+	        return ((n << s) | (n >>> (32 - s))) + b;
+	    }
+
+	    function HH(a, b, c, d, x, s, t) {
+	        var n = a + (b ^ c ^ d) + x + t;
+	        return ((n << s) | (n >>> (32 - s))) + b;
+	    }
+
+	    function II(a, b, c, d, x, s, t) {
+	        var n = a + (c ^ (b | ~d)) + x + t;
+	        return ((n << s) | (n >>> (32 - s))) + b;
+	    }
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.MD5('message');
+	     *     var hash = CryptoJS.MD5(wordArray);
+	     */
+	    C.MD5 = Hasher._createHelper(MD5);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacMD5(message, key);
+	     */
+	    C.HmacMD5 = Hasher._createHmacHelper(MD5);
+	}(Math));
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var Hasher = C_lib.Hasher;
+	    var C_algo = C.algo;
+
+	    // Reusable object
+	    var W = [];
+
+	    /**
+	     * SHA-1 hash algorithm.
+	     */
+	    var SHA1 = C_algo.SHA1 = Hasher.extend({
+	        _doReset: function () {
+	            this._hash = new WordArray.init([
+	                0x67452301, 0xefcdab89,
+	                0x98badcfe, 0x10325476,
+	                0xc3d2e1f0
+	            ]);
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Shortcut
+	            var H = this._hash.words;
+
+	            // Working variables
+	            var a = H[0];
+	            var b = H[1];
+	            var c = H[2];
+	            var d = H[3];
+	            var e = H[4];
+
+	            // Computation
+	            for (var i = 0; i < 80; i++) {
+	                if (i < 16) {
+	                    W[i] = M[offset + i] | 0;
+	                } else {
+	                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
+	                    W[i] = (n << 1) | (n >>> 31);
+	                }
+
+	                var t = ((a << 5) | (a >>> 27)) + e + W[i];
+	                if (i < 20) {
+	                    t += ((b & c) | (~b & d)) + 0x5a827999;
+	                } else if (i < 40) {
+	                    t += (b ^ c ^ d) + 0x6ed9eba1;
+	                } else if (i < 60) {
+	                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
+	                } else /* if (i < 80) */ {
+	                    t += (b ^ c ^ d) - 0x359d3e2a;
+	                }
+
+	                e = d;
+	                d = c;
+	                c = (b << 30) | (b >>> 2);
+	                b = a;
+	                a = t;
+	            }
+
+	            // Intermediate hash value
+	            H[0] = (H[0] + a) | 0;
+	            H[1] = (H[1] + b) | 0;
+	            H[2] = (H[2] + c) | 0;
+	            H[3] = (H[3] + d) | 0;
+	            H[4] = (H[4] + e) | 0;
+	        },
+
+	        _doFinalize: function () {
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+
+	            var nBitsTotal = this._nDataBytes * 8;
+	            var nBitsLeft = data.sigBytes * 8;
+
+	            // Add padding
+	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
+	            data.sigBytes = dataWords.length * 4;
+
+	            // Hash final blocks
+	            this._process();
+
+	            // Return final computed hash
+	            return this._hash;
+	        },
+
+	        clone: function () {
+	            var clone = Hasher.clone.call(this);
+	            clone._hash = this._hash.clone();
+
+	            return clone;
+	        }
+	    });
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.SHA1('message');
+	     *     var hash = CryptoJS.SHA1(wordArray);
+	     */
+	    C.SHA1 = Hasher._createHelper(SHA1);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacSHA1(message, key);
+	     */
+	    C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
+	}());
+
+
+	(function (Math) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var Hasher = C_lib.Hasher;
+	    var C_algo = C.algo;
+
+	    // Initialization and round constants tables
+	    var H = [];
+	    var K = [];
+
+	    // Compute constants
+	    (function () {
+	        function isPrime(n) {
+	            var sqrtN = Math.sqrt(n);
+	            for (var factor = 2; factor <= sqrtN; factor++) {
+	                if (!(n % factor)) {
+	                    return false;
+	                }
+	            }
+
+	            return true;
+	        }
+
+	        function getFractionalBits(n) {
+	            return ((n - (n | 0)) * 0x100000000) | 0;
+	        }
+
+	        var n = 2;
+	        var nPrime = 0;
+	        while (nPrime < 64) {
+	            if (isPrime(n)) {
+	                if (nPrime < 8) {
+	                    H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
+	                }
+	                K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
+
+	                nPrime++;
+	            }
+
+	            n++;
+	        }
+	    }());
+
+	    // Reusable object
+	    var W = [];
+
+	    /**
+	     * SHA-256 hash algorithm.
+	     */
+	    var SHA256 = C_algo.SHA256 = Hasher.extend({
+	        _doReset: function () {
+	            this._hash = new WordArray.init(H.slice(0));
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Shortcut
+	            var H = this._hash.words;
+
+	            // Working variables
+	            var a = H[0];
+	            var b = H[1];
+	            var c = H[2];
+	            var d = H[3];
+	            var e = H[4];
+	            var f = H[5];
+	            var g = H[6];
+	            var h = H[7];
+
+	            // Computation
+	            for (var i = 0; i < 64; i++) {
+	                if (i < 16) {
+	                    W[i] = M[offset + i] | 0;
+	                } else {
+	                    var gamma0x = W[i - 15];
+	                    var gamma0  = ((gamma0x << 25) | (gamma0x >>> 7))  ^
+	                                  ((gamma0x << 14) | (gamma0x >>> 18)) ^
+	                                   (gamma0x >>> 3);
+
+	                    var gamma1x = W[i - 2];
+	                    var gamma1  = ((gamma1x << 15) | (gamma1x >>> 17)) ^
+	                                  ((gamma1x << 13) | (gamma1x >>> 19)) ^
+	                                   (gamma1x >>> 10);
+
+	                    W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
+	                }
+
+	                var ch  = (e & f) ^ (~e & g);
+	                var maj = (a & b) ^ (a & c) ^ (b & c);
+
+	                var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
+	                var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7)  | (e >>> 25));
+
+	                var t1 = h + sigma1 + ch + K[i] + W[i];
+	                var t2 = sigma0 + maj;
+
+	                h = g;
+	                g = f;
+	                f = e;
+	                e = (d + t1) | 0;
+	                d = c;
+	                c = b;
+	                b = a;
+	                a = (t1 + t2) | 0;
+	            }
+
+	            // Intermediate hash value
+	            H[0] = (H[0] + a) | 0;
+	            H[1] = (H[1] + b) | 0;
+	            H[2] = (H[2] + c) | 0;
+	            H[3] = (H[3] + d) | 0;
+	            H[4] = (H[4] + e) | 0;
+	            H[5] = (H[5] + f) | 0;
+	            H[6] = (H[6] + g) | 0;
+	            H[7] = (H[7] + h) | 0;
+	        },
+
+	        _doFinalize: function () {
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+
+	            var nBitsTotal = this._nDataBytes * 8;
+	            var nBitsLeft = data.sigBytes * 8;
+
+	            // Add padding
+	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
+	            data.sigBytes = dataWords.length * 4;
+
+	            // Hash final blocks
+	            this._process();
+
+	            // Return final computed hash
+	            return this._hash;
+	        },
+
+	        clone: function () {
+	            var clone = Hasher.clone.call(this);
+	            clone._hash = this._hash.clone();
+
+	            return clone;
+	        }
+	    });
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.SHA256('message');
+	     *     var hash = CryptoJS.SHA256(wordArray);
+	     */
+	    C.SHA256 = Hasher._createHelper(SHA256);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacSHA256(message, key);
+	     */
+	    C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
+	}(Math));
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var C_algo = C.algo;
+	    var SHA256 = C_algo.SHA256;
+
+	    /**
+	     * SHA-224 hash algorithm.
+	     */
+	    var SHA224 = C_algo.SHA224 = SHA256.extend({
+	        _doReset: function () {
+	            this._hash = new WordArray.init([
+	                0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+	                0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
+	            ]);
+	        },
+
+	        _doFinalize: function () {
+	            var hash = SHA256._doFinalize.call(this);
+
+	            hash.sigBytes -= 4;
+
+	            return hash;
+	        }
+	    });
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.SHA224('message');
+	     *     var hash = CryptoJS.SHA224(wordArray);
+	     */
+	    C.SHA224 = SHA256._createHelper(SHA224);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacSHA224(message, key);
+	     */
+	    C.HmacSHA224 = SHA256._createHmacHelper(SHA224);
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var Hasher = C_lib.Hasher;
+	    var C_x64 = C.x64;
+	    var X64Word = C_x64.Word;
+	    var X64WordArray = C_x64.WordArray;
+	    var C_algo = C.algo;
+
+	    function X64Word_create() {
+	        return X64Word.create.apply(X64Word, arguments);
+	    }
+
+	    // Constants
+	    var K = [
+	        X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd),
+	        X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc),
+	        X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019),
+	        X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118),
+	        X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe),
+	        X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2),
+	        X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1),
+	        X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694),
+	        X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3),
+	        X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65),
+	        X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483),
+	        X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5),
+	        X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210),
+	        X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4),
+	        X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725),
+	        X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70),
+	        X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926),
+	        X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df),
+	        X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8),
+	        X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b),
+	        X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001),
+	        X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30),
+	        X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910),
+	        X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8),
+	        X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53),
+	        X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8),
+	        X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb),
+	        X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3),
+	        X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60),
+	        X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec),
+	        X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9),
+	        X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b),
+	        X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207),
+	        X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178),
+	        X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6),
+	        X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b),
+	        X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493),
+	        X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c),
+	        X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a),
+	        X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817)
+	    ];
+
+	    // Reusable objects
+	    var W = [];
+	    (function () {
+	        for (var i = 0; i < 80; i++) {
+	            W[i] = X64Word_create();
+	        }
+	    }());
+
+	    /**
+	     * SHA-512 hash algorithm.
+	     */
+	    var SHA512 = C_algo.SHA512 = Hasher.extend({
+	        _doReset: function () {
+	            this._hash = new X64WordArray.init([
+	                new X64Word.init(0x6a09e667, 0xf3bcc908), new X64Word.init(0xbb67ae85, 0x84caa73b),
+	                new X64Word.init(0x3c6ef372, 0xfe94f82b), new X64Word.init(0xa54ff53a, 0x5f1d36f1),
+	                new X64Word.init(0x510e527f, 0xade682d1), new X64Word.init(0x9b05688c, 0x2b3e6c1f),
+	                new X64Word.init(0x1f83d9ab, 0xfb41bd6b), new X64Word.init(0x5be0cd19, 0x137e2179)
+	            ]);
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Shortcuts
+	            var H = this._hash.words;
+
+	            var H0 = H[0];
+	            var H1 = H[1];
+	            var H2 = H[2];
+	            var H3 = H[3];
+	            var H4 = H[4];
+	            var H5 = H[5];
+	            var H6 = H[6];
+	            var H7 = H[7];
+
+	            var H0h = H0.high;
+	            var H0l = H0.low;
+	            var H1h = H1.high;
+	            var H1l = H1.low;
+	            var H2h = H2.high;
+	            var H2l = H2.low;
+	            var H3h = H3.high;
+	            var H3l = H3.low;
+	            var H4h = H4.high;
+	            var H4l = H4.low;
+	            var H5h = H5.high;
+	            var H5l = H5.low;
+	            var H6h = H6.high;
+	            var H6l = H6.low;
+	            var H7h = H7.high;
+	            var H7l = H7.low;
+
+	            // Working variables
+	            var ah = H0h;
+	            var al = H0l;
+	            var bh = H1h;
+	            var bl = H1l;
+	            var ch = H2h;
+	            var cl = H2l;
+	            var dh = H3h;
+	            var dl = H3l;
+	            var eh = H4h;
+	            var el = H4l;
+	            var fh = H5h;
+	            var fl = H5l;
+	            var gh = H6h;
+	            var gl = H6l;
+	            var hh = H7h;
+	            var hl = H7l;
+
+	            // Rounds
+	            for (var i = 0; i < 80; i++) {
+	                var Wil;
+	                var Wih;
+
+	                // Shortcut
+	                var Wi = W[i];
+
+	                // Extend message
+	                if (i < 16) {
+	                    Wih = Wi.high = M[offset + i * 2]     | 0;
+	                    Wil = Wi.low  = M[offset + i * 2 + 1] | 0;
+	                } else {
+	                    // Gamma0
+	                    var gamma0x  = W[i - 15];
+	                    var gamma0xh = gamma0x.high;
+	                    var gamma0xl = gamma0x.low;
+	                    var gamma0h  = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7);
+	                    var gamma0l  = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25));
+
+	                    // Gamma1
+	                    var gamma1x  = W[i - 2];
+	                    var gamma1xh = gamma1x.high;
+	                    var gamma1xl = gamma1x.low;
+	                    var gamma1h  = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6);
+	                    var gamma1l  = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26));
+
+	                    // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
+	                    var Wi7  = W[i - 7];
+	                    var Wi7h = Wi7.high;
+	                    var Wi7l = Wi7.low;
+
+	                    var Wi16  = W[i - 16];
+	                    var Wi16h = Wi16.high;
+	                    var Wi16l = Wi16.low;
+
+	                    Wil = gamma0l + Wi7l;
+	                    Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0);
+	                    Wil = Wil + gamma1l;
+	                    Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0);
+	                    Wil = Wil + Wi16l;
+	                    Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0);
+
+	                    Wi.high = Wih;
+	                    Wi.low  = Wil;
+	                }
+
+	                var chh  = (eh & fh) ^ (~eh & gh);
+	                var chl  = (el & fl) ^ (~el & gl);
+	                var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch);
+	                var majl = (al & bl) ^ (al & cl) ^ (bl & cl);
+
+	                var sigma0h = ((ah >>> 28) | (al << 4))  ^ ((ah << 30)  | (al >>> 2)) ^ ((ah << 25) | (al >>> 7));
+	                var sigma0l = ((al >>> 28) | (ah << 4))  ^ ((al << 30)  | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7));
+	                var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9));
+	                var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9));
+
+	                // t1 = h + sigma1 + ch + K[i] + W[i]
+	                var Ki  = K[i];
+	                var Kih = Ki.high;
+	                var Kil = Ki.low;
+
+	                var t1l = hl + sigma1l;
+	                var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0);
+	                var t1l = t1l + chl;
+	                var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0);
+	                var t1l = t1l + Kil;
+	                var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0);
+	                var t1l = t1l + Wil;
+	                var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0);
+
+	                // t2 = sigma0 + maj
+	                var t2l = sigma0l + majl;
+	                var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0);
+
+	                // Update working variables
+	                hh = gh;
+	                hl = gl;
+	                gh = fh;
+	                gl = fl;
+	                fh = eh;
+	                fl = el;
+	                el = (dl + t1l) | 0;
+	                eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0;
+	                dh = ch;
+	                dl = cl;
+	                ch = bh;
+	                cl = bl;
+	                bh = ah;
+	                bl = al;
+	                al = (t1l + t2l) | 0;
+	                ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0;
+	            }
+
+	            // Intermediate hash value
+	            H0l = H0.low  = (H0l + al);
+	            H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0));
+	            H1l = H1.low  = (H1l + bl);
+	            H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0));
+	            H2l = H2.low  = (H2l + cl);
+	            H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0));
+	            H3l = H3.low  = (H3l + dl);
+	            H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0));
+	            H4l = H4.low  = (H4l + el);
+	            H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0));
+	            H5l = H5.low  = (H5l + fl);
+	            H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0));
+	            H6l = H6.low  = (H6l + gl);
+	            H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0));
+	            H7l = H7.low  = (H7l + hl);
+	            H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0));
+	        },
+
+	        _doFinalize: function () {
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+
+	            var nBitsTotal = this._nDataBytes * 8;
+	            var nBitsLeft = data.sigBytes * 8;
+
+	            // Add padding
+	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
+	            dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 30] = Math.floor(nBitsTotal / 0x100000000);
+	            dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal;
+	            data.sigBytes = dataWords.length * 4;
+
+	            // Hash final blocks
+	            this._process();
+
+	            // Convert hash to 32-bit word array before returning
+	            var hash = this._hash.toX32();
+
+	            // Return final computed hash
+	            return hash;
+	        },
+
+	        clone: function () {
+	            var clone = Hasher.clone.call(this);
+	            clone._hash = this._hash.clone();
+
+	            return clone;
+	        },
+
+	        blockSize: 1024/32
+	    });
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.SHA512('message');
+	     *     var hash = CryptoJS.SHA512(wordArray);
+	     */
+	    C.SHA512 = Hasher._createHelper(SHA512);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacSHA512(message, key);
+	     */
+	    C.HmacSHA512 = Hasher._createHmacHelper(SHA512);
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_x64 = C.x64;
+	    var X64Word = C_x64.Word;
+	    var X64WordArray = C_x64.WordArray;
+	    var C_algo = C.algo;
+	    var SHA512 = C_algo.SHA512;
+
+	    /**
+	     * SHA-384 hash algorithm.
+	     */
+	    var SHA384 = C_algo.SHA384 = SHA512.extend({
+	        _doReset: function () {
+	            this._hash = new X64WordArray.init([
+	                new X64Word.init(0xcbbb9d5d, 0xc1059ed8), new X64Word.init(0x629a292a, 0x367cd507),
+	                new X64Word.init(0x9159015a, 0x3070dd17), new X64Word.init(0x152fecd8, 0xf70e5939),
+	                new X64Word.init(0x67332667, 0xffc00b31), new X64Word.init(0x8eb44a87, 0x68581511),
+	                new X64Word.init(0xdb0c2e0d, 0x64f98fa7), new X64Word.init(0x47b5481d, 0xbefa4fa4)
+	            ]);
+	        },
+
+	        _doFinalize: function () {
+	            var hash = SHA512._doFinalize.call(this);
+
+	            hash.sigBytes -= 16;
+
+	            return hash;
+	        }
+	    });
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.SHA384('message');
+	     *     var hash = CryptoJS.SHA384(wordArray);
+	     */
+	    C.SHA384 = SHA512._createHelper(SHA384);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacSHA384(message, key);
+	     */
+	    C.HmacSHA384 = SHA512._createHmacHelper(SHA384);
+	}());
+
+
+	(function (Math) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var Hasher = C_lib.Hasher;
+	    var C_x64 = C.x64;
+	    var X64Word = C_x64.Word;
+	    var C_algo = C.algo;
+
+	    // Constants tables
+	    var RHO_OFFSETS = [];
+	    var PI_INDEXES  = [];
+	    var ROUND_CONSTANTS = [];
+
+	    // Compute Constants
+	    (function () {
+	        // Compute rho offset constants
+	        var x = 1, y = 0;
+	        for (var t = 0; t < 24; t++) {
+	            RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;
+
+	            var newX = y % 5;
+	            var newY = (2 * x + 3 * y) % 5;
+	            x = newX;
+	            y = newY;
+	        }
+
+	        // Compute pi index constants
+	        for (var x = 0; x < 5; x++) {
+	            for (var y = 0; y < 5; y++) {
+	                PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;
+	            }
+	        }
+
+	        // Compute round constants
+	        var LFSR = 0x01;
+	        for (var i = 0; i < 24; i++) {
+	            var roundConstantMsw = 0;
+	            var roundConstantLsw = 0;
+
+	            for (var j = 0; j < 7; j++) {
+	                if (LFSR & 0x01) {
+	                    var bitPosition = (1 << j) - 1;
+	                    if (bitPosition < 32) {
+	                        roundConstantLsw ^= 1 << bitPosition;
+	                    } else /* if (bitPosition >= 32) */ {
+	                        roundConstantMsw ^= 1 << (bitPosition - 32);
+	                    }
+	                }
+
+	                // Compute next LFSR
+	                if (LFSR & 0x80) {
+	                    // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1
+	                    LFSR = (LFSR << 1) ^ 0x71;
+	                } else {
+	                    LFSR <<= 1;
+	                }
+	            }
+
+	            ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);
+	        }
+	    }());
+
+	    // Reusable objects for temporary values
+	    var T = [];
+	    (function () {
+	        for (var i = 0; i < 25; i++) {
+	            T[i] = X64Word.create();
+	        }
+	    }());
+
+	    /**
+	     * SHA-3 hash algorithm.
+	     */
+	    var SHA3 = C_algo.SHA3 = Hasher.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {number} outputLength
+	         *   The desired number of bits in the output hash.
+	         *   Only values permitted are: 224, 256, 384, 512.
+	         *   Default: 512
+	         */
+	        cfg: Hasher.cfg.extend({
+	            outputLength: 512
+	        }),
+
+	        _doReset: function () {
+	            var state = this._state = []
+	            for (var i = 0; i < 25; i++) {
+	                state[i] = new X64Word.init();
+	            }
+
+	            this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Shortcuts
+	            var state = this._state;
+	            var nBlockSizeLanes = this.blockSize / 2;
+
+	            // Absorb
+	            for (var i = 0; i < nBlockSizeLanes; i++) {
+	                // Shortcuts
+	                var M2i  = M[offset + 2 * i];
+	                var M2i1 = M[offset + 2 * i + 1];
+
+	                // Swap endian
+	                M2i = (
+	                    (((M2i << 8)  | (M2i >>> 24)) & 0x00ff00ff) |
+	                    (((M2i << 24) | (M2i >>> 8))  & 0xff00ff00)
+	                );
+	                M2i1 = (
+	                    (((M2i1 << 8)  | (M2i1 >>> 24)) & 0x00ff00ff) |
+	                    (((M2i1 << 24) | (M2i1 >>> 8))  & 0xff00ff00)
+	                );
+
+	                // Absorb message into state
+	                var lane = state[i];
+	                lane.high ^= M2i1;
+	                lane.low  ^= M2i;
+	            }
+
+	            // Rounds
+	            for (var round = 0; round < 24; round++) {
+	                // Theta
+	                for (var x = 0; x < 5; x++) {
+	                    // Mix column lanes
+	                    var tMsw = 0, tLsw = 0;
+	                    for (var y = 0; y < 5; y++) {
+	                        var lane = state[x + 5 * y];
+	                        tMsw ^= lane.high;
+	                        tLsw ^= lane.low;
+	                    }
+
+	                    // Temporary values
+	                    var Tx = T[x];
+	                    Tx.high = tMsw;
+	                    Tx.low  = tLsw;
+	                }
+	                for (var x = 0; x < 5; x++) {
+	                    // Shortcuts
+	                    var Tx4 = T[(x + 4) % 5];
+	                    var Tx1 = T[(x + 1) % 5];
+	                    var Tx1Msw = Tx1.high;
+	                    var Tx1Lsw = Tx1.low;
+
+	                    // Mix surrounding columns
+	                    var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));
+	                    var tLsw = Tx4.low  ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));
+	                    for (var y = 0; y < 5; y++) {
+	                        var lane = state[x + 5 * y];
+	                        lane.high ^= tMsw;
+	                        lane.low  ^= tLsw;
+	                    }
+	                }
+
+	                // Rho Pi
+	                for (var laneIndex = 1; laneIndex < 25; laneIndex++) {
+	                    var tMsw;
+	                    var tLsw;
+
+	                    // Shortcuts
+	                    var lane = state[laneIndex];
+	                    var laneMsw = lane.high;
+	                    var laneLsw = lane.low;
+	                    var rhoOffset = RHO_OFFSETS[laneIndex];
+
+	                    // Rotate lanes
+	                    if (rhoOffset < 32) {
+	                        tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));
+	                        tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));
+	                    } else /* if (rhoOffset >= 32) */ {
+	                        tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));
+	                        tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));
+	                    }
+
+	                    // Transpose lanes
+	                    var TPiLane = T[PI_INDEXES[laneIndex]];
+	                    TPiLane.high = tMsw;
+	                    TPiLane.low  = tLsw;
+	                }
+
+	                // Rho pi at x = y = 0
+	                var T0 = T[0];
+	                var state0 = state[0];
+	                T0.high = state0.high;
+	                T0.low  = state0.low;
+
+	                // Chi
+	                for (var x = 0; x < 5; x++) {
+	                    for (var y = 0; y < 5; y++) {
+	                        // Shortcuts
+	                        var laneIndex = x + 5 * y;
+	                        var lane = state[laneIndex];
+	                        var TLane = T[laneIndex];
+	                        var Tx1Lane = T[((x + 1) % 5) + 5 * y];
+	                        var Tx2Lane = T[((x + 2) % 5) + 5 * y];
+
+	                        // Mix rows
+	                        lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);
+	                        lane.low  = TLane.low  ^ (~Tx1Lane.low  & Tx2Lane.low);
+	                    }
+	                }
+
+	                // Iota
+	                var lane = state[0];
+	                var roundConstant = ROUND_CONSTANTS[round];
+	                lane.high ^= roundConstant.high;
+	                lane.low  ^= roundConstant.low;
+	            }
+	        },
+
+	        _doFinalize: function () {
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+	            var nBitsTotal = this._nDataBytes * 8;
+	            var nBitsLeft = data.sigBytes * 8;
+	            var blockSizeBits = this.blockSize * 32;
+
+	            // Add padding
+	            dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);
+	            dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;
+	            data.sigBytes = dataWords.length * 4;
+
+	            // Hash final blocks
+	            this._process();
+
+	            // Shortcuts
+	            var state = this._state;
+	            var outputLengthBytes = this.cfg.outputLength / 8;
+	            var outputLengthLanes = outputLengthBytes / 8;
+
+	            // Squeeze
+	            var hashWords = [];
+	            for (var i = 0; i < outputLengthLanes; i++) {
+	                // Shortcuts
+	                var lane = state[i];
+	                var laneMsw = lane.high;
+	                var laneLsw = lane.low;
+
+	                // Swap endian
+	                laneMsw = (
+	                    (((laneMsw << 8)  | (laneMsw >>> 24)) & 0x00ff00ff) |
+	                    (((laneMsw << 24) | (laneMsw >>> 8))  & 0xff00ff00)
+	                );
+	                laneLsw = (
+	                    (((laneLsw << 8)  | (laneLsw >>> 24)) & 0x00ff00ff) |
+	                    (((laneLsw << 24) | (laneLsw >>> 8))  & 0xff00ff00)
+	                );
+
+	                // Squeeze state to retrieve hash
+	                hashWords.push(laneLsw);
+	                hashWords.push(laneMsw);
+	            }
+
+	            // Return final computed hash
+	            return new WordArray.init(hashWords, outputLengthBytes);
+	        },
+
+	        clone: function () {
+	            var clone = Hasher.clone.call(this);
+
+	            var state = clone._state = this._state.slice(0);
+	            for (var i = 0; i < 25; i++) {
+	                state[i] = state[i].clone();
+	            }
+
+	            return clone;
+	        }
+	    });
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.SHA3('message');
+	     *     var hash = CryptoJS.SHA3(wordArray);
+	     */
+	    C.SHA3 = Hasher._createHelper(SHA3);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacSHA3(message, key);
+	     */
+	    C.HmacSHA3 = Hasher._createHmacHelper(SHA3);
+	}(Math));
+
+
+	/** @preserve
+	(c) 2012 by Cédric Mesnil. All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+	    - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+	    - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+	*/
+
+	(function (Math) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var Hasher = C_lib.Hasher;
+	    var C_algo = C.algo;
+
+	    // Constants table
+	    var _zl = WordArray.create([
+	        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+	        7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
+	        3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
+	        1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
+	        4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13]);
+	    var _zr = WordArray.create([
+	        5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
+	        6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
+	        15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
+	        8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
+	        12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11]);
+	    var _sl = WordArray.create([
+	         11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
+	        7, 6,   8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
+	        11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
+	          11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
+	        9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6 ]);
+	    var _sr = WordArray.create([
+	        8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
+	        9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
+	        9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
+	        15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
+	        8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11 ]);
+
+	    var _hl =  WordArray.create([ 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]);
+	    var _hr =  WordArray.create([ 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]);
+
+	    /**
+	     * RIPEMD160 hash algorithm.
+	     */
+	    var RIPEMD160 = C_algo.RIPEMD160 = Hasher.extend({
+	        _doReset: function () {
+	            this._hash  = WordArray.create([0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]);
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+
+	            // Swap endian
+	            for (var i = 0; i < 16; i++) {
+	                // Shortcuts
+	                var offset_i = offset + i;
+	                var M_offset_i = M[offset_i];
+
+	                // Swap
+	                M[offset_i] = (
+	                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |
+	                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)
+	                );
+	            }
+	            // Shortcut
+	            var H  = this._hash.words;
+	            var hl = _hl.words;
+	            var hr = _hr.words;
+	            var zl = _zl.words;
+	            var zr = _zr.words;
+	            var sl = _sl.words;
+	            var sr = _sr.words;
+
+	            // Working variables
+	            var al, bl, cl, dl, el;
+	            var ar, br, cr, dr, er;
+
+	            ar = al = H[0];
+	            br = bl = H[1];
+	            cr = cl = H[2];
+	            dr = dl = H[3];
+	            er = el = H[4];
+	            // Computation
+	            var t;
+	            for (var i = 0; i < 80; i += 1) {
+	                t = (al +  M[offset+zl[i]])|0;
+	                if (i<16){
+		            t +=  f1(bl,cl,dl) + hl[0];
+	                } else if (i<32) {
+		            t +=  f2(bl,cl,dl) + hl[1];
+	                } else if (i<48) {
+		            t +=  f3(bl,cl,dl) + hl[2];
+	                } else if (i<64) {
+		            t +=  f4(bl,cl,dl) + hl[3];
+	                } else {// if (i<80) {
+		            t +=  f5(bl,cl,dl) + hl[4];
+	                }
+	                t = t|0;
+	                t =  rotl(t,sl[i]);
+	                t = (t+el)|0;
+	                al = el;
+	                el = dl;
+	                dl = rotl(cl, 10);
+	                cl = bl;
+	                bl = t;
+
+	                t = (ar + M[offset+zr[i]])|0;
+	                if (i<16){
+		            t +=  f5(br,cr,dr) + hr[0];
+	                } else if (i<32) {
+		            t +=  f4(br,cr,dr) + hr[1];
+	                } else if (i<48) {
+		            t +=  f3(br,cr,dr) + hr[2];
+	                } else if (i<64) {
+		            t +=  f2(br,cr,dr) + hr[3];
+	                } else {// if (i<80) {
+		            t +=  f1(br,cr,dr) + hr[4];
+	                }
+	                t = t|0;
+	                t =  rotl(t,sr[i]) ;
+	                t = (t+er)|0;
+	                ar = er;
+	                er = dr;
+	                dr = rotl(cr, 10);
+	                cr = br;
+	                br = t;
+	            }
+	            // Intermediate hash value
+	            t    = (H[1] + cl + dr)|0;
+	            H[1] = (H[2] + dl + er)|0;
+	            H[2] = (H[3] + el + ar)|0;
+	            H[3] = (H[4] + al + br)|0;
+	            H[4] = (H[0] + bl + cr)|0;
+	            H[0] =  t;
+	        },
+
+	        _doFinalize: function () {
+	            // Shortcuts
+	            var data = this._data;
+	            var dataWords = data.words;
+
+	            var nBitsTotal = this._nDataBytes * 8;
+	            var nBitsLeft = data.sigBytes * 8;
+
+	            // Add padding
+	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
+	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
+	                (((nBitsTotal << 8)  | (nBitsTotal >>> 24)) & 0x00ff00ff) |
+	                (((nBitsTotal << 24) | (nBitsTotal >>> 8))  & 0xff00ff00)
+	            );
+	            data.sigBytes = (dataWords.length + 1) * 4;
+
+	            // Hash final blocks
+	            this._process();
+
+	            // Shortcuts
+	            var hash = this._hash;
+	            var H = hash.words;
+
+	            // Swap endian
+	            for (var i = 0; i < 5; i++) {
+	                // Shortcut
+	                var H_i = H[i];
+
+	                // Swap
+	                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |
+	                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);
+	            }
+
+	            // Return final computed hash
+	            return hash;
+	        },
+
+	        clone: function () {
+	            var clone = Hasher.clone.call(this);
+	            clone._hash = this._hash.clone();
+
+	            return clone;
+	        }
+	    });
+
+
+	    function f1(x, y, z) {
+	        return ((x) ^ (y) ^ (z));
+
+	    }
+
+	    function f2(x, y, z) {
+	        return (((x)&(y)) | ((~x)&(z)));
+	    }
+
+	    function f3(x, y, z) {
+	        return (((x) | (~(y))) ^ (z));
+	    }
+
+	    function f4(x, y, z) {
+	        return (((x) & (z)) | ((y)&(~(z))));
+	    }
+
+	    function f5(x, y, z) {
+	        return ((x) ^ ((y) |(~(z))));
+
+	    }
+
+	    function rotl(x,n) {
+	        return (x<<n) | (x>>>(32-n));
+	    }
+
+
+	    /**
+	     * Shortcut function to the hasher's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     *
+	     * @return {WordArray} The hash.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hash = CryptoJS.RIPEMD160('message');
+	     *     var hash = CryptoJS.RIPEMD160(wordArray);
+	     */
+	    C.RIPEMD160 = Hasher._createHelper(RIPEMD160);
+
+	    /**
+	     * Shortcut function to the HMAC's object interface.
+	     *
+	     * @param {WordArray|string} message The message to hash.
+	     * @param {WordArray|string} key The secret key.
+	     *
+	     * @return {WordArray} The HMAC.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var hmac = CryptoJS.HmacRIPEMD160(message, key);
+	     */
+	    C.HmacRIPEMD160 = Hasher._createHmacHelper(RIPEMD160);
+	}(Math));
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var Base = C_lib.Base;
+	    var C_enc = C.enc;
+	    var Utf8 = C_enc.Utf8;
+	    var C_algo = C.algo;
+
+	    /**
+	     * HMAC algorithm.
+	     */
+	    var HMAC = C_algo.HMAC = Base.extend({
+	        /**
+	         * Initializes a newly created HMAC.
+	         *
+	         * @param {Hasher} hasher The hash algorithm to use.
+	         * @param {WordArray|string} key The secret key.
+	         *
+	         * @example
+	         *
+	         *     var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
+	         */
+	        init: function (hasher, key) {
+	            // Init hasher
+	            hasher = this._hasher = new hasher.init();
+
+	            // Convert string to WordArray, else assume WordArray already
+	            if (typeof key == 'string') {
+	                key = Utf8.parse(key);
+	            }
+
+	            // Shortcuts
+	            var hasherBlockSize = hasher.blockSize;
+	            var hasherBlockSizeBytes = hasherBlockSize * 4;
+
+	            // Allow arbitrary length keys
+	            if (key.sigBytes > hasherBlockSizeBytes) {
+	                key = hasher.finalize(key);
+	            }
+
+	            // Clamp excess bits
+	            key.clamp();
+
+	            // Clone key for inner and outer pads
+	            var oKey = this._oKey = key.clone();
+	            var iKey = this._iKey = key.clone();
+
+	            // Shortcuts
+	            var oKeyWords = oKey.words;
+	            var iKeyWords = iKey.words;
+
+	            // XOR keys with pad constants
+	            for (var i = 0; i < hasherBlockSize; i++) {
+	                oKeyWords[i] ^= 0x5c5c5c5c;
+	                iKeyWords[i] ^= 0x36363636;
+	            }
+	            oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
+
+	            // Set initial values
+	            this.reset();
+	        },
+
+	        /**
+	         * Resets this HMAC to its initial state.
+	         *
+	         * @example
+	         *
+	         *     hmacHasher.reset();
+	         */
+	        reset: function () {
+	            // Shortcut
+	            var hasher = this._hasher;
+
+	            // Reset
+	            hasher.reset();
+	            hasher.update(this._iKey);
+	        },
+
+	        /**
+	         * Updates this HMAC with a message.
+	         *
+	         * @param {WordArray|string} messageUpdate The message to append.
+	         *
+	         * @return {HMAC} This HMAC instance.
+	         *
+	         * @example
+	         *
+	         *     hmacHasher.update('message');
+	         *     hmacHasher.update(wordArray);
+	         */
+	        update: function (messageUpdate) {
+	            this._hasher.update(messageUpdate);
+
+	            // Chainable
+	            return this;
+	        },
+
+	        /**
+	         * Finalizes the HMAC computation.
+	         * Note that the finalize operation is effectively a destructive, read-once operation.
+	         *
+	         * @param {WordArray|string} messageUpdate (Optional) A final message update.
+	         *
+	         * @return {WordArray} The HMAC.
+	         *
+	         * @example
+	         *
+	         *     var hmac = hmacHasher.finalize();
+	         *     var hmac = hmacHasher.finalize('message');
+	         *     var hmac = hmacHasher.finalize(wordArray);
+	         */
+	        finalize: function (messageUpdate) {
+	            // Shortcut
+	            var hasher = this._hasher;
+
+	            // Compute HMAC
+	            var innerHash = hasher.finalize(messageUpdate);
+	            hasher.reset();
+	            var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
+
+	            return hmac;
+	        }
+	    });
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var Base = C_lib.Base;
+	    var WordArray = C_lib.WordArray;
+	    var C_algo = C.algo;
+	    var SHA1 = C_algo.SHA1;
+	    var HMAC = C_algo.HMAC;
+
+	    /**
+	     * Password-Based Key Derivation Function 2 algorithm.
+	     */
+	    var PBKDF2 = C_algo.PBKDF2 = Base.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
+	         * @property {Hasher} hasher The hasher to use. Default: SHA1
+	         * @property {number} iterations The number of iterations to perform. Default: 1
+	         */
+	        cfg: Base.extend({
+	            keySize: 128/32,
+	            hasher: SHA1,
+	            iterations: 1
+	        }),
+
+	        /**
+	         * Initializes a newly created key derivation function.
+	         *
+	         * @param {Object} cfg (Optional) The configuration options to use for the derivation.
+	         *
+	         * @example
+	         *
+	         *     var kdf = CryptoJS.algo.PBKDF2.create();
+	         *     var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 });
+	         *     var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 });
+	         */
+	        init: function (cfg) {
+	            this.cfg = this.cfg.extend(cfg);
+	        },
+
+	        /**
+	         * Computes the Password-Based Key Derivation Function 2.
+	         *
+	         * @param {WordArray|string} password The password.
+	         * @param {WordArray|string} salt A salt.
+	         *
+	         * @return {WordArray} The derived key.
+	         *
+	         * @example
+	         *
+	         *     var key = kdf.compute(password, salt);
+	         */
+	        compute: function (password, salt) {
+	            // Shortcut
+	            var cfg = this.cfg;
+
+	            // Init HMAC
+	            var hmac = HMAC.create(cfg.hasher, password);
+
+	            // Initial values
+	            var derivedKey = WordArray.create();
+	            var blockIndex = WordArray.create([0x00000001]);
+
+	            // Shortcuts
+	            var derivedKeyWords = derivedKey.words;
+	            var blockIndexWords = blockIndex.words;
+	            var keySize = cfg.keySize;
+	            var iterations = cfg.iterations;
+
+	            // Generate key
+	            while (derivedKeyWords.length < keySize) {
+	                var block = hmac.update(salt).finalize(blockIndex);
+	                hmac.reset();
+
+	                // Shortcuts
+	                var blockWords = block.words;
+	                var blockWordsLength = blockWords.length;
+
+	                // Iterations
+	                var intermediate = block;
+	                for (var i = 1; i < iterations; i++) {
+	                    intermediate = hmac.finalize(intermediate);
+	                    hmac.reset();
+
+	                    // Shortcut
+	                    var intermediateWords = intermediate.words;
+
+	                    // XOR intermediate with block
+	                    for (var j = 0; j < blockWordsLength; j++) {
+	                        blockWords[j] ^= intermediateWords[j];
+	                    }
+	                }
+
+	                derivedKey.concat(block);
+	                blockIndexWords[0]++;
+	            }
+	            derivedKey.sigBytes = keySize * 4;
+
+	            return derivedKey;
+	        }
+	    });
+
+	    /**
+	     * Computes the Password-Based Key Derivation Function 2.
+	     *
+	     * @param {WordArray|string} password The password.
+	     * @param {WordArray|string} salt A salt.
+	     * @param {Object} cfg (Optional) The configuration options to use for this computation.
+	     *
+	     * @return {WordArray} The derived key.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var key = CryptoJS.PBKDF2(password, salt);
+	     *     var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });
+	     *     var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 });
+	     */
+	    C.PBKDF2 = function (password, salt, cfg) {
+	        return PBKDF2.create(cfg).compute(password, salt);
+	    };
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var Base = C_lib.Base;
+	    var WordArray = C_lib.WordArray;
+	    var C_algo = C.algo;
+	    var MD5 = C_algo.MD5;
+
+	    /**
+	     * This key derivation function is meant to conform with EVP_BytesToKey.
+	     * www.openssl.org/docs/crypto/EVP_BytesToKey.html
+	     */
+	    var EvpKDF = C_algo.EvpKDF = Base.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
+	         * @property {Hasher} hasher The hash algorithm to use. Default: MD5
+	         * @property {number} iterations The number of iterations to perform. Default: 1
+	         */
+	        cfg: Base.extend({
+	            keySize: 128/32,
+	            hasher: MD5,
+	            iterations: 1
+	        }),
+
+	        /**
+	         * Initializes a newly created key derivation function.
+	         *
+	         * @param {Object} cfg (Optional) The configuration options to use for the derivation.
+	         *
+	         * @example
+	         *
+	         *     var kdf = CryptoJS.algo.EvpKDF.create();
+	         *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
+	         *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
+	         */
+	        init: function (cfg) {
+	            this.cfg = this.cfg.extend(cfg);
+	        },
+
+	        /**
+	         * Derives a key from a password.
+	         *
+	         * @param {WordArray|string} password The password.
+	         * @param {WordArray|string} salt A salt.
+	         *
+	         * @return {WordArray} The derived key.
+	         *
+	         * @example
+	         *
+	         *     var key = kdf.compute(password, salt);
+	         */
+	        compute: function (password, salt) {
+	            var block;
+
+	            // Shortcut
+	            var cfg = this.cfg;
+
+	            // Init hasher
+	            var hasher = cfg.hasher.create();
+
+	            // Initial values
+	            var derivedKey = WordArray.create();
+
+	            // Shortcuts
+	            var derivedKeyWords = derivedKey.words;
+	            var keySize = cfg.keySize;
+	            var iterations = cfg.iterations;
+
+	            // Generate key
+	            while (derivedKeyWords.length < keySize) {
+	                if (block) {
+	                    hasher.update(block);
+	                }
+	                block = hasher.update(password).finalize(salt);
+	                hasher.reset();
+
+	                // Iterations
+	                for (var i = 1; i < iterations; i++) {
+	                    block = hasher.finalize(block);
+	                    hasher.reset();
+	                }
+
+	                derivedKey.concat(block);
+	            }
+	            derivedKey.sigBytes = keySize * 4;
+
+	            return derivedKey;
+	        }
+	    });
+
+	    /**
+	     * Derives a key from a password.
+	     *
+	     * @param {WordArray|string} password The password.
+	     * @param {WordArray|string} salt A salt.
+	     * @param {Object} cfg (Optional) The configuration options to use for this computation.
+	     *
+	     * @return {WordArray} The derived key.
+	     *
+	     * @static
+	     *
+	     * @example
+	     *
+	     *     var key = CryptoJS.EvpKDF(password, salt);
+	     *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
+	     *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
+	     */
+	    C.EvpKDF = function (password, salt, cfg) {
+	        return EvpKDF.create(cfg).compute(password, salt);
+	    };
+	}());
+
+
+	/**
+	 * Cipher core components.
+	 */
+	CryptoJS.lib.Cipher || (function (undefined) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var Base = C_lib.Base;
+	    var WordArray = C_lib.WordArray;
+	    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
+	    var C_enc = C.enc;
+	    var Utf8 = C_enc.Utf8;
+	    var Base64 = C_enc.Base64;
+	    var C_algo = C.algo;
+	    var EvpKDF = C_algo.EvpKDF;
+
+	    /**
+	     * Abstract base cipher template.
+	     *
+	     * @property {number} keySize This cipher's key size. Default: 4 (128 bits)
+	     * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
+	     * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
+	     * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
+	     */
+	    var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {WordArray} iv The IV to use for this operation.
+	         */
+	        cfg: Base.extend(),
+
+	        /**
+	         * Creates this cipher in encryption mode.
+	         *
+	         * @param {WordArray} key The key.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @return {Cipher} A cipher instance.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
+	         */
+	        createEncryptor: function (key, cfg) {
+	            return this.create(this._ENC_XFORM_MODE, key, cfg);
+	        },
+
+	        /**
+	         * Creates this cipher in decryption mode.
+	         *
+	         * @param {WordArray} key The key.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @return {Cipher} A cipher instance.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
+	         */
+	        createDecryptor: function (key, cfg) {
+	            return this.create(this._DEC_XFORM_MODE, key, cfg);
+	        },
+
+	        /**
+	         * Initializes a newly created cipher.
+	         *
+	         * @param {number} xformMode Either the encryption or decryption transormation mode constant.
+	         * @param {WordArray} key The key.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @example
+	         *
+	         *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
+	         */
+	        init: function (xformMode, key, cfg) {
+	            // Apply config defaults
+	            this.cfg = this.cfg.extend(cfg);
+
+	            // Store transform mode and key
+	            this._xformMode = xformMode;
+	            this._key = key;
+
+	            // Set initial values
+	            this.reset();
+	        },
+
+	        /**
+	         * Resets this cipher to its initial state.
+	         *
+	         * @example
+	         *
+	         *     cipher.reset();
+	         */
+	        reset: function () {
+	            // Reset data buffer
+	            BufferedBlockAlgorithm.reset.call(this);
+
+	            // Perform concrete-cipher logic
+	            this._doReset();
+	        },
+
+	        /**
+	         * Adds data to be encrypted or decrypted.
+	         *
+	         * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
+	         *
+	         * @return {WordArray} The data after processing.
+	         *
+	         * @example
+	         *
+	         *     var encrypted = cipher.process('data');
+	         *     var encrypted = cipher.process(wordArray);
+	         */
+	        process: function (dataUpdate) {
+	            // Append
+	            this._append(dataUpdate);
+
+	            // Process available blocks
+	            return this._process();
+	        },
+
+	        /**
+	         * Finalizes the encryption or decryption process.
+	         * Note that the finalize operation is effectively a destructive, read-once operation.
+	         *
+	         * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
+	         *
+	         * @return {WordArray} The data after final processing.
+	         *
+	         * @example
+	         *
+	         *     var encrypted = cipher.finalize();
+	         *     var encrypted = cipher.finalize('data');
+	         *     var encrypted = cipher.finalize(wordArray);
+	         */
+	        finalize: function (dataUpdate) {
+	            // Final data update
+	            if (dataUpdate) {
+	                this._append(dataUpdate);
+	            }
+
+	            // Perform concrete-cipher logic
+	            var finalProcessedData = this._doFinalize();
+
+	            return finalProcessedData;
+	        },
+
+	        keySize: 128/32,
+
+	        ivSize: 128/32,
+
+	        _ENC_XFORM_MODE: 1,
+
+	        _DEC_XFORM_MODE: 2,
+
+	        /**
+	         * Creates shortcut functions to a cipher's object interface.
+	         *
+	         * @param {Cipher} cipher The cipher to create a helper for.
+	         *
+	         * @return {Object} An object with encrypt and decrypt shortcut functions.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
+	         */
+	        _createHelper: (function () {
+	            function selectCipherStrategy(key) {
+	                if (typeof key == 'string') {
+	                    return PasswordBasedCipher;
+	                } else {
+	                    return SerializableCipher;
+	                }
+	            }
+
+	            return function (cipher) {
+	                return {
+	                    encrypt: function (message, key, cfg) {
+	                        return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
+	                    },
+
+	                    decrypt: function (ciphertext, key, cfg) {
+	                        return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
+	                    }
+	                };
+	            };
+	        }())
+	    });
+
+	    /**
+	     * Abstract base stream cipher template.
+	     *
+	     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
+	     */
+	    var StreamCipher = C_lib.StreamCipher = Cipher.extend({
+	        _doFinalize: function () {
+	            // Process partial blocks
+	            var finalProcessedBlocks = this._process(!!'flush');
+
+	            return finalProcessedBlocks;
+	        },
+
+	        blockSize: 1
+	    });
+
+	    /**
+	     * Mode namespace.
+	     */
+	    var C_mode = C.mode = {};
+
+	    /**
+	     * Abstract base block cipher mode template.
+	     */
+	    var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
+	        /**
+	         * Creates this mode for encryption.
+	         *
+	         * @param {Cipher} cipher A block cipher instance.
+	         * @param {Array} iv The IV words.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
+	         */
+	        createEncryptor: function (cipher, iv) {
+	            return this.Encryptor.create(cipher, iv);
+	        },
+
+	        /**
+	         * Creates this mode for decryption.
+	         *
+	         * @param {Cipher} cipher A block cipher instance.
+	         * @param {Array} iv The IV words.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
+	         */
+	        createDecryptor: function (cipher, iv) {
+	            return this.Decryptor.create(cipher, iv);
+	        },
+
+	        /**
+	         * Initializes a newly created mode.
+	         *
+	         * @param {Cipher} cipher A block cipher instance.
+	         * @param {Array} iv The IV words.
+	         *
+	         * @example
+	         *
+	         *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
+	         */
+	        init: function (cipher, iv) {
+	            this._cipher = cipher;
+	            this._iv = iv;
+	        }
+	    });
+
+	    /**
+	     * Cipher Block Chaining mode.
+	     */
+	    var CBC = C_mode.CBC = (function () {
+	        /**
+	         * Abstract base CBC mode.
+	         */
+	        var CBC = BlockCipherMode.extend();
+
+	        /**
+	         * CBC encryptor.
+	         */
+	        CBC.Encryptor = CBC.extend({
+	            /**
+	             * Processes the data block at offset.
+	             *
+	             * @param {Array} words The data words to operate on.
+	             * @param {number} offset The offset where the block starts.
+	             *
+	             * @example
+	             *
+	             *     mode.processBlock(data.words, offset);
+	             */
+	            processBlock: function (words, offset) {
+	                // Shortcuts
+	                var cipher = this._cipher;
+	                var blockSize = cipher.blockSize;
+
+	                // XOR and encrypt
+	                xorBlock.call(this, words, offset, blockSize);
+	                cipher.encryptBlock(words, offset);
+
+	                // Remember this block to use with next block
+	                this._prevBlock = words.slice(offset, offset + blockSize);
+	            }
+	        });
+
+	        /**
+	         * CBC decryptor.
+	         */
+	        CBC.Decryptor = CBC.extend({
+	            /**
+	             * Processes the data block at offset.
+	             *
+	             * @param {Array} words The data words to operate on.
+	             * @param {number} offset The offset where the block starts.
+	             *
+	             * @example
+	             *
+	             *     mode.processBlock(data.words, offset);
+	             */
+	            processBlock: function (words, offset) {
+	                // Shortcuts
+	                var cipher = this._cipher;
+	                var blockSize = cipher.blockSize;
+
+	                // Remember this block to use with next block
+	                var thisBlock = words.slice(offset, offset + blockSize);
+
+	                // Decrypt and XOR
+	                cipher.decryptBlock(words, offset);
+	                xorBlock.call(this, words, offset, blockSize);
+
+	                // This block becomes the previous block
+	                this._prevBlock = thisBlock;
+	            }
+	        });
+
+	        function xorBlock(words, offset, blockSize) {
+	            var block;
+
+	            // Shortcut
+	            var iv = this._iv;
+
+	            // Choose mixing block
+	            if (iv) {
+	                block = iv;
+
+	                // Remove IV for subsequent blocks
+	                this._iv = undefined;
+	            } else {
+	                block = this._prevBlock;
+	            }
+
+	            // XOR blocks
+	            for (var i = 0; i < blockSize; i++) {
+	                words[offset + i] ^= block[i];
+	            }
+	        }
+
+	        return CBC;
+	    }());
+
+	    /**
+	     * Padding namespace.
+	     */
+	    var C_pad = C.pad = {};
+
+	    /**
+	     * PKCS #5/7 padding strategy.
+	     */
+	    var Pkcs7 = C_pad.Pkcs7 = {
+	        /**
+	         * Pads data using the algorithm defined in PKCS #5/7.
+	         *
+	         * @param {WordArray} data The data to pad.
+	         * @param {number} blockSize The multiple that the data should be padded to.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);
+	         */
+	        pad: function (data, blockSize) {
+	            // Shortcut
+	            var blockSizeBytes = blockSize * 4;
+
+	            // Count padding bytes
+	            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
+
+	            // Create padding word
+	            var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
+
+	            // Create padding
+	            var paddingWords = [];
+	            for (var i = 0; i < nPaddingBytes; i += 4) {
+	                paddingWords.push(paddingWord);
+	            }
+	            var padding = WordArray.create(paddingWords, nPaddingBytes);
+
+	            // Add padding
+	            data.concat(padding);
+	        },
+
+	        /**
+	         * Unpads data that had been padded using the algorithm defined in PKCS #5/7.
+	         *
+	         * @param {WordArray} data The data to unpad.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     CryptoJS.pad.Pkcs7.unpad(wordArray);
+	         */
+	        unpad: function (data) {
+	            // Get number of padding bytes from last byte
+	            var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
+
+	            // Remove padding
+	            data.sigBytes -= nPaddingBytes;
+	        }
+	    };
+
+	    /**
+	     * Abstract base block cipher template.
+	     *
+	     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
+	     */
+	    var BlockCipher = C_lib.BlockCipher = Cipher.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {Mode} mode The block mode to use. Default: CBC
+	         * @property {Padding} padding The padding strategy to use. Default: Pkcs7
+	         */
+	        cfg: Cipher.cfg.extend({
+	            mode: CBC,
+	            padding: Pkcs7
+	        }),
+
+	        reset: function () {
+	            var modeCreator;
+
+	            // Reset cipher
+	            Cipher.reset.call(this);
+
+	            // Shortcuts
+	            var cfg = this.cfg;
+	            var iv = cfg.iv;
+	            var mode = cfg.mode;
+
+	            // Reset block mode
+	            if (this._xformMode == this._ENC_XFORM_MODE) {
+	                modeCreator = mode.createEncryptor;
+	            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
+	                modeCreator = mode.createDecryptor;
+	                // Keep at least one block in the buffer for unpadding
+	                this._minBufferSize = 1;
+	            }
+
+	            if (this._mode && this._mode.__creator == modeCreator) {
+	                this._mode.init(this, iv && iv.words);
+	            } else {
+	                this._mode = modeCreator.call(mode, this, iv && iv.words);
+	                this._mode.__creator = modeCreator;
+	            }
+	        },
+
+	        _doProcessBlock: function (words, offset) {
+	            this._mode.processBlock(words, offset);
+	        },
+
+	        _doFinalize: function () {
+	            var finalProcessedBlocks;
+
+	            // Shortcut
+	            var padding = this.cfg.padding;
+
+	            // Finalize
+	            if (this._xformMode == this._ENC_XFORM_MODE) {
+	                // Pad data
+	                padding.pad(this._data, this.blockSize);
+
+	                // Process final blocks
+	                finalProcessedBlocks = this._process(!!'flush');
+	            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
+	                // Process final blocks
+	                finalProcessedBlocks = this._process(!!'flush');
+
+	                // Unpad data
+	                padding.unpad(finalProcessedBlocks);
+	            }
+
+	            return finalProcessedBlocks;
+	        },
+
+	        blockSize: 128/32
+	    });
+
+	    /**
+	     * A collection of cipher parameters.
+	     *
+	     * @property {WordArray} ciphertext The raw ciphertext.
+	     * @property {WordArray} key The key to this ciphertext.
+	     * @property {WordArray} iv The IV used in the ciphering operation.
+	     * @property {WordArray} salt The salt used with a key derivation function.
+	     * @property {Cipher} algorithm The cipher algorithm.
+	     * @property {Mode} mode The block mode used in the ciphering operation.
+	     * @property {Padding} padding The padding scheme used in the ciphering operation.
+	     * @property {number} blockSize The block size of the cipher.
+	     * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
+	     */
+	    var CipherParams = C_lib.CipherParams = Base.extend({
+	        /**
+	         * Initializes a newly created cipher params object.
+	         *
+	         * @param {Object} cipherParams An object with any of the possible cipher parameters.
+	         *
+	         * @example
+	         *
+	         *     var cipherParams = CryptoJS.lib.CipherParams.create({
+	         *         ciphertext: ciphertextWordArray,
+	         *         key: keyWordArray,
+	         *         iv: ivWordArray,
+	         *         salt: saltWordArray,
+	         *         algorithm: CryptoJS.algo.AES,
+	         *         mode: CryptoJS.mode.CBC,
+	         *         padding: CryptoJS.pad.PKCS7,
+	         *         blockSize: 4,
+	         *         formatter: CryptoJS.format.OpenSSL
+	         *     });
+	         */
+	        init: function (cipherParams) {
+	            this.mixIn(cipherParams);
+	        },
+
+	        /**
+	         * Converts this cipher params object to a string.
+	         *
+	         * @param {Format} formatter (Optional) The formatting strategy to use.
+	         *
+	         * @return {string} The stringified cipher params.
+	         *
+	         * @throws Error If neither the formatter nor the default formatter is set.
+	         *
+	         * @example
+	         *
+	         *     var string = cipherParams + '';
+	         *     var string = cipherParams.toString();
+	         *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);
+	         */
+	        toString: function (formatter) {
+	            return (formatter || this.formatter).stringify(this);
+	        }
+	    });
+
+	    /**
+	     * Format namespace.
+	     */
+	    var C_format = C.format = {};
+
+	    /**
+	     * OpenSSL formatting strategy.
+	     */
+	    var OpenSSLFormatter = C_format.OpenSSL = {
+	        /**
+	         * Converts a cipher params object to an OpenSSL-compatible string.
+	         *
+	         * @param {CipherParams} cipherParams The cipher params object.
+	         *
+	         * @return {string} The OpenSSL-compatible string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
+	         */
+	        stringify: function (cipherParams) {
+	            var wordArray;
+
+	            // Shortcuts
+	            var ciphertext = cipherParams.ciphertext;
+	            var salt = cipherParams.salt;
+
+	            // Format
+	            if (salt) {
+	                wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
+	            } else {
+	                wordArray = ciphertext;
+	            }
+
+	            return wordArray.toString(Base64);
+	        },
+
+	        /**
+	         * Converts an OpenSSL-compatible string to a cipher params object.
+	         *
+	         * @param {string} openSSLStr The OpenSSL-compatible string.
+	         *
+	         * @return {CipherParams} The cipher params object.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
+	         */
+	        parse: function (openSSLStr) {
+	            var salt;
+
+	            // Parse base64
+	            var ciphertext = Base64.parse(openSSLStr);
+
+	            // Shortcut
+	            var ciphertextWords = ciphertext.words;
+
+	            // Test for salt
+	            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
+	                // Extract salt
+	                salt = WordArray.create(ciphertextWords.slice(2, 4));
+
+	                // Remove salt from ciphertext
+	                ciphertextWords.splice(0, 4);
+	                ciphertext.sigBytes -= 16;
+	            }
+
+	            return CipherParams.create({ ciphertext: ciphertext, salt: salt });
+	        }
+	    };
+
+	    /**
+	     * A cipher wrapper that returns ciphertext as a serializable cipher params object.
+	     */
+	    var SerializableCipher = C_lib.SerializableCipher = Base.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
+	         */
+	        cfg: Base.extend({
+	            format: OpenSSLFormatter
+	        }),
+
+	        /**
+	         * Encrypts a message.
+	         *
+	         * @param {Cipher} cipher The cipher algorithm to use.
+	         * @param {WordArray|string} message The message to encrypt.
+	         * @param {WordArray} key The key.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @return {CipherParams} A cipher params object.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
+	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
+	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
+	         */
+	        encrypt: function (cipher, message, key, cfg) {
+	            // Apply config defaults
+	            cfg = this.cfg.extend(cfg);
+
+	            // Encrypt
+	            var encryptor = cipher.createEncryptor(key, cfg);
+	            var ciphertext = encryptor.finalize(message);
+
+	            // Shortcut
+	            var cipherCfg = encryptor.cfg;
+
+	            // Create and return serializable cipher params
+	            return CipherParams.create({
+	                ciphertext: ciphertext,
+	                key: key,
+	                iv: cipherCfg.iv,
+	                algorithm: cipher,
+	                mode: cipherCfg.mode,
+	                padding: cipherCfg.padding,
+	                blockSize: cipher.blockSize,
+	                formatter: cfg.format
+	            });
+	        },
+
+	        /**
+	         * Decrypts serialized ciphertext.
+	         *
+	         * @param {Cipher} cipher The cipher algorithm to use.
+	         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
+	         * @param {WordArray} key The key.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @return {WordArray} The plaintext.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
+	         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
+	         */
+	        decrypt: function (cipher, ciphertext, key, cfg) {
+	            // Apply config defaults
+	            cfg = this.cfg.extend(cfg);
+
+	            // Convert string to CipherParams
+	            ciphertext = this._parse(ciphertext, cfg.format);
+
+	            // Decrypt
+	            var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
+
+	            return plaintext;
+	        },
+
+	        /**
+	         * Converts serialized ciphertext to CipherParams,
+	         * else assumed CipherParams already and returns ciphertext unchanged.
+	         *
+	         * @param {CipherParams|string} ciphertext The ciphertext.
+	         * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
+	         *
+	         * @return {CipherParams} The unserialized ciphertext.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
+	         */
+	        _parse: function (ciphertext, format) {
+	            if (typeof ciphertext == 'string') {
+	                return format.parse(ciphertext, this);
+	            } else {
+	                return ciphertext;
+	            }
+	        }
+	    });
+
+	    /**
+	     * Key derivation function namespace.
+	     */
+	    var C_kdf = C.kdf = {};
+
+	    /**
+	     * OpenSSL key derivation function.
+	     */
+	    var OpenSSLKdf = C_kdf.OpenSSL = {
+	        /**
+	         * Derives a key and IV from a password.
+	         *
+	         * @param {string} password The password to derive from.
+	         * @param {number} keySize The size in words of the key to generate.
+	         * @param {number} ivSize The size in words of the IV to generate.
+	         * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
+	         *
+	         * @return {CipherParams} A cipher params object with the key, IV, and salt.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
+	         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
+	         */
+	        execute: function (password, keySize, ivSize, salt) {
+	            // Generate random salt
+	            if (!salt) {
+	                salt = WordArray.random(64/8);
+	            }
+
+	            // Derive key and IV
+	            var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
+
+	            // Separate key and IV
+	            var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
+	            key.sigBytes = keySize * 4;
+
+	            // Return params
+	            return CipherParams.create({ key: key, iv: iv, salt: salt });
+	        }
+	    };
+
+	    /**
+	     * A serializable cipher wrapper that derives the key from a password,
+	     * and returns ciphertext as a serializable cipher params object.
+	     */
+	    var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
+	         */
+	        cfg: SerializableCipher.cfg.extend({
+	            kdf: OpenSSLKdf
+	        }),
+
+	        /**
+	         * Encrypts a message using a password.
+	         *
+	         * @param {Cipher} cipher The cipher algorithm to use.
+	         * @param {WordArray|string} message The message to encrypt.
+	         * @param {string} password The password.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @return {CipherParams} A cipher params object.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
+	         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
+	         */
+	        encrypt: function (cipher, message, password, cfg) {
+	            // Apply config defaults
+	            cfg = this.cfg.extend(cfg);
+
+	            // Derive key and other params
+	            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
+
+	            // Add IV to config
+	            cfg.iv = derivedParams.iv;
+
+	            // Encrypt
+	            var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
+
+	            // Mix in derived params
+	            ciphertext.mixIn(derivedParams);
+
+	            return ciphertext;
+	        },
+
+	        /**
+	         * Decrypts serialized ciphertext using a password.
+	         *
+	         * @param {Cipher} cipher The cipher algorithm to use.
+	         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
+	         * @param {string} password The password.
+	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
+	         *
+	         * @return {WordArray} The plaintext.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
+	         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
+	         */
+	        decrypt: function (cipher, ciphertext, password, cfg) {
+	            // Apply config defaults
+	            cfg = this.cfg.extend(cfg);
+
+	            // Convert string to CipherParams
+	            ciphertext = this._parse(ciphertext, cfg.format);
+
+	            // Derive key and other params
+	            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
+
+	            // Add IV to config
+	            cfg.iv = derivedParams.iv;
+
+	            // Decrypt
+	            var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
+
+	            return plaintext;
+	        }
+	    });
+	}());
+
+
+	/**
+	 * Cipher Feedback block mode.
+	 */
+	CryptoJS.mode.CFB = (function () {
+	    var CFB = CryptoJS.lib.BlockCipherMode.extend();
+
+	    CFB.Encryptor = CFB.extend({
+	        processBlock: function (words, offset) {
+	            // Shortcuts
+	            var cipher = this._cipher;
+	            var blockSize = cipher.blockSize;
+
+	            generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
+
+	            // Remember this block to use with next block
+	            this._prevBlock = words.slice(offset, offset + blockSize);
+	        }
+	    });
+
+	    CFB.Decryptor = CFB.extend({
+	        processBlock: function (words, offset) {
+	            // Shortcuts
+	            var cipher = this._cipher;
+	            var blockSize = cipher.blockSize;
+
+	            // Remember this block to use with next block
+	            var thisBlock = words.slice(offset, offset + blockSize);
+
+	            generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
+
+	            // This block becomes the previous block
+	            this._prevBlock = thisBlock;
+	        }
+	    });
+
+	    function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
+	        var keystream;
+
+	        // Shortcut
+	        var iv = this._iv;
+
+	        // Generate keystream
+	        if (iv) {
+	            keystream = iv.slice(0);
+
+	            // Remove IV for subsequent blocks
+	            this._iv = undefined;
+	        } else {
+	            keystream = this._prevBlock;
+	        }
+	        cipher.encryptBlock(keystream, 0);
+
+	        // Encrypt
+	        for (var i = 0; i < blockSize; i++) {
+	            words[offset + i] ^= keystream[i];
+	        }
+	    }
+
+	    return CFB;
+	}());
+
+
+	/**
+	 * Counter block mode.
+	 */
+	CryptoJS.mode.CTR = (function () {
+	    var CTR = CryptoJS.lib.BlockCipherMode.extend();
+
+	    var Encryptor = CTR.Encryptor = CTR.extend({
+	        processBlock: function (words, offset) {
+	            // Shortcuts
+	            var cipher = this._cipher
+	            var blockSize = cipher.blockSize;
+	            var iv = this._iv;
+	            var counter = this._counter;
+
+	            // Generate keystream
+	            if (iv) {
+	                counter = this._counter = iv.slice(0);
+
+	                // Remove IV for subsequent blocks
+	                this._iv = undefined;
+	            }
+	            var keystream = counter.slice(0);
+	            cipher.encryptBlock(keystream, 0);
+
+	            // Increment counter
+	            counter[blockSize - 1] = (counter[blockSize - 1] + 1) | 0
+
+	            // Encrypt
+	            for (var i = 0; i < blockSize; i++) {
+	                words[offset + i] ^= keystream[i];
+	            }
+	        }
+	    });
+
+	    CTR.Decryptor = Encryptor;
+
+	    return CTR;
+	}());
+
+
+	/** @preserve
+	 * Counter block mode compatible with  Dr Brian Gladman fileenc.c
+	 * derived from CryptoJS.mode.CTR
+	 * Jan Hruby jhruby.web@gmail.com
+	 */
+	CryptoJS.mode.CTRGladman = (function () {
+	    var CTRGladman = CryptoJS.lib.BlockCipherMode.extend();
+
+		function incWord(word)
+		{
+			if (((word >> 24) & 0xff) === 0xff) { //overflow
+			var b1 = (word >> 16)&0xff;
+			var b2 = (word >> 8)&0xff;
+			var b3 = word & 0xff;
+
+			if (b1 === 0xff) // overflow b1
+			{
+			b1 = 0;
+			if (b2 === 0xff)
+			{
+				b2 = 0;
+				if (b3 === 0xff)
+				{
+					b3 = 0;
+				}
+				else
+				{
+					++b3;
+				}
+			}
+			else
+			{
+				++b2;
+			}
+			}
+			else
+			{
+			++b1;
+			}
+
+			word = 0;
+			word += (b1 << 16);
+			word += (b2 << 8);
+			word += b3;
+			}
+			else
+			{
+			word += (0x01 << 24);
+			}
+			return word;
+		}
+
+		function incCounter(counter)
+		{
+			if ((counter[0] = incWord(counter[0])) === 0)
+			{
+				// encr_data in fileenc.c from  Dr Brian Gladman's counts only with DWORD j < 8
+				counter[1] = incWord(counter[1]);
+			}
+			return counter;
+		}
+
+	    var Encryptor = CTRGladman.Encryptor = CTRGladman.extend({
+	        processBlock: function (words, offset) {
+	            // Shortcuts
+	            var cipher = this._cipher
+	            var blockSize = cipher.blockSize;
+	            var iv = this._iv;
+	            var counter = this._counter;
+
+	            // Generate keystream
+	            if (iv) {
+	                counter = this._counter = iv.slice(0);
+
+	                // Remove IV for subsequent blocks
+	                this._iv = undefined;
+	            }
+
+				incCounter(counter);
+
+				var keystream = counter.slice(0);
+	            cipher.encryptBlock(keystream, 0);
+
+	            // Encrypt
+	            for (var i = 0; i < blockSize; i++) {
+	                words[offset + i] ^= keystream[i];
+	            }
+	        }
+	    });
+
+	    CTRGladman.Decryptor = Encryptor;
+
+	    return CTRGladman;
+	}());
+
+
+
+
+	/**
+	 * Output Feedback block mode.
+	 */
+	CryptoJS.mode.OFB = (function () {
+	    var OFB = CryptoJS.lib.BlockCipherMode.extend();
+
+	    var Encryptor = OFB.Encryptor = OFB.extend({
+	        processBlock: function (words, offset) {
+	            // Shortcuts
+	            var cipher = this._cipher
+	            var blockSize = cipher.blockSize;
+	            var iv = this._iv;
+	            var keystream = this._keystream;
+
+	            // Generate keystream
+	            if (iv) {
+	                keystream = this._keystream = iv.slice(0);
+
+	                // Remove IV for subsequent blocks
+	                this._iv = undefined;
+	            }
+	            cipher.encryptBlock(keystream, 0);
+
+	            // Encrypt
+	            for (var i = 0; i < blockSize; i++) {
+	                words[offset + i] ^= keystream[i];
+	            }
+	        }
+	    });
+
+	    OFB.Decryptor = Encryptor;
+
+	    return OFB;
+	}());
+
+
+	/**
+	 * Electronic Codebook block mode.
+	 */
+	CryptoJS.mode.ECB = (function () {
+	    var ECB = CryptoJS.lib.BlockCipherMode.extend();
+
+	    ECB.Encryptor = ECB.extend({
+	        processBlock: function (words, offset) {
+	            this._cipher.encryptBlock(words, offset);
+	        }
+	    });
+
+	    ECB.Decryptor = ECB.extend({
+	        processBlock: function (words, offset) {
+	            this._cipher.decryptBlock(words, offset);
+	        }
+	    });
+
+	    return ECB;
+	}());
+
+
+	/**
+	 * ANSI X.923 padding strategy.
+	 */
+	CryptoJS.pad.AnsiX923 = {
+	    pad: function (data, blockSize) {
+	        // Shortcuts
+	        var dataSigBytes = data.sigBytes;
+	        var blockSizeBytes = blockSize * 4;
+
+	        // Count padding bytes
+	        var nPaddingBytes = blockSizeBytes - dataSigBytes % blockSizeBytes;
+
+	        // Compute last byte position
+	        var lastBytePos = dataSigBytes + nPaddingBytes - 1;
+
+	        // Pad
+	        data.clamp();
+	        data.words[lastBytePos >>> 2] |= nPaddingBytes << (24 - (lastBytePos % 4) * 8);
+	        data.sigBytes += nPaddingBytes;
+	    },
+
+	    unpad: function (data) {
+	        // Get number of padding bytes from last byte
+	        var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
+
+	        // Remove padding
+	        data.sigBytes -= nPaddingBytes;
+	    }
+	};
+
+
+	/**
+	 * ISO 10126 padding strategy.
+	 */
+	CryptoJS.pad.Iso10126 = {
+	    pad: function (data, blockSize) {
+	        // Shortcut
+	        var blockSizeBytes = blockSize * 4;
+
+	        // Count padding bytes
+	        var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
+
+	        // Pad
+	        data.concat(CryptoJS.lib.WordArray.random(nPaddingBytes - 1)).
+	             concat(CryptoJS.lib.WordArray.create([nPaddingBytes << 24], 1));
+	    },
+
+	    unpad: function (data) {
+	        // Get number of padding bytes from last byte
+	        var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
+
+	        // Remove padding
+	        data.sigBytes -= nPaddingBytes;
+	    }
+	};
+
+
+	/**
+	 * ISO/IEC 9797-1 Padding Method 2.
+	 */
+	CryptoJS.pad.Iso97971 = {
+	    pad: function (data, blockSize) {
+	        // Add 0x80 byte
+	        data.concat(CryptoJS.lib.WordArray.create([0x80000000], 1));
+
+	        // Zero pad the rest
+	        CryptoJS.pad.ZeroPadding.pad(data, blockSize);
+	    },
+
+	    unpad: function (data) {
+	        // Remove zero padding
+	        CryptoJS.pad.ZeroPadding.unpad(data);
+
+	        // Remove one more byte -- the 0x80 byte
+	        data.sigBytes--;
+	    }
+	};
+
+
+	/**
+	 * Zero padding strategy.
+	 */
+	CryptoJS.pad.ZeroPadding = {
+	    pad: function (data, blockSize) {
+	        // Shortcut
+	        var blockSizeBytes = blockSize * 4;
+
+	        // Pad
+	        data.clamp();
+	        data.sigBytes += blockSizeBytes - ((data.sigBytes % blockSizeBytes) || blockSizeBytes);
+	    },
+
+	    unpad: function (data) {
+	        // Shortcut
+	        var dataWords = data.words;
+
+	        // Unpad
+	        var i = data.sigBytes - 1;
+	        for (var i = data.sigBytes - 1; i >= 0; i--) {
+	            if (((dataWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff)) {
+	                data.sigBytes = i + 1;
+	                break;
+	            }
+	        }
+	    }
+	};
+
+
+	/**
+	 * A noop padding strategy.
+	 */
+	CryptoJS.pad.NoPadding = {
+	    pad: function () {
+	    },
+
+	    unpad: function () {
+	    }
+	};
+
+
+	(function (undefined) {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var CipherParams = C_lib.CipherParams;
+	    var C_enc = C.enc;
+	    var Hex = C_enc.Hex;
+	    var C_format = C.format;
+
+	    var HexFormatter = C_format.Hex = {
+	        /**
+	         * Converts the ciphertext of a cipher params object to a hexadecimally encoded string.
+	         *
+	         * @param {CipherParams} cipherParams The cipher params object.
+	         *
+	         * @return {string} The hexadecimally encoded string.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var hexString = CryptoJS.format.Hex.stringify(cipherParams);
+	         */
+	        stringify: function (cipherParams) {
+	            return cipherParams.ciphertext.toString(Hex);
+	        },
+
+	        /**
+	         * Converts a hexadecimally encoded ciphertext string to a cipher params object.
+	         *
+	         * @param {string} input The hexadecimally encoded string.
+	         *
+	         * @return {CipherParams} The cipher params object.
+	         *
+	         * @static
+	         *
+	         * @example
+	         *
+	         *     var cipherParams = CryptoJS.format.Hex.parse(hexString);
+	         */
+	        parse: function (input) {
+	            var ciphertext = Hex.parse(input);
+	            return CipherParams.create({ ciphertext: ciphertext });
+	        }
+	    };
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var BlockCipher = C_lib.BlockCipher;
+	    var C_algo = C.algo;
+
+	    // Lookup tables
+	    var SBOX = [];
+	    var INV_SBOX = [];
+	    var SUB_MIX_0 = [];
+	    var SUB_MIX_1 = [];
+	    var SUB_MIX_2 = [];
+	    var SUB_MIX_3 = [];
+	    var INV_SUB_MIX_0 = [];
+	    var INV_SUB_MIX_1 = [];
+	    var INV_SUB_MIX_2 = [];
+	    var INV_SUB_MIX_3 = [];
+
+	    // Compute lookup tables
+	    (function () {
+	        // Compute double table
+	        var d = [];
+	        for (var i = 0; i < 256; i++) {
+	            if (i < 128) {
+	                d[i] = i << 1;
+	            } else {
+	                d[i] = (i << 1) ^ 0x11b;
+	            }
+	        }
+
+	        // Walk GF(2^8)
+	        var x = 0;
+	        var xi = 0;
+	        for (var i = 0; i < 256; i++) {
+	            // Compute sbox
+	            var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
+	            sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
+	            SBOX[x] = sx;
+	            INV_SBOX[sx] = x;
+
+	            // Compute multiplication
+	            var x2 = d[x];
+	            var x4 = d[x2];
+	            var x8 = d[x4];
+
+	            // Compute sub bytes, mix columns tables
+	            var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
+	            SUB_MIX_0[x] = (t << 24) | (t >>> 8);
+	            SUB_MIX_1[x] = (t << 16) | (t >>> 16);
+	            SUB_MIX_2[x] = (t << 8)  | (t >>> 24);
+	            SUB_MIX_3[x] = t;
+
+	            // Compute inv sub bytes, inv mix columns tables
+	            var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
+	            INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
+	            INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
+	            INV_SUB_MIX_2[sx] = (t << 8)  | (t >>> 24);
+	            INV_SUB_MIX_3[sx] = t;
+
+	            // Compute next counter
+	            if (!x) {
+	                x = xi = 1;
+	            } else {
+	                x = x2 ^ d[d[d[x8 ^ x2]]];
+	                xi ^= d[d[xi]];
+	            }
+	        }
+	    }());
+
+	    // Precomputed Rcon lookup
+	    var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
+
+	    /**
+	     * AES block cipher algorithm.
+	     */
+	    var AES = C_algo.AES = BlockCipher.extend({
+	        _doReset: function () {
+	            var t;
+
+	            // Skip reset of nRounds has been set before and key did not change
+	            if (this._nRounds && this._keyPriorReset === this._key) {
+	                return;
+	            }
+
+	            // Shortcuts
+	            var key = this._keyPriorReset = this._key;
+	            var keyWords = key.words;
+	            var keySize = key.sigBytes / 4;
+
+	            // Compute number of rounds
+	            var nRounds = this._nRounds = keySize + 6;
+
+	            // Compute number of key schedule rows
+	            var ksRows = (nRounds + 1) * 4;
+
+	            // Compute key schedule
+	            var keySchedule = this._keySchedule = [];
+	            for (var ksRow = 0; ksRow < ksRows; ksRow++) {
+	                if (ksRow < keySize) {
+	                    keySchedule[ksRow] = keyWords[ksRow];
+	                } else {
+	                    t = keySchedule[ksRow - 1];
+
+	                    if (!(ksRow % keySize)) {
+	                        // Rot word
+	                        t = (t << 8) | (t >>> 24);
+
+	                        // Sub word
+	                        t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
+
+	                        // Mix Rcon
+	                        t ^= RCON[(ksRow / keySize) | 0] << 24;
+	                    } else if (keySize > 6 && ksRow % keySize == 4) {
+	                        // Sub word
+	                        t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
+	                    }
+
+	                    keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
+	                }
+	            }
+
+	            // Compute inv key schedule
+	            var invKeySchedule = this._invKeySchedule = [];
+	            for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
+	                var ksRow = ksRows - invKsRow;
+
+	                if (invKsRow % 4) {
+	                    var t = keySchedule[ksRow];
+	                } else {
+	                    var t = keySchedule[ksRow - 4];
+	                }
+
+	                if (invKsRow < 4 || ksRow <= 4) {
+	                    invKeySchedule[invKsRow] = t;
+	                } else {
+	                    invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
+	                                               INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
+	                }
+	            }
+	        },
+
+	        encryptBlock: function (M, offset) {
+	            this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
+	        },
+
+	        decryptBlock: function (M, offset) {
+	            // Swap 2nd and 4th rows
+	            var t = M[offset + 1];
+	            M[offset + 1] = M[offset + 3];
+	            M[offset + 3] = t;
+
+	            this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
+
+	            // Inv swap 2nd and 4th rows
+	            var t = M[offset + 1];
+	            M[offset + 1] = M[offset + 3];
+	            M[offset + 3] = t;
+	        },
+
+	        _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
+	            // Shortcut
+	            var nRounds = this._nRounds;
+
+	            // Get input, add round key
+	            var s0 = M[offset]     ^ keySchedule[0];
+	            var s1 = M[offset + 1] ^ keySchedule[1];
+	            var s2 = M[offset + 2] ^ keySchedule[2];
+	            var s3 = M[offset + 3] ^ keySchedule[3];
+
+	            // Key schedule row counter
+	            var ksRow = 4;
+
+	            // Rounds
+	            for (var round = 1; round < nRounds; round++) {
+	                // Shift rows, sub bytes, mix columns, add round key
+	                var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
+	                var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
+	                var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
+	                var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
+
+	                // Update state
+	                s0 = t0;
+	                s1 = t1;
+	                s2 = t2;
+	                s3 = t3;
+	            }
+
+	            // Shift rows, sub bytes, add round key
+	            var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
+	            var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
+	            var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
+	            var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
+
+	            // Set output
+	            M[offset]     = t0;
+	            M[offset + 1] = t1;
+	            M[offset + 2] = t2;
+	            M[offset + 3] = t3;
+	        },
+
+	        keySize: 256/32
+	    });
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);
+	     */
+	    C.AES = BlockCipher._createHelper(AES);
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var WordArray = C_lib.WordArray;
+	    var BlockCipher = C_lib.BlockCipher;
+	    var C_algo = C.algo;
+
+	    // Permuted Choice 1 constants
+	    var PC1 = [
+	        57, 49, 41, 33, 25, 17, 9,  1,
+	        58, 50, 42, 34, 26, 18, 10, 2,
+	        59, 51, 43, 35, 27, 19, 11, 3,
+	        60, 52, 44, 36, 63, 55, 47, 39,
+	        31, 23, 15, 7,  62, 54, 46, 38,
+	        30, 22, 14, 6,  61, 53, 45, 37,
+	        29, 21, 13, 5,  28, 20, 12, 4
+	    ];
+
+	    // Permuted Choice 2 constants
+	    var PC2 = [
+	        14, 17, 11, 24, 1,  5,
+	        3,  28, 15, 6,  21, 10,
+	        23, 19, 12, 4,  26, 8,
+	        16, 7,  27, 20, 13, 2,
+	        41, 52, 31, 37, 47, 55,
+	        30, 40, 51, 45, 33, 48,
+	        44, 49, 39, 56, 34, 53,
+	        46, 42, 50, 36, 29, 32
+	    ];
+
+	    // Cumulative bit shift constants
+	    var BIT_SHIFTS = [1,  2,  4,  6,  8,  10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];
+
+	    // SBOXes and round permutation constants
+	    var SBOX_P = [
+	        {
+	            0x0: 0x808200,
+	            0x10000000: 0x8000,
+	            0x20000000: 0x808002,
+	            0x30000000: 0x2,
+	            0x40000000: 0x200,
+	            0x50000000: 0x808202,
+	            0x60000000: 0x800202,
+	            0x70000000: 0x800000,
+	            0x80000000: 0x202,
+	            0x90000000: 0x800200,
+	            0xa0000000: 0x8200,
+	            0xb0000000: 0x808000,
+	            0xc0000000: 0x8002,
+	            0xd0000000: 0x800002,
+	            0xe0000000: 0x0,
+	            0xf0000000: 0x8202,
+	            0x8000000: 0x0,
+	            0x18000000: 0x808202,
+	            0x28000000: 0x8202,
+	            0x38000000: 0x8000,
+	            0x48000000: 0x808200,
+	            0x58000000: 0x200,
+	            0x68000000: 0x808002,
+	            0x78000000: 0x2,
+	            0x88000000: 0x800200,
+	            0x98000000: 0x8200,
+	            0xa8000000: 0x808000,
+	            0xb8000000: 0x800202,
+	            0xc8000000: 0x800002,
+	            0xd8000000: 0x8002,
+	            0xe8000000: 0x202,
+	            0xf8000000: 0x800000,
+	            0x1: 0x8000,
+	            0x10000001: 0x2,
+	            0x20000001: 0x808200,
+	            0x30000001: 0x800000,
+	            0x40000001: 0x808002,
+	            0x50000001: 0x8200,
+	            0x60000001: 0x200,
+	            0x70000001: 0x800202,
+	            0x80000001: 0x808202,
+	            0x90000001: 0x808000,
+	            0xa0000001: 0x800002,
+	            0xb0000001: 0x8202,
+	            0xc0000001: 0x202,
+	            0xd0000001: 0x800200,
+	            0xe0000001: 0x8002,
+	            0xf0000001: 0x0,
+	            0x8000001: 0x808202,
+	            0x18000001: 0x808000,
+	            0x28000001: 0x800000,
+	            0x38000001: 0x200,
+	            0x48000001: 0x8000,
+	            0x58000001: 0x800002,
+	            0x68000001: 0x2,
+	            0x78000001: 0x8202,
+	            0x88000001: 0x8002,
+	            0x98000001: 0x800202,
+	            0xa8000001: 0x202,
+	            0xb8000001: 0x808200,
+	            0xc8000001: 0x800200,
+	            0xd8000001: 0x0,
+	            0xe8000001: 0x8200,
+	            0xf8000001: 0x808002
+	        },
+	        {
+	            0x0: 0x40084010,
+	            0x1000000: 0x4000,
+	            0x2000000: 0x80000,
+	            0x3000000: 0x40080010,
+	            0x4000000: 0x40000010,
+	            0x5000000: 0x40084000,
+	            0x6000000: 0x40004000,
+	            0x7000000: 0x10,
+	            0x8000000: 0x84000,
+	            0x9000000: 0x40004010,
+	            0xa000000: 0x40000000,
+	            0xb000000: 0x84010,
+	            0xc000000: 0x80010,
+	            0xd000000: 0x0,
+	            0xe000000: 0x4010,
+	            0xf000000: 0x40080000,
+	            0x800000: 0x40004000,
+	            0x1800000: 0x84010,
+	            0x2800000: 0x10,
+	            0x3800000: 0x40004010,
+	            0x4800000: 0x40084010,
+	            0x5800000: 0x40000000,
+	            0x6800000: 0x80000,
+	            0x7800000: 0x40080010,
+	            0x8800000: 0x80010,
+	            0x9800000: 0x0,
+	            0xa800000: 0x4000,
+	            0xb800000: 0x40080000,
+	            0xc800000: 0x40000010,
+	            0xd800000: 0x84000,
+	            0xe800000: 0x40084000,
+	            0xf800000: 0x4010,
+	            0x10000000: 0x0,
+	            0x11000000: 0x40080010,
+	            0x12000000: 0x40004010,
+	            0x13000000: 0x40084000,
+	            0x14000000: 0x40080000,
+	            0x15000000: 0x10,
+	            0x16000000: 0x84010,
+	            0x17000000: 0x4000,
+	            0x18000000: 0x4010,
+	            0x19000000: 0x80000,
+	            0x1a000000: 0x80010,
+	            0x1b000000: 0x40000010,
+	            0x1c000000: 0x84000,
+	            0x1d000000: 0x40004000,
+	            0x1e000000: 0x40000000,
+	            0x1f000000: 0x40084010,
+	            0x10800000: 0x84010,
+	            0x11800000: 0x80000,
+	            0x12800000: 0x40080000,
+	            0x13800000: 0x4000,
+	            0x14800000: 0x40004000,
+	            0x15800000: 0x40084010,
+	            0x16800000: 0x10,
+	            0x17800000: 0x40000000,
+	            0x18800000: 0x40084000,
+	            0x19800000: 0x40000010,
+	            0x1a800000: 0x40004010,
+	            0x1b800000: 0x80010,
+	            0x1c800000: 0x0,
+	            0x1d800000: 0x4010,
+	            0x1e800000: 0x40080010,
+	            0x1f800000: 0x84000
+	        },
+	        {
+	            0x0: 0x104,
+	            0x100000: 0x0,
+	            0x200000: 0x4000100,
+	            0x300000: 0x10104,
+	            0x400000: 0x10004,
+	            0x500000: 0x4000004,
+	            0x600000: 0x4010104,
+	            0x700000: 0x4010000,
+	            0x800000: 0x4000000,
+	            0x900000: 0x4010100,
+	            0xa00000: 0x10100,
+	            0xb00000: 0x4010004,
+	            0xc00000: 0x4000104,
+	            0xd00000: 0x10000,
+	            0xe00000: 0x4,
+	            0xf00000: 0x100,
+	            0x80000: 0x4010100,
+	            0x180000: 0x4010004,
+	            0x280000: 0x0,
+	            0x380000: 0x4000100,
+	            0x480000: 0x4000004,
+	            0x580000: 0x10000,
+	            0x680000: 0x10004,
+	            0x780000: 0x104,
+	            0x880000: 0x4,
+	            0x980000: 0x100,
+	            0xa80000: 0x4010000,
+	            0xb80000: 0x10104,
+	            0xc80000: 0x10100,
+	            0xd80000: 0x4000104,
+	            0xe80000: 0x4010104,
+	            0xf80000: 0x4000000,
+	            0x1000000: 0x4010100,
+	            0x1100000: 0x10004,
+	            0x1200000: 0x10000,
+	            0x1300000: 0x4000100,
+	            0x1400000: 0x100,
+	            0x1500000: 0x4010104,
+	            0x1600000: 0x4000004,
+	            0x1700000: 0x0,
+	            0x1800000: 0x4000104,
+	            0x1900000: 0x4000000,
+	            0x1a00000: 0x4,
+	            0x1b00000: 0x10100,
+	            0x1c00000: 0x4010000,
+	            0x1d00000: 0x104,
+	            0x1e00000: 0x10104,
+	            0x1f00000: 0x4010004,
+	            0x1080000: 0x4000000,
+	            0x1180000: 0x104,
+	            0x1280000: 0x4010100,
+	            0x1380000: 0x0,
+	            0x1480000: 0x10004,
+	            0x1580000: 0x4000100,
+	            0x1680000: 0x100,
+	            0x1780000: 0x4010004,
+	            0x1880000: 0x10000,
+	            0x1980000: 0x4010104,
+	            0x1a80000: 0x10104,
+	            0x1b80000: 0x4000004,
+	            0x1c80000: 0x4000104,
+	            0x1d80000: 0x4010000,
+	            0x1e80000: 0x4,
+	            0x1f80000: 0x10100
+	        },
+	        {
+	            0x0: 0x80401000,
+	            0x10000: 0x80001040,
+	            0x20000: 0x401040,
+	            0x30000: 0x80400000,
+	            0x40000: 0x0,
+	            0x50000: 0x401000,
+	            0x60000: 0x80000040,
+	            0x70000: 0x400040,
+	            0x80000: 0x80000000,
+	            0x90000: 0x400000,
+	            0xa0000: 0x40,
+	            0xb0000: 0x80001000,
+	            0xc0000: 0x80400040,
+	            0xd0000: 0x1040,
+	            0xe0000: 0x1000,
+	            0xf0000: 0x80401040,
+	            0x8000: 0x80001040,
+	            0x18000: 0x40,
+	            0x28000: 0x80400040,
+	            0x38000: 0x80001000,
+	            0x48000: 0x401000,
+	            0x58000: 0x80401040,
+	            0x68000: 0x0,
+	            0x78000: 0x80400000,
+	            0x88000: 0x1000,
+	            0x98000: 0x80401000,
+	            0xa8000: 0x400000,
+	            0xb8000: 0x1040,
+	            0xc8000: 0x80000000,
+	            0xd8000: 0x400040,
+	            0xe8000: 0x401040,
+	            0xf8000: 0x80000040,
+	            0x100000: 0x400040,
+	            0x110000: 0x401000,
+	            0x120000: 0x80000040,
+	            0x130000: 0x0,
+	            0x140000: 0x1040,
+	            0x150000: 0x80400040,
+	            0x160000: 0x80401000,
+	            0x170000: 0x80001040,
+	            0x180000: 0x80401040,
+	            0x190000: 0x80000000,
+	            0x1a0000: 0x80400000,
+	            0x1b0000: 0x401040,
+	            0x1c0000: 0x80001000,
+	            0x1d0000: 0x400000,
+	            0x1e0000: 0x40,
+	            0x1f0000: 0x1000,
+	            0x108000: 0x80400000,
+	            0x118000: 0x80401040,
+	            0x128000: 0x0,
+	            0x138000: 0x401000,
+	            0x148000: 0x400040,
+	            0x158000: 0x80000000,
+	            0x168000: 0x80001040,
+	            0x178000: 0x40,
+	            0x188000: 0x80000040,
+	            0x198000: 0x1000,
+	            0x1a8000: 0x80001000,
+	            0x1b8000: 0x80400040,
+	            0x1c8000: 0x1040,
+	            0x1d8000: 0x80401000,
+	            0x1e8000: 0x400000,
+	            0x1f8000: 0x401040
+	        },
+	        {
+	            0x0: 0x80,
+	            0x1000: 0x1040000,
+	            0x2000: 0x40000,
+	            0x3000: 0x20000000,
+	            0x4000: 0x20040080,
+	            0x5000: 0x1000080,
+	            0x6000: 0x21000080,
+	            0x7000: 0x40080,
+	            0x8000: 0x1000000,
+	            0x9000: 0x20040000,
+	            0xa000: 0x20000080,
+	            0xb000: 0x21040080,
+	            0xc000: 0x21040000,
+	            0xd000: 0x0,
+	            0xe000: 0x1040080,
+	            0xf000: 0x21000000,
+	            0x800: 0x1040080,
+	            0x1800: 0x21000080,
+	            0x2800: 0x80,
+	            0x3800: 0x1040000,
+	            0x4800: 0x40000,
+	            0x5800: 0x20040080,
+	            0x6800: 0x21040000,
+	            0x7800: 0x20000000,
+	            0x8800: 0x20040000,
+	            0x9800: 0x0,
+	            0xa800: 0x21040080,
+	            0xb800: 0x1000080,
+	            0xc800: 0x20000080,
+	            0xd800: 0x21000000,
+	            0xe800: 0x1000000,
+	            0xf800: 0x40080,
+	            0x10000: 0x40000,
+	            0x11000: 0x80,
+	            0x12000: 0x20000000,
+	            0x13000: 0x21000080,
+	            0x14000: 0x1000080,
+	            0x15000: 0x21040000,
+	            0x16000: 0x20040080,
+	            0x17000: 0x1000000,
+	            0x18000: 0x21040080,
+	            0x19000: 0x21000000,
+	            0x1a000: 0x1040000,
+	            0x1b000: 0x20040000,
+	            0x1c000: 0x40080,
+	            0x1d000: 0x20000080,
+	            0x1e000: 0x0,
+	            0x1f000: 0x1040080,
+	            0x10800: 0x21000080,
+	            0x11800: 0x1000000,
+	            0x12800: 0x1040000,
+	            0x13800: 0x20040080,
+	            0x14800: 0x20000000,
+	            0x15800: 0x1040080,
+	            0x16800: 0x80,
+	            0x17800: 0x21040000,
+	            0x18800: 0x40080,
+	            0x19800: 0x21040080,
+	            0x1a800: 0x0,
+	            0x1b800: 0x21000000,
+	            0x1c800: 0x1000080,
+	            0x1d800: 0x40000,
+	            0x1e800: 0x20040000,
+	            0x1f800: 0x20000080
+	        },
+	        {
+	            0x0: 0x10000008,
+	            0x100: 0x2000,
+	            0x200: 0x10200000,
+	            0x300: 0x10202008,
+	            0x400: 0x10002000,
+	            0x500: 0x200000,
+	            0x600: 0x200008,
+	            0x700: 0x10000000,
+	            0x800: 0x0,
+	            0x900: 0x10002008,
+	            0xa00: 0x202000,
+	            0xb00: 0x8,
+	            0xc00: 0x10200008,
+	            0xd00: 0x202008,
+	            0xe00: 0x2008,
+	            0xf00: 0x10202000,
+	            0x80: 0x10200000,
+	            0x180: 0x10202008,
+	            0x280: 0x8,
+	            0x380: 0x200000,
+	            0x480: 0x202008,
+	            0x580: 0x10000008,
+	            0x680: 0x10002000,
+	            0x780: 0x2008,
+	            0x880: 0x200008,
+	            0x980: 0x2000,
+	            0xa80: 0x10002008,
+	            0xb80: 0x10200008,
+	            0xc80: 0x0,
+	            0xd80: 0x10202000,
+	            0xe80: 0x202000,
+	            0xf80: 0x10000000,
+	            0x1000: 0x10002000,
+	            0x1100: 0x10200008,
+	            0x1200: 0x10202008,
+	            0x1300: 0x2008,
+	            0x1400: 0x200000,
+	            0x1500: 0x10000000,
+	            0x1600: 0x10000008,
+	            0x1700: 0x202000,
+	            0x1800: 0x202008,
+	            0x1900: 0x0,
+	            0x1a00: 0x8,
+	            0x1b00: 0x10200000,
+	            0x1c00: 0x2000,
+	            0x1d00: 0x10002008,
+	            0x1e00: 0x10202000,
+	            0x1f00: 0x200008,
+	            0x1080: 0x8,
+	            0x1180: 0x202000,
+	            0x1280: 0x200000,
+	            0x1380: 0x10000008,
+	            0x1480: 0x10002000,
+	            0x1580: 0x2008,
+	            0x1680: 0x10202008,
+	            0x1780: 0x10200000,
+	            0x1880: 0x10202000,
+	            0x1980: 0x10200008,
+	            0x1a80: 0x2000,
+	            0x1b80: 0x202008,
+	            0x1c80: 0x200008,
+	            0x1d80: 0x0,
+	            0x1e80: 0x10000000,
+	            0x1f80: 0x10002008
+	        },
+	        {
+	            0x0: 0x100000,
+	            0x10: 0x2000401,
+	            0x20: 0x400,
+	            0x30: 0x100401,
+	            0x40: 0x2100401,
+	            0x50: 0x0,
+	            0x60: 0x1,
+	            0x70: 0x2100001,
+	            0x80: 0x2000400,
+	            0x90: 0x100001,
+	            0xa0: 0x2000001,
+	            0xb0: 0x2100400,
+	            0xc0: 0x2100000,
+	            0xd0: 0x401,
+	            0xe0: 0x100400,
+	            0xf0: 0x2000000,
+	            0x8: 0x2100001,
+	            0x18: 0x0,
+	            0x28: 0x2000401,
+	            0x38: 0x2100400,
+	            0x48: 0x100000,
+	            0x58: 0x2000001,
+	            0x68: 0x2000000,
+	            0x78: 0x401,
+	            0x88: 0x100401,
+	            0x98: 0x2000400,
+	            0xa8: 0x2100000,
+	            0xb8: 0x100001,
+	            0xc8: 0x400,
+	            0xd8: 0x2100401,
+	            0xe8: 0x1,
+	            0xf8: 0x100400,
+	            0x100: 0x2000000,
+	            0x110: 0x100000,
+	            0x120: 0x2000401,
+	            0x130: 0x2100001,
+	            0x140: 0x100001,
+	            0x150: 0x2000400,
+	            0x160: 0x2100400,
+	            0x170: 0x100401,
+	            0x180: 0x401,
+	            0x190: 0x2100401,
+	            0x1a0: 0x100400,
+	            0x1b0: 0x1,
+	            0x1c0: 0x0,
+	            0x1d0: 0x2100000,
+	            0x1e0: 0x2000001,
+	            0x1f0: 0x400,
+	            0x108: 0x100400,
+	            0x118: 0x2000401,
+	            0x128: 0x2100001,
+	            0x138: 0x1,
+	            0x148: 0x2000000,
+	            0x158: 0x100000,
+	            0x168: 0x401,
+	            0x178: 0x2100400,
+	            0x188: 0x2000001,
+	            0x198: 0x2100000,
+	            0x1a8: 0x0,
+	            0x1b8: 0x2100401,
+	            0x1c8: 0x100401,
+	            0x1d8: 0x400,
+	            0x1e8: 0x2000400,
+	            0x1f8: 0x100001
+	        },
+	        {
+	            0x0: 0x8000820,
+	            0x1: 0x20000,
+	            0x2: 0x8000000,
+	            0x3: 0x20,
+	            0x4: 0x20020,
+	            0x5: 0x8020820,
+	            0x6: 0x8020800,
+	            0x7: 0x800,
+	            0x8: 0x8020000,
+	            0x9: 0x8000800,
+	            0xa: 0x20800,
+	            0xb: 0x8020020,
+	            0xc: 0x820,
+	            0xd: 0x0,
+	            0xe: 0x8000020,
+	            0xf: 0x20820,
+	            0x80000000: 0x800,
+	            0x80000001: 0x8020820,
+	            0x80000002: 0x8000820,
+	            0x80000003: 0x8000000,
+	            0x80000004: 0x8020000,
+	            0x80000005: 0x20800,
+	            0x80000006: 0x20820,
+	            0x80000007: 0x20,
+	            0x80000008: 0x8000020,
+	            0x80000009: 0x820,
+	            0x8000000a: 0x20020,
+	            0x8000000b: 0x8020800,
+	            0x8000000c: 0x0,
+	            0x8000000d: 0x8020020,
+	            0x8000000e: 0x8000800,
+	            0x8000000f: 0x20000,
+	            0x10: 0x20820,
+	            0x11: 0x8020800,
+	            0x12: 0x20,
+	            0x13: 0x800,
+	            0x14: 0x8000800,
+	            0x15: 0x8000020,
+	            0x16: 0x8020020,
+	            0x17: 0x20000,
+	            0x18: 0x0,
+	            0x19: 0x20020,
+	            0x1a: 0x8020000,
+	            0x1b: 0x8000820,
+	            0x1c: 0x8020820,
+	            0x1d: 0x20800,
+	            0x1e: 0x820,
+	            0x1f: 0x8000000,
+	            0x80000010: 0x20000,
+	            0x80000011: 0x800,
+	            0x80000012: 0x8020020,
+	            0x80000013: 0x20820,
+	            0x80000014: 0x20,
+	            0x80000015: 0x8020000,
+	            0x80000016: 0x8000000,
+	            0x80000017: 0x8000820,
+	            0x80000018: 0x8020820,
+	            0x80000019: 0x8000020,
+	            0x8000001a: 0x8000800,
+	            0x8000001b: 0x0,
+	            0x8000001c: 0x20800,
+	            0x8000001d: 0x820,
+	            0x8000001e: 0x20020,
+	            0x8000001f: 0x8020800
+	        }
+	    ];
+
+	    // Masks that select the SBOX input
+	    var SBOX_MASK = [
+	        0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
+	        0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f
+	    ];
+
+	    /**
+	     * DES block cipher algorithm.
+	     */
+	    var DES = C_algo.DES = BlockCipher.extend({
+	        _doReset: function () {
+	            // Shortcuts
+	            var key = this._key;
+	            var keyWords = key.words;
+
+	            // Select 56 bits according to PC1
+	            var keyBits = [];
+	            for (var i = 0; i < 56; i++) {
+	                var keyBitPos = PC1[i] - 1;
+	                keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;
+	            }
+
+	            // Assemble 16 subkeys
+	            var subKeys = this._subKeys = [];
+	            for (var nSubKey = 0; nSubKey < 16; nSubKey++) {
+	                // Create subkey
+	                var subKey = subKeys[nSubKey] = [];
+
+	                // Shortcut
+	                var bitShift = BIT_SHIFTS[nSubKey];
+
+	                // Select 48 bits according to PC2
+	                for (var i = 0; i < 24; i++) {
+	                    // Select from the left 28 key bits
+	                    subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);
+
+	                    // Select from the right 28 key bits
+	                    subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);
+	                }
+
+	                // Since each subkey is applied to an expanded 32-bit input,
+	                // the subkey can be broken into 8 values scaled to 32-bits,
+	                // which allows the key to be used without expansion
+	                subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);
+	                for (var i = 1; i < 7; i++) {
+	                    subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);
+	                }
+	                subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);
+	            }
+
+	            // Compute inverse subkeys
+	            var invSubKeys = this._invSubKeys = [];
+	            for (var i = 0; i < 16; i++) {
+	                invSubKeys[i] = subKeys[15 - i];
+	            }
+	        },
+
+	        encryptBlock: function (M, offset) {
+	            this._doCryptBlock(M, offset, this._subKeys);
+	        },
+
+	        decryptBlock: function (M, offset) {
+	            this._doCryptBlock(M, offset, this._invSubKeys);
+	        },
+
+	        _doCryptBlock: function (M, offset, subKeys) {
+	            // Get input
+	            this._lBlock = M[offset];
+	            this._rBlock = M[offset + 1];
+
+	            // Initial permutation
+	            exchangeLR.call(this, 4,  0x0f0f0f0f);
+	            exchangeLR.call(this, 16, 0x0000ffff);
+	            exchangeRL.call(this, 2,  0x33333333);
+	            exchangeRL.call(this, 8,  0x00ff00ff);
+	            exchangeLR.call(this, 1,  0x55555555);
+
+	            // Rounds
+	            for (var round = 0; round < 16; round++) {
+	                // Shortcuts
+	                var subKey = subKeys[round];
+	                var lBlock = this._lBlock;
+	                var rBlock = this._rBlock;
+
+	                // Feistel function
+	                var f = 0;
+	                for (var i = 0; i < 8; i++) {
+	                    f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];
+	                }
+	                this._lBlock = rBlock;
+	                this._rBlock = lBlock ^ f;
+	            }
+
+	            // Undo swap from last round
+	            var t = this._lBlock;
+	            this._lBlock = this._rBlock;
+	            this._rBlock = t;
+
+	            // Final permutation
+	            exchangeLR.call(this, 1,  0x55555555);
+	            exchangeRL.call(this, 8,  0x00ff00ff);
+	            exchangeRL.call(this, 2,  0x33333333);
+	            exchangeLR.call(this, 16, 0x0000ffff);
+	            exchangeLR.call(this, 4,  0x0f0f0f0f);
+
+	            // Set output
+	            M[offset] = this._lBlock;
+	            M[offset + 1] = this._rBlock;
+	        },
+
+	        keySize: 64/32,
+
+	        ivSize: 64/32,
+
+	        blockSize: 64/32
+	    });
+
+	    // Swap bits across the left and right words
+	    function exchangeLR(offset, mask) {
+	        var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;
+	        this._rBlock ^= t;
+	        this._lBlock ^= t << offset;
+	    }
+
+	    function exchangeRL(offset, mask) {
+	        var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;
+	        this._lBlock ^= t;
+	        this._rBlock ^= t << offset;
+	    }
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.DES.decrypt(ciphertext, key, cfg);
+	     */
+	    C.DES = BlockCipher._createHelper(DES);
+
+	    /**
+	     * Triple-DES block cipher algorithm.
+	     */
+	    var TripleDES = C_algo.TripleDES = BlockCipher.extend({
+	        _doReset: function () {
+	            // Shortcuts
+	            var key = this._key;
+	            var keyWords = key.words;
+	            // Make sure the key length is valid (64, 128 or >= 192 bit)
+	            if (keyWords.length !== 2 && keyWords.length !== 4 && keyWords.length < 6) {
+	                throw new Error('Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.');
+	            }
+
+	            // Extend the key according to the keying options defined in 3DES standard
+	            var key1 = keyWords.slice(0, 2);
+	            var key2 = keyWords.length < 4 ? keyWords.slice(0, 2) : keyWords.slice(2, 4);
+	            var key3 = keyWords.length < 6 ? keyWords.slice(0, 2) : keyWords.slice(4, 6);
+
+	            // Create DES instances
+	            this._des1 = DES.createEncryptor(WordArray.create(key1));
+	            this._des2 = DES.createEncryptor(WordArray.create(key2));
+	            this._des3 = DES.createEncryptor(WordArray.create(key3));
+	        },
+
+	        encryptBlock: function (M, offset) {
+	            this._des1.encryptBlock(M, offset);
+	            this._des2.decryptBlock(M, offset);
+	            this._des3.encryptBlock(M, offset);
+	        },
+
+	        decryptBlock: function (M, offset) {
+	            this._des3.decryptBlock(M, offset);
+	            this._des2.encryptBlock(M, offset);
+	            this._des1.decryptBlock(M, offset);
+	        },
+
+	        keySize: 192/32,
+
+	        ivSize: 64/32,
+
+	        blockSize: 64/32
+	    });
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);
+	     */
+	    C.TripleDES = BlockCipher._createHelper(TripleDES);
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var StreamCipher = C_lib.StreamCipher;
+	    var C_algo = C.algo;
+
+	    /**
+	     * RC4 stream cipher algorithm.
+	     */
+	    var RC4 = C_algo.RC4 = StreamCipher.extend({
+	        _doReset: function () {
+	            // Shortcuts
+	            var key = this._key;
+	            var keyWords = key.words;
+	            var keySigBytes = key.sigBytes;
+
+	            // Init sbox
+	            var S = this._S = [];
+	            for (var i = 0; i < 256; i++) {
+	                S[i] = i;
+	            }
+
+	            // Key setup
+	            for (var i = 0, j = 0; i < 256; i++) {
+	                var keyByteIndex = i % keySigBytes;
+	                var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff;
+
+	                j = (j + S[i] + keyByte) % 256;
+
+	                // Swap
+	                var t = S[i];
+	                S[i] = S[j];
+	                S[j] = t;
+	            }
+
+	            // Counters
+	            this._i = this._j = 0;
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            M[offset] ^= generateKeystreamWord.call(this);
+	        },
+
+	        keySize: 256/32,
+
+	        ivSize: 0
+	    });
+
+	    function generateKeystreamWord() {
+	        // Shortcuts
+	        var S = this._S;
+	        var i = this._i;
+	        var j = this._j;
+
+	        // Generate keystream word
+	        var keystreamWord = 0;
+	        for (var n = 0; n < 4; n++) {
+	            i = (i + 1) % 256;
+	            j = (j + S[i]) % 256;
+
+	            // Swap
+	            var t = S[i];
+	            S[i] = S[j];
+	            S[j] = t;
+
+	            keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8);
+	        }
+
+	        // Update counters
+	        this._i = i;
+	        this._j = j;
+
+	        return keystreamWord;
+	    }
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.RC4.decrypt(ciphertext, key, cfg);
+	     */
+	    C.RC4 = StreamCipher._createHelper(RC4);
+
+	    /**
+	     * Modified RC4 stream cipher algorithm.
+	     */
+	    var RC4Drop = C_algo.RC4Drop = RC4.extend({
+	        /**
+	         * Configuration options.
+	         *
+	         * @property {number} drop The number of keystream words to drop. Default 192
+	         */
+	        cfg: RC4.cfg.extend({
+	            drop: 192
+	        }),
+
+	        _doReset: function () {
+	            RC4._doReset.call(this);
+
+	            // Drop
+	            for (var i = this.cfg.drop; i > 0; i--) {
+	                generateKeystreamWord.call(this);
+	            }
+	        }
+	    });
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);
+	     */
+	    C.RC4Drop = StreamCipher._createHelper(RC4Drop);
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var StreamCipher = C_lib.StreamCipher;
+	    var C_algo = C.algo;
+
+	    // Reusable objects
+	    var S  = [];
+	    var C_ = [];
+	    var G  = [];
+
+	    /**
+	     * Rabbit stream cipher algorithm
+	     */
+	    var Rabbit = C_algo.Rabbit = StreamCipher.extend({
+	        _doReset: function () {
+	            // Shortcuts
+	            var K = this._key.words;
+	            var iv = this.cfg.iv;
+
+	            // Swap endian
+	            for (var i = 0; i < 4; i++) {
+	                K[i] = (((K[i] << 8)  | (K[i] >>> 24)) & 0x00ff00ff) |
+	                       (((K[i] << 24) | (K[i] >>> 8))  & 0xff00ff00);
+	            }
+
+	            // Generate initial state values
+	            var X = this._X = [
+	                K[0], (K[3] << 16) | (K[2] >>> 16),
+	                K[1], (K[0] << 16) | (K[3] >>> 16),
+	                K[2], (K[1] << 16) | (K[0] >>> 16),
+	                K[3], (K[2] << 16) | (K[1] >>> 16)
+	            ];
+
+	            // Generate initial counter values
+	            var C = this._C = [
+	                (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
+	                (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
+	                (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
+	                (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
+	            ];
+
+	            // Carry bit
+	            this._b = 0;
+
+	            // Iterate the system four times
+	            for (var i = 0; i < 4; i++) {
+	                nextState.call(this);
+	            }
+
+	            // Modify the counters
+	            for (var i = 0; i < 8; i++) {
+	                C[i] ^= X[(i + 4) & 7];
+	            }
+
+	            // IV setup
+	            if (iv) {
+	                // Shortcuts
+	                var IV = iv.words;
+	                var IV_0 = IV[0];
+	                var IV_1 = IV[1];
+
+	                // Generate four subvectors
+	                var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
+	                var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
+	                var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
+	                var i3 = (i2 << 16)  | (i0 & 0x0000ffff);
+
+	                // Modify counter values
+	                C[0] ^= i0;
+	                C[1] ^= i1;
+	                C[2] ^= i2;
+	                C[3] ^= i3;
+	                C[4] ^= i0;
+	                C[5] ^= i1;
+	                C[6] ^= i2;
+	                C[7] ^= i3;
+
+	                // Iterate the system four times
+	                for (var i = 0; i < 4; i++) {
+	                    nextState.call(this);
+	                }
+	            }
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Shortcut
+	            var X = this._X;
+
+	            // Iterate the system
+	            nextState.call(this);
+
+	            // Generate four keystream words
+	            S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
+	            S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
+	            S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
+	            S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
+
+	            for (var i = 0; i < 4; i++) {
+	                // Swap endian
+	                S[i] = (((S[i] << 8)  | (S[i] >>> 24)) & 0x00ff00ff) |
+	                       (((S[i] << 24) | (S[i] >>> 8))  & 0xff00ff00);
+
+	                // Encrypt
+	                M[offset + i] ^= S[i];
+	            }
+	        },
+
+	        blockSize: 128/32,
+
+	        ivSize: 64/32
+	    });
+
+	    function nextState() {
+	        // Shortcuts
+	        var X = this._X;
+	        var C = this._C;
+
+	        // Save old counter values
+	        for (var i = 0; i < 8; i++) {
+	            C_[i] = C[i];
+	        }
+
+	        // Calculate new counter values
+	        C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
+	        C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
+	        C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
+	        C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
+	        C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
+	        C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
+	        C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
+	        C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
+	        this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
+
+	        // Calculate the g-values
+	        for (var i = 0; i < 8; i++) {
+	            var gx = X[i] + C[i];
+
+	            // Construct high and low argument for squaring
+	            var ga = gx & 0xffff;
+	            var gb = gx >>> 16;
+
+	            // Calculate high and low result of squaring
+	            var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
+	            var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
+
+	            // High XOR low
+	            G[i] = gh ^ gl;
+	        }
+
+	        // Calculate new state values
+	        X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
+	        X[1] = (G[1] + ((G[0] << 8)  | (G[0] >>> 24)) + G[7]) | 0;
+	        X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
+	        X[3] = (G[3] + ((G[2] << 8)  | (G[2] >>> 24)) + G[1]) | 0;
+	        X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
+	        X[5] = (G[5] + ((G[4] << 8)  | (G[4] >>> 24)) + G[3]) | 0;
+	        X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
+	        X[7] = (G[7] + ((G[6] << 8)  | (G[6] >>> 24)) + G[5]) | 0;
+	    }
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg);
+	     */
+	    C.Rabbit = StreamCipher._createHelper(Rabbit);
+	}());
+
+
+	(function () {
+	    // Shortcuts
+	    var C = CryptoJS;
+	    var C_lib = C.lib;
+	    var StreamCipher = C_lib.StreamCipher;
+	    var C_algo = C.algo;
+
+	    // Reusable objects
+	    var S  = [];
+	    var C_ = [];
+	    var G  = [];
+
+	    /**
+	     * Rabbit stream cipher algorithm.
+	     *
+	     * This is a legacy version that neglected to convert the key to little-endian.
+	     * This error doesn't affect the cipher's security,
+	     * but it does affect its compatibility with other implementations.
+	     */
+	    var RabbitLegacy = C_algo.RabbitLegacy = StreamCipher.extend({
+	        _doReset: function () {
+	            // Shortcuts
+	            var K = this._key.words;
+	            var iv = this.cfg.iv;
+
+	            // Generate initial state values
+	            var X = this._X = [
+	                K[0], (K[3] << 16) | (K[2] >>> 16),
+	                K[1], (K[0] << 16) | (K[3] >>> 16),
+	                K[2], (K[1] << 16) | (K[0] >>> 16),
+	                K[3], (K[2] << 16) | (K[1] >>> 16)
+	            ];
+
+	            // Generate initial counter values
+	            var C = this._C = [
+	                (K[2] << 16) | (K[2] >>> 16), (K[0] & 0xffff0000) | (K[1] & 0x0000ffff),
+	                (K[3] << 16) | (K[3] >>> 16), (K[1] & 0xffff0000) | (K[2] & 0x0000ffff),
+	                (K[0] << 16) | (K[0] >>> 16), (K[2] & 0xffff0000) | (K[3] & 0x0000ffff),
+	                (K[1] << 16) | (K[1] >>> 16), (K[3] & 0xffff0000) | (K[0] & 0x0000ffff)
+	            ];
+
+	            // Carry bit
+	            this._b = 0;
+
+	            // Iterate the system four times
+	            for (var i = 0; i < 4; i++) {
+	                nextState.call(this);
+	            }
+
+	            // Modify the counters
+	            for (var i = 0; i < 8; i++) {
+	                C[i] ^= X[(i + 4) & 7];
+	            }
+
+	            // IV setup
+	            if (iv) {
+	                // Shortcuts
+	                var IV = iv.words;
+	                var IV_0 = IV[0];
+	                var IV_1 = IV[1];
+
+	                // Generate four subvectors
+	                var i0 = (((IV_0 << 8) | (IV_0 >>> 24)) & 0x00ff00ff) | (((IV_0 << 24) | (IV_0 >>> 8)) & 0xff00ff00);
+	                var i2 = (((IV_1 << 8) | (IV_1 >>> 24)) & 0x00ff00ff) | (((IV_1 << 24) | (IV_1 >>> 8)) & 0xff00ff00);
+	                var i1 = (i0 >>> 16) | (i2 & 0xffff0000);
+	                var i3 = (i2 << 16)  | (i0 & 0x0000ffff);
+
+	                // Modify counter values
+	                C[0] ^= i0;
+	                C[1] ^= i1;
+	                C[2] ^= i2;
+	                C[3] ^= i3;
+	                C[4] ^= i0;
+	                C[5] ^= i1;
+	                C[6] ^= i2;
+	                C[7] ^= i3;
+
+	                // Iterate the system four times
+	                for (var i = 0; i < 4; i++) {
+	                    nextState.call(this);
+	                }
+	            }
+	        },
+
+	        _doProcessBlock: function (M, offset) {
+	            // Shortcut
+	            var X = this._X;
+
+	            // Iterate the system
+	            nextState.call(this);
+
+	            // Generate four keystream words
+	            S[0] = X[0] ^ (X[5] >>> 16) ^ (X[3] << 16);
+	            S[1] = X[2] ^ (X[7] >>> 16) ^ (X[5] << 16);
+	            S[2] = X[4] ^ (X[1] >>> 16) ^ (X[7] << 16);
+	            S[3] = X[6] ^ (X[3] >>> 16) ^ (X[1] << 16);
+
+	            for (var i = 0; i < 4; i++) {
+	                // Swap endian
+	                S[i] = (((S[i] << 8)  | (S[i] >>> 24)) & 0x00ff00ff) |
+	                       (((S[i] << 24) | (S[i] >>> 8))  & 0xff00ff00);
+
+	                // Encrypt
+	                M[offset + i] ^= S[i];
+	            }
+	        },
+
+	        blockSize: 128/32,
+
+	        ivSize: 64/32
+	    });
+
+	    function nextState() {
+	        // Shortcuts
+	        var X = this._X;
+	        var C = this._C;
+
+	        // Save old counter values
+	        for (var i = 0; i < 8; i++) {
+	            C_[i] = C[i];
+	        }
+
+	        // Calculate new counter values
+	        C[0] = (C[0] + 0x4d34d34d + this._b) | 0;
+	        C[1] = (C[1] + 0xd34d34d3 + ((C[0] >>> 0) < (C_[0] >>> 0) ? 1 : 0)) | 0;
+	        C[2] = (C[2] + 0x34d34d34 + ((C[1] >>> 0) < (C_[1] >>> 0) ? 1 : 0)) | 0;
+	        C[3] = (C[3] + 0x4d34d34d + ((C[2] >>> 0) < (C_[2] >>> 0) ? 1 : 0)) | 0;
+	        C[4] = (C[4] + 0xd34d34d3 + ((C[3] >>> 0) < (C_[3] >>> 0) ? 1 : 0)) | 0;
+	        C[5] = (C[5] + 0x34d34d34 + ((C[4] >>> 0) < (C_[4] >>> 0) ? 1 : 0)) | 0;
+	        C[6] = (C[6] + 0x4d34d34d + ((C[5] >>> 0) < (C_[5] >>> 0) ? 1 : 0)) | 0;
+	        C[7] = (C[7] + 0xd34d34d3 + ((C[6] >>> 0) < (C_[6] >>> 0) ? 1 : 0)) | 0;
+	        this._b = (C[7] >>> 0) < (C_[7] >>> 0) ? 1 : 0;
+
+	        // Calculate the g-values
+	        for (var i = 0; i < 8; i++) {
+	            var gx = X[i] + C[i];
+
+	            // Construct high and low argument for squaring
+	            var ga = gx & 0xffff;
+	            var gb = gx >>> 16;
+
+	            // Calculate high and low result of squaring
+	            var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb;
+	            var gl = (((gx & 0xffff0000) * gx) | 0) + (((gx & 0x0000ffff) * gx) | 0);
+
+	            // High XOR low
+	            G[i] = gh ^ gl;
+	        }
+
+	        // Calculate new state values
+	        X[0] = (G[0] + ((G[7] << 16) | (G[7] >>> 16)) + ((G[6] << 16) | (G[6] >>> 16))) | 0;
+	        X[1] = (G[1] + ((G[0] << 8)  | (G[0] >>> 24)) + G[7]) | 0;
+	        X[2] = (G[2] + ((G[1] << 16) | (G[1] >>> 16)) + ((G[0] << 16) | (G[0] >>> 16))) | 0;
+	        X[3] = (G[3] + ((G[2] << 8)  | (G[2] >>> 24)) + G[1]) | 0;
+	        X[4] = (G[4] + ((G[3] << 16) | (G[3] >>> 16)) + ((G[2] << 16) | (G[2] >>> 16))) | 0;
+	        X[5] = (G[5] + ((G[4] << 8)  | (G[4] >>> 24)) + G[3]) | 0;
+	        X[6] = (G[6] + ((G[5] << 16) | (G[5] >>> 16)) + ((G[4] << 16) | (G[4] >>> 16))) | 0;
+	        X[7] = (G[7] + ((G[6] << 8)  | (G[6] >>> 24)) + G[5]) | 0;
+	    }
+
+	    /**
+	     * Shortcut functions to the cipher's object interface.
+	     *
+	     * @example
+	     *
+	     *     var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg);
+	     *     var plaintext  = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg);
+	     */
+	    C.RabbitLegacy = StreamCipher._createHelper(RabbitLegacy);
+	}());
+
+
+	return CryptoJS;
+
+}));

+ 27 - 0
app/assets/js/plupload-2.3.7/bower.json

@@ -0,0 +1,27 @@
+{
+	"name": "plupload",
+	"license": "AGPLv3",
+	"authors": [
+		"Davit Barbakadze <davit.barbakadze@ephox.com>"
+	],
+	"homepage": "http://plupload.com",
+	"repository": {
+		"type": "git",
+		"url": "https://github.com/moxiecode/plupload.git"
+	},
+	"main": [
+		"./js/plupload.full.min.js"
+	],
+	"ignore": [
+		"tests/",
+		"src/",
+		"build/",
+		"examples/",
+		"Jakefile.js",
+		"package.json",
+		"bower.json",
+		"composer.json",
+		"README.md",
+		".*"
+	]
+}

+ 85 - 0
app/assets/js/plupload-2.3.7/examples/custom.html

@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
+<title>Plupload - Custom example</title>
+
+<!-- production -->
+<script type="text/javascript" src="../js/plupload.full.min.js"></script>
+
+
+<!-- debug 
+<script type="text/javascript" src="../js/moxie.js"></script>
+<script type="text/javascript" src="../js/plupload.dev.js"></script>
+-->
+
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+
+<h1>Custom example</h1>
+
+<p>Shows you how to use the core plupload API.</p>
+
+<div id="filelist">Your browser doesn't have Flash, Silverlight or HTML5 support.</div>
+<br />
+
+<div id="container">
+    <a id="pickfiles" href="javascript:;">[Select files]</a> 
+    <a id="uploadfiles" href="javascript:;">[Upload files]</a>
+</div>
+
+<br />
+<pre id="console"></pre>
+
+
+<script type="text/javascript">
+// Custom example logic
+
+var uploader = new plupload.Uploader({
+	runtimes : 'html5,flash,silverlight,html4',
+	browse_button : 'pickfiles', // you can pass an id...
+	container: document.getElementById('container'), // ... or DOM Element itself
+	url : 'upload.php',
+	flash_swf_url : '../js/Moxie.swf',
+	silverlight_xap_url : '../js/Moxie.xap',
+	
+	filters : {
+		max_file_size : '10mb',
+		mime_types: [
+			{title : "Image files", extensions : "jpg,gif,png"},
+			{title : "Zip files", extensions : "zip"}
+		]
+	},
+
+	init: {
+		PostInit: function() {
+			document.getElementById('filelist').innerHTML = '';
+
+			document.getElementById('uploadfiles').onclick = function() {
+				uploader.start();
+				return false;
+			};
+		},
+
+		FilesAdded: function(up, files) {
+			plupload.each(files, function(file) {
+				document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
+			});
+		},
+
+		UploadProgress: function(up, file) {
+			document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
+		},
+
+		Error: function(up, err) {
+			document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
+		}
+	}
+});
+
+uploader.init();
+
+</script>
+</body>
+</html>

+ 34 - 0
app/assets/js/plupload-2.3.7/examples/dump.php

@@ -0,0 +1,34 @@
+<?php
+#!! IMPORTANT: 
+#!! this file is just an example, it doesn't incorporate any security checks and 
+#!! is not recommended to be used in production environment as it is. Be sure to 
+#!! revise it and customize to your needs.
+die("Make sure that you enable some form of authentication before removing this line.");
+?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+<title>Plupload - Form dump</title>
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+	
+<h1>Post dump</h1>
+
+<p>Shows the form items posted.</p>
+
+<table>
+	<tr>
+		<th>Name</th>
+		<th>Value</th>
+	</tr>
+	<?php $count = 0; foreach ($_POST as $name => $value) { ?>
+	<tr class="<?php echo $count % 2 == 0 ? 'alt' : ''; ?>">
+		<td><?php echo htmlentities(stripslashes($name)) ?></td>
+		<td><?php echo nl2br(htmlentities(stripslashes($value))) ?></td>
+	</tr>
+	<?php } ?>
+</table>
+
+</body>
+</html>

+ 217 - 0
app/assets/js/plupload-2.3.7/examples/events.html

@@ -0,0 +1,217 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
+<title>Plupload - Events example</title>
+
+<!-- production -->
+<script type="text/javascript" src="../js/plupload.full.min.js"></script>
+
+
+<!-- debug 
+<script type="text/javascript" src="../js/moxie.js"></script>
+<script type="text/javascript" src="../js/plupload.dev.js"></script>
+-->
+
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+
+<h1>Events example</h1>
+
+<div id="container">
+    <a id="pickfiles" href="javascript:;">[Select files]</a> 
+    <a id="uploadfiles" href="javascript:;">[Upload files]</a>
+</div>
+
+<br />
+<pre id="console"></pre>
+ 
+<script type="text/javascript">
+	var uploader = new plupload.Uploader({
+        // General settings
+        runtimes : 'silverlight,html4',
+		browse_button : 'pickfiles', // you can pass in id...
+        url : 'upload.php',
+        chunk_size : '1mb',
+        unique_names : true,
+ 
+        // Resize images on client-side if we can
+        resize : { width : 320, height : 240, quality : 90 },
+        
+        filters : {
+            max_file_size : '10mb',
+
+			// Specify what files to browse for
+            mime_types: [
+                {title : "Image files", extensions : "jpg,gif,png"},
+                {title : "Zip files", extensions : "zip"}
+            ]
+        },
+ 
+		flash_swf_url : '../js/Moxie.swf',
+		silverlight_xap_url : '../js/Moxie.xap',
+         
+        // PreInit events, bound before the internal events
+        preinit : {
+            Init: function(up, info) {
+                log('[Init]', 'Info:', info, 'Features:', up.features);
+            },
+ 
+            UploadFile: function(up, file) {
+                log('[UploadFile]', file);
+ 
+                // You can override settings before the file is uploaded
+                // up.setOption('url', 'upload.php?id=' + file.id);
+                // up.setOption('multipart_params', {param1 : 'value1', param2 : 'value2'});
+            }
+        },
+ 
+        // Post init events, bound after the internal events
+        init : {
+			PostInit: function() {
+				// Called after initialization is finished and internal event handlers bound
+				log('[PostInit]');
+				
+				document.getElementById('uploadfiles').onclick = function() {
+					uploader.start();
+					return false;
+				};
+			},
+
+			Browse: function(up) {
+                // Called when file picker is clicked
+                log('[Browse]');
+            },
+
+            Refresh: function(up) {
+                // Called when the position or dimensions of the picker change
+                log('[Refresh]');
+            },
+ 
+            StateChanged: function(up) {
+                // Called when the state of the queue is changed
+                log('[StateChanged]', up.state == plupload.STARTED ? "STARTED" : "STOPPED");
+            },
+ 
+            QueueChanged: function(up) {
+                // Called when queue is changed by adding or removing files
+                log('[QueueChanged]');
+            },
+
+			OptionChanged: function(up, name, value, oldValue) {
+				// Called when one of the configuration options is changed
+				log('[OptionChanged]', 'Option Name: ', name, 'Value: ', value, 'Old Value: ', oldValue);
+			},
+
+			BeforeUpload: function(up, file) {
+				// Called right before the upload for a given file starts, can be used to cancel it if required
+				log('[BeforeUpload]', 'File: ', file);
+			},
+ 
+            UploadProgress: function(up, file) {
+                // Called while file is being uploaded
+                log('[UploadProgress]', 'File:', file, "Total:", up.total);
+            },
+
+			FileFiltered: function(up, file) {
+				// Called when file successfully files all the filters
+                log('[FileFiltered]', 'File:', file);
+			},
+ 
+            FilesAdded: function(up, files) {
+                // Called when files are added to queue
+                log('[FilesAdded]');
+ 
+                plupload.each(files, function(file) {
+                    log('  File:', file);
+                });
+            },
+ 
+            FilesRemoved: function(up, files) {
+                // Called when files are removed from queue
+                log('[FilesRemoved]');
+ 
+                plupload.each(files, function(file) {
+                    log('  File:', file);
+                });
+            },
+ 
+            FileUploaded: function(up, file, info) {
+                // Called when file has finished uploading
+                log('[FileUploaded] File:', file, "Info:", info);
+            },
+ 
+            ChunkUploaded: function(up, file, info) {
+                // Called when file chunk has finished uploading
+                log('[ChunkUploaded] File:', file, "Info:", info);
+            },
+
+			UploadComplete: function(up, files) {
+				// Called when all files are either uploaded or failed
+                log('[UploadComplete]');
+			},
+
+			Destroy: function(up) {
+				// Called when uploader is destroyed
+                log('[Destroy] ');
+			},
+ 
+            Error: function(up, args) {
+                // Called when error occurs
+                log('[Error] ', args);
+            }
+        }
+    });
+ 
+ 
+    function log() {
+        var str = "";
+ 
+        plupload.each(arguments, function(arg) {
+            var row = "";
+ 
+            if (typeof(arg) != "string") {
+                plupload.each(arg, function(value, key) {
+                    // Convert items in File objects to human readable form
+                    if (arg instanceof plupload.File) {
+                        // Convert status to human readable
+                        switch (value) {
+                            case plupload.QUEUED:
+                                value = 'QUEUED';
+                                break;
+ 
+                            case plupload.UPLOADING:
+                                value = 'UPLOADING';
+                                break;
+ 
+                            case plupload.FAILED:
+                                value = 'FAILED';
+                                break;
+ 
+                            case plupload.DONE:
+                                value = 'DONE';
+                                break;
+                        }
+                    }
+ 
+                    if (typeof(value) != "function") {
+                        row += (row ? ', ' : '') + key + '=' + value;
+                    }
+                });
+ 
+                str += row + " ";
+            } else {
+                str += arg + " ";
+            }
+        });
+ 
+        var log = document.getElementById('console');
+        log.innerHTML += str + "\n";
+    }
+
+	uploader.init();
+
+</script>
+</body>
+</html>

+ 139 - 0
app/assets/js/plupload-2.3.7/examples/jquery/all_runtimes.html

@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
+<title>Plupload - Queue widget example</title>
+
+<link rel="stylesheet" href="../../js/jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" media="screen" />
+
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
+
+<!-- production -->
+<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
+<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
+
+<!-- debug 
+<script type="text/javascript" src="../../js/moxie.js"></script>
+<script type="text/javascript" src="../../js/plupload.dev.js"></script>
+<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
+-->
+
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+
+<form method="post" action="dump.php">
+	<h1>Queue widget example</h1>
+
+	<p>Shows the jQuery Plupload Queue widget and under different runtimes.</p>
+
+	<div style="float: left; margin-right: 20px">
+		<h3>Flash runtime</h3>
+		<div id="flash_uploader" style="width: 500px; height: 330px;">Your browser doesn't have Flash installed.</div>
+
+		<h3>Silverlight runtime</h3>
+		<div id="silverlight_uploader" style="width: 500px; height: 330px;">Your browser doesn't have Silverlight installed.</div>
+	</div>
+
+	<div style="float: left; margin-right: 20px">
+		<h3>HTML 4 runtime</h3>
+		<div id="html4_uploader" style="width: 500px; height: 330px;">Your browser doesn't have HTML 4 support.</div>
+		
+		<h3>HTML 5 runtime</h3>
+		<div id="html5_uploader" style="width: 500px; height: 330px;">Your browser doesn't support native upload.</div>
+	</div>
+
+	<br style="clear: both" />
+
+	<input type="submit" value="Send" />
+</form>
+
+<script type="text/javascript">
+$(function() {
+	// Setup flash version
+	$("#flash_uploader").pluploadQueue({
+		// General settings
+		runtimes : 'flash',
+		url : '../upload.php',
+		chunk_size : '1mb',
+		unique_names : true,
+		
+		filters : {
+			max_file_size : '10mb',
+			mime_types: [
+				{title : "Image files", extensions : "jpg,gif,png"},
+				{title : "Zip files", extensions : "zip"}
+			]
+		},
+
+		// Resize images on clientside if we can
+		resize : {width : 320, height : 240, quality : 90},
+
+		// Flash settings
+		flash_swf_url : '../../js/Moxie.swf'
+	});
+
+
+	// Setup silverlight version
+	$("#silverlight_uploader").pluploadQueue({
+		// General settings
+		runtimes : 'silverlight',
+		url : '../upload.php',
+		chunk_size : '1mb',
+		unique_names : true,
+		
+		filters : {
+			max_file_size : '10mb',
+			mime_types: [
+				{title : "Image files", extensions : "jpg,gif,png"},
+				{title : "Zip files", extensions : "zip"}
+			]
+		},
+
+		// Resize images on clientside if we can
+		resize : {width : 320, height : 240, quality : 90},
+
+		// Silverlight settings
+		silverlight_xap_url : '../../js/Moxie.xap'
+	});
+
+	// Setup html5 version
+	$("#html5_uploader").pluploadQueue({
+		// General settings
+		runtimes : 'html5',
+		url : '../upload.php',
+		chunk_size : '1mb',
+		unique_names : true,
+		
+		filters : {
+			max_file_size : '10mb',
+			mime_types: [
+				{title : "Image files", extensions : "jpg,gif,png"},
+				{title : "Zip files", extensions : "zip"}
+			]
+		},
+
+		// Resize images on clientside if we can
+		resize : {width : 320, height : 240, quality : 90}
+	});
+
+
+	// Setup html4 version
+	$("#html4_uploader").pluploadQueue({
+		// General settings
+		runtimes : 'html4',
+		url : '../upload.php',
+		unique_names : true,
+		
+		filters : {
+			mime_types: [
+				{title : "Image files", extensions : "jpg,gif,png"},
+				{title : "Zip files", extensions : "zip"}
+			]
+		}
+	});
+});
+</script>
+
+</body>
+</html>

+ 113 - 0
app/assets/js/plupload-2.3.7/examples/jquery/jquery_ui_widget.html

@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
+<title>Plupload - jQuery UI Widget</title>
+
+<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" />
+<link rel="stylesheet" href="../../js/jquery.ui.plupload/css/jquery.ui.plupload.css" type="text/css" />
+
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
+<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
+
+<!-- production -->
+<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
+<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
+
+<!-- debug 
+<script type="text/javascript" src="../../js/moxie.js"></script>
+<script type="text/javascript" src="../../js/plupload.dev.js"></script>
+<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
+-->
+
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+
+<h1>jQuery UI Widget</h1>
+
+<p>You can see this example with different themes on the <a href="http://plupload.com/example_jquery_ui.php">www.plupload.com</a> website.</p>
+
+<form id="form" method="post" action="../dump.php">
+	<div id="uploader">
+		<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
+	</div>
+	<br />
+	<input type="submit" value="Submit" />
+</form>
+
+<script type="text/javascript">
+// Initialize the widget when the DOM is ready
+$(function() {
+	$("#uploader").plupload({
+		// General settings
+		runtimes : 'html5,flash,silverlight,html4',
+		url : '../upload.php',
+
+		// User can upload no more then 20 files in one go (sets multiple_queues to false)
+		max_file_count: 20,
+		
+		chunk_size: '1mb',
+
+		// Resize images on clientside if we can
+		resize : {
+			width : 200, 
+			height : 200, 
+			quality : 90,
+			crop: true // crop to exact dimensions
+		},
+		
+		filters : {
+			// Maximum file size
+			max_file_size : '1000mb',
+			// Specify what files to browse for
+			mime_types: [
+				{title : "Image files", extensions : "jpg,gif,png"},
+				{title : "Zip files", extensions : "zip"}
+			]
+		},
+
+		// Rename files by clicking on their titles
+		rename: true,
+		
+		// Sort files
+		sortable: true,
+
+		// Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
+		dragdrop: true,
+
+		// Views to activate
+		views: {
+			list: true,
+			thumbs: true, // Show thumbs
+			active: 'thumbs'
+		},
+
+		// Flash settings
+		flash_swf_url : '../../js/Moxie.swf',
+
+		// Silverlight settings
+		silverlight_xap_url : '../../js/Moxie.xap'
+	});
+
+
+	// Handle the case when form was submitted before uploading has finished
+	$('#form').submit(function(e) {
+		// Files in queue upload them first
+		if ($('#uploader').plupload('getFiles').length > 0) {
+
+			// When all files are uploaded submit form
+			$('#uploader').on('complete', function() {
+				$('#form')[0].submit();
+			});
+
+			$('#uploader').plupload('start');
+		} else {
+			alert("You must have at least one file in the queue.");
+		}
+		return false; // Keep the form from submitting
+	});
+});
+</script>
+</body>
+</html>

+ 66 - 0
app/assets/js/plupload-2.3.7/examples/jquery/queue_widget.html

@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
+<title>Plupload - Queue widget example</title>
+
+<link rel="stylesheet" href="../../js/jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" media="screen" />
+
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
+
+<!-- production -->
+<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
+<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
+
+<!-- debug 
+<script type="text/javascript" src="../../js/moxie.js"></script>
+<script type="text/javascript" src="../../js/plupload.dev.js"></script>
+<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
+-->
+
+
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+
+<form method="post" action="dump.php">	
+	<div id="uploader">
+		<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
+	</div>
+	<input type="submit" value="Send" />
+</form>
+
+<script type="text/javascript">
+$(function() {
+	
+	// Setup html5 version
+	$("#uploader").pluploadQueue({
+		// General settings
+		runtimes : 'html5,flash,silverlight,html4',
+		url : '../upload.php',
+		chunk_size: '1mb',
+		rename : true,
+		dragdrop: true,
+		
+		filters : {
+			// Maximum file size
+			max_file_size : '10mb',
+			// Specify what files to browse for
+			mime_types: [
+				{title : "Image files", extensions : "jpg,gif,png"},
+				{title : "Zip files", extensions : "zip"}
+			]
+		},
+
+		// Resize images on clientside if we can
+		resize : {width : 320, height : 240, quality : 90},
+
+		flash_swf_url : '../../js/Moxie.swf',
+		silverlight_xap_url : '../../js/Moxie.xap'
+	});
+
+});
+</script>
+
+</body>
+</html>

+ 131 - 0
app/assets/js/plupload-2.3.7/examples/jquery/s3.php

@@ -0,0 +1,131 @@
+<?php
+#!! IMPORTANT: 
+#!! this file is just an example, it doesn't incorporate any security checks and 
+#!! is not recommended to be used in production environment as it is. Be sure to 
+#!! revise it and customize to your needs.
+die("Make sure that you enable some form of authentication before removing this line.");
+
+/* 
+In order to upload files to S3 using Flash runtime, one should start by placing crossdomain.xml into the bucket.
+crossdomain.xml can be as simple as this:
+
+<?xml version="1.0"?>
+<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
+<cross-domain-policy>
+<allow-access-from domain="*" secure="false" />
+</cross-domain-policy>
+
+In our tests SilverLight didn't require anything special and worked with this configuration just fine. It may fail back
+to the same crossdomain.xml as last resort.
+
+!!!Important!!! Plupload UI Widget here, is used only for demo purposes and is not required for uploading to S3.
+*/
+
+// important variables that will be used throughout this example
+$bucket = 'BUCKET';
+
+// these can be found on your Account page, under Security Credentials > Access Keys
+$accessKeyId = 'ACCESS_KEY_ID';
+$secret = 'SECRET_ACCESS_KEY';
+
+// prepare policy
+$policy = base64_encode(json_encode(array(
+	// ISO 8601 - date('c'); generates uncompatible date, so better do it manually
+	'expiration' => date('Y-m-d\TH:i:s.000\Z', strtotime('+1 day')),  
+	'conditions' => array(
+		array('bucket' => $bucket),
+		array('acl' => 'public-read'),
+		array('starts-with', '$key', ''),
+		// for demo purposes we are accepting only images
+		array('starts-with', '$Content-Type', 'image/'),
+		// Plupload internally adds name field, so we need to mention it here
+		array('starts-with', '$name', ''), 	
+		// One more field to take into account: Filename - gets silently sent by FileReference.upload() in Flash
+		// http://docs.amazonwebservices.com/AmazonS3/latest/dev/HTTPPOSTFlash.html
+		array('starts-with', '$Filename', ''), 
+	)
+)));
+
+// sign policy
+$signature = base64_encode(hash_hmac('sha1', $policy, $secret, true));
+
+?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
+
+<title>Plupload to Amazon S3 Example</title>
+
+<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" />
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
+<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
+
+<!-- Load plupload and all it's runtimes and finally the UI widget -->
+<link rel="stylesheet" href="../../js/jquery.ui.plupload/css/jquery.ui.plupload.css" type="text/css" />
+
+
+<!-- production -->
+<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
+<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
+
+<!-- debug 
+<script type="text/javascript" src="../../js/moxie.js"></script>
+<script type="text/javascript" src="../../js/plupload.dev.js"></script>
+<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
+-->
+
+</head>
+<body style="font: 13px Verdana; background: #eee; color: #333">
+
+<h1>Plupload to Amazon S3 Example</h1>
+
+<div id="uploader">
+    <p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
+</div>
+
+<script type="text/javascript">
+// Convert divs to queue widgets when the DOM is ready
+$(function() {
+	$("#uploader").plupload({
+		runtimes : 'html5,flash,silverlight',
+		url : 'http://<?php echo $bucket; ?>.s3.amazonaws.com/',
+		
+		multipart: true,
+		multipart_params: {
+			'key': '${filename}', // use filename as a key
+			'Filename': '${filename}', // adding this to keep consistency across the runtimes
+			'acl': 'public-read',
+			'Content-Type': 'image/jpeg',
+			'AWSAccessKeyId' : '<?php echo $accessKeyId; ?>',		
+			'policy': '<?php echo $policy; ?>',
+			'signature': '<?php echo $signature; ?>'
+		},
+		
+		// !!!Important!!! 
+		// this is not recommended with S3, since it will force Flash runtime into the mode, with no progress indication
+		//resize : {width : 800, height : 600, quality : 60},  // Resize images on clientside, if possible 
+		
+		// optional, but better be specified directly
+		file_data_name: 'file',
+
+		filters : {
+			// Maximum file size
+			max_file_size : '10mb',
+			// Specify what files to browse for
+			mime_types: [
+				{title : "Image files", extensions : "jpg,jpeg"}
+			]
+		},
+
+		// Flash settings
+		flash_swf_url : '../../js/Moxie.swf',
+
+		// Silverlight settings
+		silverlight_xap_url : '../../js/Moxie.xap'
+	});
+});
+</script>
+
+</body>
+</html>

+ 126 - 0
app/assets/js/plupload-2.3.7/examples/upload.php

@@ -0,0 +1,126 @@
+<?php
+/**
+ * upload.php
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+#!! IMPORTANT: 
+#!! this file is just an example, it doesn't incorporate any security checks and 
+#!! is not recommended to be used in production environment as it is. Be sure to 
+#!! revise it and customize to your needs.
+die("Make sure that you enable some form of authentication before removing this line.");
+
+
+// Make sure file is not cached (as it happens for example on iOS devices)
+header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+/* 
+// Support CORS
+header("Access-Control-Allow-Origin: *");
+// other CORS headers if any...
+if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
+	exit; // finish preflight CORS requests here
+}
+*/
+
+// 5 minutes execution time
+@set_time_limit(5 * 60);
+
+// Uncomment this one to fake upload time
+// usleep(5000);
+
+// Settings
+$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
+//$targetDir = 'uploads';
+$cleanupTargetDir = true; // Remove old files
+$maxFileAge = 5 * 3600; // Temp file age in seconds
+
+
+// Create target dir
+if (!file_exists($targetDir)) {
+	@mkdir($targetDir);
+}
+
+// Get a file name
+if (isset($_REQUEST["name"])) {
+	$fileName = $_REQUEST["name"];
+} elseif (!empty($_FILES)) {
+	$fileName = $_FILES["file"]["name"];
+} else {
+	$fileName = uniqid("file_");
+}
+
+$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
+
+// Chunking might be enabled
+$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
+$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
+
+
+// Remove old temp files	
+if ($cleanupTargetDir) {
+	if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
+		die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
+	}
+
+	while (($file = readdir($dir)) !== false) {
+		$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
+
+		// If temp file is current file proceed to the next
+		if ($tmpfilePath == "{$filePath}.part") {
+			continue;
+		}
+
+		// Remove temp file if it is older than the max age and is not the current file
+		if (preg_match('/\.part$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge)) {
+			@unlink($tmpfilePath);
+		}
+	}
+	closedir($dir);
+}	
+
+
+// Open temp file
+if (!$out = @fopen("{$filePath}.part", $chunks ? "ab" : "wb")) {
+	die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
+}
+
+if (!empty($_FILES)) {
+	if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
+		die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
+	}
+
+	// Read binary input stream and append it to temp file
+	if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {
+		die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
+	}
+} else {	
+	if (!$in = @fopen("php://input", "rb")) {
+		die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
+	}
+}
+
+while ($buff = fread($in, 4096)) {
+	fwrite($out, $buff);
+}
+
+@fclose($out);
+@fclose($in);
+
+// Check if file has been uploaded
+if (!$chunks || $chunk == $chunks - 1) {
+	// Strip the temp .part suffix off 
+	rename("{$filePath}.part", $filePath);
+}
+
+// Return Success JSON-RPC response
+die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');

BIN
app/assets/js/plupload-2.3.7/js/Moxie.swf


BIN
app/assets/js/plupload-2.3.7/js/Moxie.xap


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ar.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/az.js

@@ -0,0 +1,2 @@
+// Azerbaijani (az)
+plupload.addI18n({"Stop Upload":"Yükləməni saxla","Upload URL might be wrong or doesn't exist.":"Yükləmə ünvanı səhvdir və ya mövcud deyil","tb":"tb","Size":"Həcm","Close":"Bağla","You must specify either browse_button or drop_element.":"","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Faylları əlavə edin və yüklə düyməsinə klikləyin.","List":"","Filename":"Faylın adı","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Şəklin formatı uyğun deyil və ya dəstəklənmir.","Status":"Status","HTTP Error.":"HTTP xətası.","Start Upload":"Yüklə","Error: File too large:":"Xəta:Fayl həcmi çox böyükdür.","kb":"kb","Duplicate file error.":"Bu fayl artıq növbədə var.","File size error.":"Fayl həcmi xətası.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Xəta: Yanlış fayl uzantısı:","Select files":"Faylları seçin","%s already present in the queue.":"%s artıq növbədə var.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fayl: %s","b":"b","Uploaded %d/%d files":"%d/%d fayl yüklənib","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"Növbədə %d fayl var","File: %s, size: %d, max file size: %d":"Fayl: %s, həcm: %d, max fayl həcmi: %d","Thumbnails":"","Drag files here.":"Faylları bura çəkin.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Fayl sayı çox böyükdür.","File extension error.":"Fayl uzantısı xətası.","mb":"mb","Add Files":"Fayl əlavə et"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/bg.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/bs.js

@@ -0,0 +1,2 @@
+// Bosnian (bs)
+plupload.addI18n({"Stop Upload":"Prekini dodavanje","Upload URL might be wrong or doesn't exist.":"URL za dodavanje je neispravan ili ne postoji.","tb":"tb","Size":"Veličina","Close":"Zatvori","You must specify either browse_button or drop_element.":"","Init error.":"Inicijalizacijska greška.","Add files to the upload queue and click the start button.":"Dodajte datoteke u red i kliknite na dugme za pokretanje.","List":"","Filename":"Naziv datoteke","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Format slike je neispravan ili nije podržan.","Status":"Status","HTTP Error.":"HTTP greška.","Start Upload":"Započni dodavanje","Error: File too large:":"Greška! Datoteka je prevelika:","kb":"kb","Duplicate file error.":"Dupla datoteka.","File size error.":"Greška u veličini datoteke.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Greška! Neispravan ekstenzija datoteke:","Select files":"Odaberite datoteke","%s already present in the queue.":"%s se već nalazi u redu.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Dodano %d/%d datoteka","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Dodavanje trenutno dozvoljava samo %d datoteka istovremeno. Dodatne datoteke su uklonjene.","%d files queued":"%d datoteka čeka","File: %s, size: %d, max file size: %d":"Datoteka: %s, veličina: %d, maksimalna veličina: %d","Thumbnails":"","Drag files here.":"Dovucite datoteke ovdje.","Runtime ran out of available memory.":"Nema više dostupne memorije.","File count error.":"Greška u brojanju datoeka.","File extension error.":"Greška u ekstenziji datoteke.","mb":"mb","Add Files":"Dodaj datoteke"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ca.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/cs.js

@@ -0,0 +1,2 @@
+// Czech (cs)
+plupload.addI18n({"Stop Upload":"Zastavit nahrávání","Upload URL might be wrong or doesn't exist.":"URL uploadu je možná špatně, nebo neexistuje.","tb":"tb","Size":"Velikost","Close":"Zavřít","You must specify either browse_button or drop_element.":"Musíte specifikovat browse_button či drop_element.","Init error.":"Chyba inicializace.","Add files to the upload queue and click the start button.":"Přidejte soubory do fronty a pak spusťte nahrávání.","List":"Seznam","Filename":"Název souboru","%s specified, but cannot be found.":"%s bylo specifikováno, ale nebylo nalezeno.","Image format either wrong or not supported.":"Špatný, nebo nepodporovaný formát obrázku.","Status":"Stav","HTTP Error.":"Chyba HTTP.","Start Upload":"Spustit nahrávání","Error: File too large:":"Chyba: Soubor je příliš veliký:","kb":"kb","Duplicate file error.":"Chyba - duplikovaný soubor.","File size error.":"Chyba velikosti souboru.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Chyba: Neplatná koncovka souboru:","Select files":"Vyberte soubory","%s already present in the queue.":"%s je již zařazen ve frontě.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Rozlišení je mimo rozmezí! <b>%s</b> runtime podporuje obrázky pouze do %wx%hpx.","File: %s":"Soubor: %s","b":"b","Uploaded %d/%d files":"Nahráno %d/%d souborů","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload akceptuje pouze %d soubor(ů) najednou. Další soubory byly odstraněny.","%d files queued":"%d souborů ve frontě","File: %s, size: %d, max file size: %d":"Soubor: %s, velikost: %d, maximální velikost souboru: %d","Thumbnails":"Náhledy","Drag files here.":"Sem přetáhněte soubory.","Runtime ran out of available memory.":"Běh skriptu přesáhl dostupnou paměť.","File count error.":"Chyba v počtu souborů.","File extension error.":"Chyba přípony souboru.","mb":"mb","Add Files":"Přidat soubory"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/cy.js

@@ -0,0 +1,2 @@
+// Welsh (cy)
+plupload.addI18n({"Stop Upload":"Atal Lanlwytho","Upload URL might be wrong or doesn't exist.":"URL y lanlwythiad ynb anghywir neu ddim yn bodoli.","tb":"tb","Size":"Maint","Close":"Cau","You must specify either browse_button or drop_element.":"","Init error.":"Gwall cych.","Add files to the upload queue and click the start button.":"Ychwanegwch ffeiliau i'r ciw lanlwytho a chlicio'r botwm dechrau.","List":"","Filename":"Enw'r ffeil","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Fformat delwedd yn anghywir neu heb ei gynnal.","Status":"Statws","HTTP Error.":"Gwall HTTP.","Start Upload":"Dechrau Lanlwytho","Error: File too large:":"Gwall: Ffeil yn rhy fawr:","kb":"kb","Duplicate file error.":"Gwall ffeil ddyblyg.","File size error.":"Gwall maint ffeil.","N/A":"Dd/A","gb":"gb","Error: Invalid file extension:":"Gwall: estyniad ffeil annilys:","Select files":"Dewis ffeiliau","%s already present in the queue.":"%s yn y ciw yn barod.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Ffeil: %s","b":"b","Uploaded %d/%d files":"Lanlwythwyd  %d/%d ffeil","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Mae'r elfen lanlwytho yn derbyn %d ffeil ar y tro. Caiff ffeiliau ychwanegol eu tynnu.","%d files queued":"%d ffeil mewn ciw","File: %s, size: %d, max file size: %d":"Ffeil: %s, maint: %d, maint mwyaf ffeil: %d","Thumbnails":"","Drag files here.":"Llusgwch ffeiliau yma.","Runtime ran out of available memory.":"Allan o gof.","File count error.":"Gwall cyfri ffeiliau.","File extension error.":"Gwall estyniad ffeil.","mb":"mb","Add Files":"Ychwanegu Ffeiliau"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/da.js

@@ -0,0 +1,2 @@
+// Danish (da)
+plupload.addI18n({"Stop Upload":"Stop upload","Upload URL might be wrong or doesn't exist.":"Upload URL kan være forkert eller ikke eksisterende.","tb":"tb","Size":"Størrelse","Close":"Luk","You must specify either browse_button or drop_element.":"","Init error.":"Opstarts fejl.","Add files to the upload queue and click the start button.":"Tilføj filer til køen og klik Start upload knappen.","List":"","Filename":"Filnavn","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Billede format er enten forkert eller ikke understøttet.","Status":"Status","HTTP Error.":"HTTP fejl.","Start Upload":"Start upload","Error: File too large:":"Fejl: Filen er for stor:","kb":"kb","Duplicate file error.":"Filen findes allerede.","File size error.":"Filstørrelse fejl.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Fejl: Ugyldigt fil format:","Select files":"Vælg filer","%s already present in the queue.":"%s findes allerede i køen.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fil: %s","b":"b","Uploaded %d/%d files":"Uploaded %d/%d filer","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload accepterer kun %d fil(er) af gangen. Ekstra filer blev skippet.","%d files queued":"%d filer i kø","File: %s, size: %d, max file size: %d":"Fil: %s, størrelse: %d, maks. filstørrelse: %d","Thumbnails":"","Drag files here.":"Træk filer her.","Runtime ran out of available memory.":"Runtime mangler tilgængelige hukommelse.","File count error.":"Fil antal fejl.","File extension error.":"Fil format fejl.","mb":"mb","Add Files":"Tilføj filer"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/de.js

@@ -0,0 +1,2 @@
+// German (de)
+plupload.addI18n({"Stop Upload":"Hochladen abbrechen","Upload URL might be wrong or doesn't exist.":"Upload-URL ist falsch oder existiert nicht.","tb":"TB","Size":"Größe","Close":"Schließen","You must specify either browse_button or drop_element.":"","Init error.":"Initialisierungsfehler","Add files to the upload queue and click the start button.":"Dateien hinzufügen und auf 'Hochladen' klicken.","List":"Liste","Filename":"Dateiname","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Bildformat falsch oder nicht unterstützt.","Status":"Status","HTTP Error.":"HTTP-Fehler","Start Upload":"Hochladen beginnen","Error: File too large:":"Fehler: Datei zu groß:","kb":"KB","Duplicate file error.":"Datei bereits hochgeladen","File size error.":"Fehler bei Dateigröße","N/A":"Nicht verfügbar","gb":"GB","Error: Invalid file extension:":"Fehler: Ungültige Dateiendung:","Select files":"Dateien auswählen","%s already present in the queue.":"%s ist bereits in der Warteschlange","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datei: %s","b":"B","Uploaded %d/%d files":"%d/%d Dateien wurden hochgeladen","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Pro Durchgang können nur %d Datei(en) akzeptiert werden. Überzählige Dateien wurden ignoriert.","%d files queued":"%d Dateien in der Warteschlange","File: %s, size: %d, max file size: %d":"Datei: %s, Größe: %d, maximale Dateigröße: %d","Thumbnails":"Vorschaubilder","Drag files here.":"Dateien auf diese Fläche bewegen.","Runtime ran out of available memory.":"Nicht genügend Speicher verfügbar.","File count error.":"Fehlerhafte Dateianzahl.","File extension error.":"Fehler bei Dateiendung","mb":"MB","Add Files":"Dateien hinzufügen"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/el.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/en.js

@@ -0,0 +1,2 @@
+// English (en)
+plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Size","Close":"Close","You must specify either browse_button or drop_element.":"You must specify either browse_button or drop_element.","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Add files to the upload queue and click the start button.","List":"List","Filename":"Filename","%s specified, but cannot be found.":"%s specified, but cannot be found.","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Start Upload","Error: File too large:":"Error: File too large:","kb":"kb","Duplicate file error.":"Duplicate file error.","File size error.":"File size error.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Select files","%s already present in the queue.":"%s already present in the queue.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.","File: %s":"File: %s","b":"b","Uploaded %d/%d files":"Uploaded %d/%d files","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d files queued","File: %s, size: %d, max file size: %d":"File: %s, size: %d, max file size: %d","Thumbnails":"Thumbnails","Drag files here.":"Drag files here.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"File count error.","File extension error.":"File extension error.","mb":"mb","Add Files":"Add Files"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/es.js

@@ -0,0 +1,2 @@
+// Spanish (es)
+plupload.addI18n({"Stop Upload":"Detener Subida.","Upload URL might be wrong or doesn't exist.":"URL de carga inexistente.","tb":"TB","Size":"Tamaño","Close":"Cerrar","You must specify either browse_button or drop_element.":"Debe especificar el browse_button o el drop_element","Init error.":"Error de inicialización.","Add files to the upload queue and click the start button.":"Agregue archivos a la lista de subida y pulse clic en el botón de Iniciar carga","List":"Lista","Filename":"Nombre de archivo","%s specified, but cannot be found.":"%s especificado, pero no se puede encontrar","Image format either wrong or not supported.":"Formato de imagen no soportada.","Status":"Estado","HTTP Error.":"Error de HTTP.","Start Upload":"Iniciar carga","Error: File too large:":"Error: archivo demasiado grande:","kb":"KB","Duplicate file error.":"Error, archivo duplicado","File size error.":"Error de tamaño de archivo.","N/A":"No disponible","gb":"GB","Error: Invalid file extension:":"Error: Extensión de archivo inválida:","Select files":"Elija archivos","%s already present in the queue.":"%s ya se encuentra en la lista.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resolución fuera de límites! El tiempo de ejecución <b>%s</b> sólo admite imágenes hasta %wx%hpx","File: %s":"Archivo: %s","b":"B","Uploaded %d/%d files":"Subidos %d/%d archivos","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Se aceptan sólo %d archivo(s) al tiempo. Más, no se tienen en cuenta.","%d files queued":"%d archivos en cola.","File: %s, size: %d, max file size: %d":"Archivo: %s, tamaño: %d, tamaño máximo de archivo: %d","Thumbnails":"Miniaturas","Drag files here.":"Arrastre archivos aquí","Runtime ran out of available memory.":"No hay memoria disponible.","File count error.":"Error en contador de archivos.","File extension error.":"Error de extensión de archivo.","mb":"MB","Add Files":"Agregar archivos"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/et.js

@@ -0,0 +1,2 @@
+// Estonian (et)
+plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Üleslaadimise URL võib olla vale või seda pole.","tb":"","Size":"Suurus","Close":"Sulge","You must specify either browse_button or drop_element.":"","Init error.":"Lähtestamise viga.","Add files to the upload queue and click the start button.":"Lisa failid üleslaadimise järjekorda ja klõpsa alustamise nupule.","List":"","Filename":"Failinimi","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Olek","HTTP Error.":"HTTP ühenduse viga.","Start Upload":"Start Upload","Error: File too large:":"Error: File too large:","kb":"","Duplicate file error.":"","File size error.":"Failisuuruse viga.","N/A":"N/A","gb":"","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Vali faile","%s already present in the queue.":"","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fail: %s","b":"","Uploaded %d/%d files":"Üles laaditud %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Üleslaadimise element saab vastu võtta ainult %d faili ühe korraga. Ülejäänud failid jäetakse laadimata.","%d files queued":"Järjekorras on %d faili","File: %s, size: %d, max file size: %d":"","Thumbnails":"","Drag files here.":"Lohista failid siia.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Failide arvu viga.","File extension error.":"Faililaiendi viga.","mb":"","Add Files":"Add Files"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/fa.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/fi.js

@@ -0,0 +1,2 @@
+// Finnish (fi)
+plupload.addI18n({"Stop Upload":"Pysäytä lähetys","Upload URL might be wrong or doesn't exist.":"Lähetyksen URL-osoite saattaa olla väärä tai sitä ei ole olemassa.","tb":"TB","Size":"Koko","Close":"Sulje","You must specify either browse_button or drop_element.":"","Init error.":"Init virhe.","Add files to the upload queue and click the start button.":"Lisää tiedostoja lähetysjonoon ja klikkaa aloita-nappia.","List":"","Filename":"Tiedostonimi","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Kuvaformaatti on joko väärä tai ei tuettu.","Status":"Tila","HTTP Error.":"HTTP-virhe.","Start Upload":"Aloita lähetys","Error: File too large:":"Virhe: Liian suuri tiedosto:","kb":"kB","Duplicate file error.":"Tuplatiedostovirhe.","File size error.":"Tiedostokokovirhe.","N/A":"N/A","gb":"GB","Error: Invalid file extension:":"Virhe: Virheellinen tiedostopääte:","Select files":"Valitse tiedostoja","%s already present in the queue.":"%s on jo jonossa.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Tiedosto: %s","b":"B","Uploaded %d/%d files":"Lähetetty %d/%d tiedostoa","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Vain %d tiedosto(a) voidaan lähettää kerralla. Ylimääräiset tiedostot ohitettiin.","%d files queued":"%d tiedostoa jonossa","File: %s, size: %d, max file size: %d":"Tiedosto: %s, koko: %d, suurin sallittu tiedostokoko: %d","Thumbnails":"","Drag files here.":"Raahaa tiedostot tähän.","Runtime ran out of available memory.":"Toiminnon käytettävissä oleva muisti loppui kesken.","File count error.":"Tiedostolaskentavirhe.","File extension error.":"Tiedostopäätevirhe.","mb":"MB","Add Files":"Lisää tiedostoja"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/fr.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/he.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/hr.js

@@ -0,0 +1,2 @@
+// Croatian (hr)
+plupload.addI18n({"Stop Upload":"Zaustavi upload.","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Veličina","Close":"Zatvori","You must specify either browse_button or drop_element.":"","Init error.":"Greška inicijalizacije.","Add files to the upload queue and click the start button.":"Dodajte datoteke u listu i kliknite Upload.","List":"","Filename":"Ime datoteke","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP greška.","Start Upload":"Pokreni upload.","Error: File too large:":"Pogreška: Datoteka je prevelika:","kb":"kb","Duplicate file error.":"Pogreška dvostruke datoteke.","File size error.":"Greška veličine datoteke.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Pogreška: Nevažeći nastavak datoteke:","Select files":"Odaberite datoteke:","%s already present in the queue.":"%s  je već prisutan  u listi čekanja.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Uploadano %d/%d datoteka","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d datoteka na čekanju.","File: %s, size: %d, max file size: %d":"Datoteka: %s, veličina: %d, maksimalna veličina: %d","Thumbnails":"","Drag files here.":"Dovucite datoteke ovdje","Runtime ran out of available memory.":"Runtime aplikaciji  je ponestalo memorije.","File count error.":"Pogreška u broju datoteka.","File extension error.":"Pogreška u nastavku datoteke.","mb":"mb","Add Files":"Dodaj datoteke"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/hu.js

@@ -0,0 +1,2 @@
+// Hungarian (hu)
+plupload.addI18n({"Stop Upload":"Feltöltés leállítása","Upload URL might be wrong or doesn't exist.":"A feltöltő URL hibás vagy nem létezik.","tb":"TB","Size":"Méret","Close":"Bezárás","You must specify either browse_button or drop_element.":"","Init error.":"Init hiba.","Add files to the upload queue and click the start button.":"A fájlok feltöltési sorhoz való hozzáadása után az Indítás gombra kell kattintani.","List":"","Filename":"Fájlnév","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Rossz vagy nem támogatott képformátum.","Status":"Állapot","HTTP Error.":"HTTP-hiba.","Start Upload":"Feltöltés indítása","Error: File too large:":"Hiba: a fájl túl nagy:","kb":"kB","Duplicate file error.":"Duplikáltfájl-hiba.","File size error.":"Hibás fájlméret.","N/A":"Nem elérhető","gb":"GB","Error: Invalid file extension:":"Hiba: érvénytelen fájlkiterjesztés:","Select files":"Fájlok kiválasztása","%s already present in the queue.":"%s már szerepel a listában.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fájl: %s","b":"b","Uploaded %d/%d files":"Feltöltött fájlok: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"A feltöltés egyszerre csak %d fájlt fogad el, a többi fájl nem lesz feltöltve.","%d files queued":"%d fájl sorbaállítva","File: %s, size: %d, max file size: %d":"Fájl: %s, méret: %d, legnagyobb fájlméret: %d","Thumbnails":"","Drag files here.":"Ide lehet húzni a fájlokat.","Runtime ran out of available memory.":"Futásidőben elfogyott a rendelkezésre álló memória.","File count error.":"A fájlok számával kapcsolatos hiba.","File extension error.":"Hibás fájlkiterjesztés.","mb":"MB","Add Files":"Fájlok hozzáadása"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/hy.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/id.js

@@ -0,0 +1,2 @@
+// Indonesian (id)
+plupload.addI18n({"Stop Upload":"Hentikan Upload","Upload URL might be wrong or doesn't exist.":"Alamat URL untuk upload tidak benar atau tidak ada","tb":"tb","Size":"Ukuran","Close":"Tutup","You must specify either browse_button or drop_element.":"","Init error.":"Kesalahan pada Init","Add files to the upload queue and click the start button.":"Tambahkan file kedalam antrian upload dan klik tombol Mulai","List":"","Filename":"Nama File","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Kesalahan pada jenis gambar atau jenis file tidak didukung","Status":"Status","HTTP Error.":"HTTP Bermasalah","Start Upload":"Mulai Upload","Error: File too large:":"Kesalahan: File terlalu besar","kb":"kb","Duplicate file error.":"Terjadi duplikasi file","File size error.":"Kesalahan pada ukuran file","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Kesalahan: Ekstensi file tidak dikenal","Select files":"Pilih file","%s already present in the queue.":"%s sudah ada dalam daftar antrian","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"File: %s","b":"b","Uploaded %d/%d files":"File terupload %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Tempat untuk upload hanya menerima %d file(s) dalam setiap upload. File lainnya tidak akan disertakan","%d files queued":"%d file dalam antrian","File: %s, size: %d, max file size: %d":"File: %s, ukuran: %d, maksimum ukuran file: %d","Thumbnails":"","Drag files here.":"Tarik file kesini","Runtime ran out of available memory.":"Tidak cukup memori","File count error.":"Kesalahan pada jumlah file","File extension error.":"Kesalahan pada ekstensi file","mb":"mb","Add Files":"Tambah File"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/it.js

@@ -0,0 +1,2 @@
+// Italian (it)
+plupload.addI18n({"Stop Upload":"Ferma Upload","Upload URL might be wrong or doesn't exist.":"URL di Upload errata o non esistente","tb":"tb","Size":"Dimensione","Close":"Chiudi","You must specify either browse_button or drop_element.":"Devi indicare almeno uno tra browse_button o drop_element.","Init error.":"Errore inizializzazione.","Add files to the upload queue and click the start button.":"Aggiungi i file alla coda di caricamento e clicca il pulsante di avvio.","List":"Lista","Filename":"Nome file","%s specified, but cannot be found.":"%s specificato, ma non è stato possibile trovarlo.","Image format either wrong or not supported.":"Formato immagine errato o non supportato.","Status":"Stato","HTTP Error.":"Errore HTTP.","Start Upload":"Inizia Upload","Error: File too large:":"Errore: File troppo grande:","kb":"kb","Duplicate file error.":"Errore file duplicato.","File size error.":"Errore dimensione file.","N/A":"N/D","gb":"gb","Error: Invalid file extension:":"Errore: Estensione file non valida:","Select files":"Seleziona i files","%s already present in the queue.":"%s già presente nella coda.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Risoluzione oltre i limiti! <b>%s</b> runtime supporta immagini fino a %wx%hpx.","File: %s":"File: %s","b":"byte","Uploaded %d/%d files":"Caricati %d/%d file","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d file in coda","File: %s, size: %d, max file size: %d":"File: %s, dimensione: %d, dimensione max file: %d","Thumbnails":"Anteprime","Drag files here.":"Trascina i files qui.","Runtime ran out of available memory.":"Runtime ha esaurito la memoria disponibile.","File count error.":"File count error.","File extension error.":"Errore estensione file.","mb":"mb","Add Files":"Aggiungi file"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ja.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ka.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/kk.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/km.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ko.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ku_IQ.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/lt.js

@@ -0,0 +1,2 @@
+// Lithuanian (lt)
+plupload.addI18n({"Stop Upload":"Stabdyti įkėlimą","Upload URL might be wrong or doesn't exist.":"Klaidinga arba neegzistuojanti įkėlimo nuoroda.","tb":"tb","Size":"Dydis","Close":"Uždaryti","You must specify either browse_button or drop_element.":"","Init error.":"Įkrovimo klaida.","Add files to the upload queue and click the start button.":"Pridėkite bylas į įkėlimo eilę ir paspauskite starto mygtuką.","List":"","Filename":"Bylos pavadinimas","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Paveiksliuko formatas klaidingas arba nebepalaikomas.","Status":"Statusas","HTTP Error.":"HTTP klaida.","Start Upload":"Pradėti įkėlimą","Error: File too large:":"Klaida: Byla per didelė:","kb":"kb","Duplicate file error.":"Pasikartojanti byla.","File size error.":"Netinkamas bylos dydis.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Klaida: Netinkamas bylos plėtinys:","Select files":"Žymėti bylas","%s already present in the queue.":"%s jau yra eilėje.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Byla: %s","b":"b","Uploaded %d/%d files":"Įkelta bylų: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Vienu metu galima įkelti tik %d bylas(ų). Papildomos bylos buvo pašalintos.","%d files queued":"%d bylų eilėje","File: %s, size: %d, max file size: %d":"Byla: %s, dydis: %d, galimas dydis: %d","Thumbnails":"","Drag files here.":"Padėti bylas čia.","Runtime ran out of available memory.":"Išeikvota darbinė atmintis.","File count error.":"Netinkamas bylų kiekis.","File extension error.":"Netinkamas pletinys.","mb":"mb","Add Files":"Pridėti bylas"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/lv.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/ms.js

@@ -0,0 +1,2 @@
+// Malay (ms)
+plupload.addI18n({"Stop Upload":"Berhenti Muat naik","Upload URL might be wrong or doesn't exist.":"URL muat naik mungkin salah atau tidak wujud.","tb":"tb","Size":"saiz","Close":"Tutup","You must specify either browse_button or drop_element.":"","Init error.":"Ralat perlaksanaan.","Add files to the upload queue and click the start button.":"Tambah fail ke dalam giliran muat naik dan klik butang Muat Naik.","List":"","Filename":"Nama fail","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Format imej sama ada salah atau tidak disokong.","Status":"Status","HTTP Error.":"Ralat HTTP.","Start Upload":"Muat Naik","Error: File too large:":"Ralat: Fail terlalu bersar:","kb":"kb","Duplicate file error.":"Ralat menggandakan fail.","File size error.":"Ralat saiz fail.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Ralat: Sambungan fail tidak sah:","Select files":"Pilih fail","%s already present in the queue.":"%s telah ada dalam barisan.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fail: %s","b":"b","Uploaded %d/%d files":"%d/%d telah dimuat naik","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Element muat naik hanya menerima %d fail(-fail) pada satu masa. Fail tambahan telah digugurkan.","%d files queued":"%d fail dalam barisan","File: %s, size: %d, max file size: %d":"Fail: %s, saiz: %d, saiz maks fail: %d","Thumbnails":"","Drag files here.":"Seret fail ke sini.","Runtime ran out of available memory.":"Ruang ingatan masa larian tidak mencukupi.","File count error.":"Ralat bilangan fail.","File extension error.":"Ralat sambungan fail.","mb":"mb","Add Files":"Tambah Fail"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/nl.js

@@ -0,0 +1,2 @@
+// Dutch (nl)
+plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL is verkeerd of bestaat niet.","tb":"tb","Size":"Grootte","Close":"Sluiten","You must specify either browse_button or drop_element.":"","Init error.":"Initialisatie error.","Add files to the upload queue and click the start button.":"Voeg bestanden toe aan de wachtrij en druk op 'Start'.","List":"","Filename":"Bestandsnaam","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"bestandsextensie is verkeerd of niet ondersteund.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Start Upload","Error: File too large:":"Error: Bestand te groot:","kb":"kb","Duplicate file error.":"Bestand bestaat al.","File size error.":"Bestandsgrootte error.","N/A":"Niet beschikbaar","gb":"gb","Error: Invalid file extension:":"Error: Ongeldige bestandsextensie:","Select files":"Selecteer bestand(en):","%s already present in the queue.":"%s is al aan de wachtrij toegevoegd.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Bestand: %s","b":"b","Uploaded %d/%d files":"%d/%d bestanden ge-upload","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload accepteert alleen %d bestand(en) tegelijk. Extra bestanden zijn verwijderd.","%d files queued":"%d bestand(en) in de wachtrij","File: %s, size: %d, max file size: %d":"Bestand: %s, grootte: %d, maximale bestandsgrootte: %d","Thumbnails":"","Drag files here.":"Sleep bestanden hierheen.","Runtime ran out of available memory.":"Het maximum bruikbare geheugen is overschreden.","File count error.":"Teveel bestand(en) error.","File extension error.":"Ongeldig bestandsextensie.","mb":"mb","Add Files":"Bestand(en) toevoegen"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/pl.js

@@ -0,0 +1,2 @@
+// Polish (pl)
+plupload.addI18n({"Stop Upload":"Przerwij transfer.","Upload URL might be wrong or doesn't exist.":"Adres URL może być nieprawidłowy lub może nie istnieć","tb":"tb","Size":"Rozmiar","Close":"Zamknij","You must specify either browse_button or drop_element.":"Musisz określić browse_button albo drop_element.","Init error.":"Błąd inicjalizacji.","Add files to the upload queue and click the start button.":"Dodaj pliki i kliknij 'Rozpocznij transfer'.","List":"Lista","Filename":"Nazwa pliku","%s specified, but cannot be found.":"%s określony ale nie można znaleźć.","Image format either wrong or not supported.":"Format zdjęcia jest zły lub nieobsługiwany","Status":"Status","HTTP Error.":"Błąd HTTP.","Start Upload":"Wyślij","Error: File too large:":"Błąd: Plik za duży:","kb":"kb","Duplicate file error.":"Błąd: duplikacja pliku.","File size error.":"Plik jest zbyt duży.","N/A":"Nie dostępne","gb":"gb","Error: Invalid file extension:":"Błąd: Nieprawidłowe rozszerzenie pliku:","Select files":"Wybierz pliki:","%s already present in the queue.":"%s już występuje w kolejce.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Za duża rozdzielczość! <b>%s</b> maksymalna rozdzielczość to: %wx%hpx.","File: %s":"Plik: %s","b":"b","Uploaded %d/%d files":"Wysłano %d/%d plików","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Można jednocześnie dodać %d plików. Dodatkowe pliki zostały usunięte.","%d files queued":"%d plików w kolejce.","File: %s, size: %d, max file size: %d":"Plik: %s, rozmiar: %d, maksymalny rozmiar pliku: %d","Thumbnails":"Miniatury","Drag files here.":"Przeciągnij tu pliki","Runtime ran out of available memory.":"Wyczerpano pamięć RAM.","File count error.":"Błąd liczenia pliku.","File extension error.":"Nie obsługiwany format pliku.","mb":"mb","Add Files":"Dodaj pliki"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/pt.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/pt_BR.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/ro.js

@@ -0,0 +1,2 @@
+// Romanian (ro)
+plupload.addI18n({"Stop Upload":"Oprește încărcarea","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Mărime","Close":"Închide","You must specify either browse_button or drop_element.":"","Init error.":"Eroare inițializare.","Add files to the upload queue and click the start button.":"Adaugă fișiere în lista apoi apasă butonul \"Începe încărcarea\".","List":"","Filename":"Nume fișier","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Formatul de imagine ori este greșit ori nu este suportat.","Status":"Stare","HTTP Error.":"Eroare HTTP","Start Upload":"Începe încărcarea","Error: File too large:":"Eroare: Fișierul este prea mare:","kb":"kb","Duplicate file error.":"Eroare duplicat fișier.","File size error.":"Eroare dimensiune fișier.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Eroare: Extensia fișierului este invalidă:","Select files":"Selectează fișierele","%s already present in the queue.":"%s există deja în lista de așteptare.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fișier: %s","b":"b","Uploaded %d/%d files":"Fișiere încărcate %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d fișiere listate","File: %s, size: %d, max file size: %d":"Fișier: %s, mărime: %d, mărime maximă: %d","Thumbnails":"","Drag files here.":"Trage aici fișierele.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Eroare numărare fișiere.","File extension error.":"Eroare extensie fișier.","mb":"mb","Add Files":"Adaugă fișiere"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/ru.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/sk.js

@@ -0,0 +1,2 @@
+// Slovak (sk)
+plupload.addI18n({"Stop Upload":"Zastaviť nahrávanie","Upload URL might be wrong or doesn't exist.":"URL pre nahratie nie je správna alebo neexistuje.","tb":"tb","Size":"Veľkosť","Close":"Zatvoriť","You must specify either browse_button or drop_element.":"","Init error.":"Chyba inicializácie.","Add files to the upload queue and click the start button.":"Pridajte súbory do zoznamu a potom spustite nahrávanie.","List":"","Filename":"Názov súboru","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Formát obrázku je nesprávny alebo nie je podporovaný.","Status":"Stav","HTTP Error.":"HTTP Chyba.","Start Upload":"Spustiť nahrávanie","Error: File too large:":"Chyba: Súbor je príliš veľký:","kb":"kb","Duplicate file error.":"Duplicitný súbor.","File size error.":"Súbor je príliš veľký.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Error: Nesprávny typ súboru:","Select files":"Vyberte súbory","%s already present in the queue.":"%s sa už nachádza v zozname.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Súbor: %s","b":"b","Uploaded %d/%d files":"Nahraných %d/%d súborov","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d súborov pridaných do zoznamu","File: %s, size: %d, max file size: %d":"Súbor: %s, veľkosť: %d, max. veľkosť súboru: %d","Thumbnails":"","Drag files here.":"Sem pretiahnite súbory.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Nesprávny počet súborov.","File extension error.":"Chybný typ súboru.","mb":"mb","Add Files":"Pridať súbory"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/sl.js

@@ -0,0 +1,2 @@
+// Slovenian (sl)
+plupload.addI18n({"Stop Upload":"Ustavi prenos","Upload URL might be wrong or doesn't exist.":"URL za nalaganje je napačen ali ne obstaja.","tb":"tb","Size":"Velikost","Close":"Zapri","You must specify either browse_button or drop_element.":"","Init error.":"Napaka pri inicializaciji.","Add files to the upload queue and click the start button.":"Dodaj datoteke na seznam in klikni na gumb začni","List":"Seznam","Filename":"Ime datoteke","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Format slike je napačen ali ni podrpt.","Status":"Status","HTTP Error.":"Neznana HTTP napaka.","Start Upload":"Začni prenos","Error: File too large:":"Napaka: datoteka je prevelika:","kb":"kb","Duplicate file error.":"Datoteka je že na seznamu.","File size error.":"Datoteka je prevelika.","N/A":"Ni na voljo","gb":"gb","Error: Invalid file extension:":"Napaka: napačen tip datoteke:","Select files":"Izberi datoteke","%s already present in the queue.":"%s je že na seznamu.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Naloženo %d/%d datotek","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Nalagalnik sprejme samo %d datotek na enkrat. Višek datotek je odstranjen iz seznama.","%d files queued":"%d datotek na seznamu","File: %s, size: %d, max file size: %d":"Datoteka: %s, velikost: %d, največja dovoljena velikost: %d","Thumbnails":"Sličice","Drag files here.":"Potegni datoteke sem.","Runtime ran out of available memory.":"Zmanjkalo je pomnilnika.","File count error.":"Napačno število datotek.","File extension error.":"Napačen tip datoteke.","mb":"mb","Add Files":"Dodaj datoteke"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/sq.js

@@ -0,0 +1,2 @@
+// Albanian (sq)
+plupload.addI18n({"Stop Upload":"Ndalimi i ngarkimit","Upload URL might be wrong or doesn't exist.":"Ngarkimi i URL-s është i gabuar ose nuk ekziston.","tb":"TB","Size":"Madhësia","Close":"Mbyll","You must specify either browse_button or drop_element.":"","Init error.":"Init gabim.","Add files to the upload queue and click the start button.":"Mbas ngarkimit të dosjeve sipas rradhës duhet të klikoni butonin Start.","List":"","Filename":"Emri i dosjes","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Formati i fotove është i keq ose nuk është i pranueshëm.","Status":"Statusi","HTTP Error.":"HTTP Gabim.","Start Upload":"Nisja e ngarkimit","Error: File too large:":"Gabim: dosja është shumë e madhe:","kb":"KB","Duplicate file error.":"Gabim i dublikimit të dosjes.","File size error.":"Gabim i madhësisë së dosjes.","N/A":"Nuk është në dispozicion","gb":"GB","Error: Invalid file extension:":"Gabim: përhapja e llojit të dosjes është e pavlefshme:","Select files":"Zhgjidhni dosjet","%s already present in the queue.":"%s tashmë ekziston në list.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Dosje: %s","b":"B","Uploaded %d/%d files":"Dosjet e ngarkuara: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Ngarkimi pranon njëherësh vetëm %d dosje, dosjet e tjera nuk do të jenë të ngarkuara.","%d files queued":"Dosja %d e vendosur në rradhë","File: %s, size: %d, max file size: %d":"Dosje: %s, madhësia: %d, madhësia maximale e dosjes: %d","Thumbnails":"","Drag files here.":"Këtu mund të tërhiqni dosjet","Runtime ran out of available memory.":"Memoria që ishte në dispozicion ka mbaruar.","File count error.":"Gabim në lidhje me numrin e dosjeve.","File extension error.":"Gabim i zgjerimit të dosjes.","mb":"MB","Add Files":"Shtoni dosjet"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/sr.js

@@ -0,0 +1,2 @@
+// Serbian (sr)
+plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"","Size":"Veličina","Close":"Close","You must specify either browse_button or drop_element.":"","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Dodajte fajlove u listu i kliknite na dugme Start.","List":"","Filename":"Naziv fajla","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Počni upload","Error: File too large:":"Error: File too large:","kb":"","Duplicate file error.":"","File size error.":"File size error.","N/A":"N/A","gb":"","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Izaberite fajlove","%s already present in the queue.":"","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"File: %s","b":"","Uploaded %d/%d files":"Snimljeno %d/%d fajlova","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d files queued","File: %s, size: %d, max file size: %d":"","Thumbnails":"","Drag files here.":"Prevucite fajlove ovde.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"File count error.","File extension error.":"File extension error.","mb":"","Add Files":"Dodaj fajlove"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/sv.js

@@ -0,0 +1,2 @@
+// Swedish (sv)
+plupload.addI18n({"Stop Upload":"Avbryt","Upload URL might be wrong or doesn't exist.":"URL:en va fel eller existerar inte.","tb":"tb","Size":"Storlek","Close":"Stäng","You must specify either browse_button or drop_element.":"Du behöver specificera browse_button eller drop_element.","Init error.":"Problem vid initialisering.","Add files to the upload queue and click the start button.":"Lägg till filer till kön och tryck på start.","List":"Lista","Filename":"Filnamn","%s specified, but cannot be found.":"%s specificerad, men hittades inte.","Image format either wrong or not supported.":"Bildformatet är fel eller så finns inte stöd för det.","Status":"Status","HTTP Error.":"HTTP problem.","Start Upload":"Starta","Error: File too large:":"Fel: Filen är för stor:","kb":"kb","Duplicate file error.":"Problem med dubbla filer.","File size error.":"Problem med filstorlek.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Fel: Ej godkänd filändelse.","Select files":"Välj filer","%s already present in the queue.":"%s är redan tillagd.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Upplösning utanför gränserna! <b>%s</b> bara bilder upp till %wx%hpx stöds.","File: %s":"Fil: %s","b":"b","Uploaded %d/%d files":"Laddade upp %d/%d filer","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Det går bara lägga till %d filer åt gången, allt utöver detta togs bort.","%d files queued":"%d filer i kö","File: %s, size: %d, max file size: %d":"Fil: %s, storlek: %d, max storlek: %d","Thumbnails":"Miniatyrer","Drag files here.":"Dra filer hit","Runtime ran out of available memory.":"Slut på minne.","File count error.":"Räknefel.","File extension error.":"Problem med filändelse.","mb":"mb","Add Files":"Lägg till"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/th_TH.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/tr.js

@@ -0,0 +1,2 @@
+// Turkish (tr)
+plupload.addI18n({"Stop Upload":"Yüklemeyi durdur","Upload URL might be wrong or doesn't exist.":"URL yok ya da hatalı olabilir.","tb":"tb","Size":"Boyut","Close":"Kapat","You must specify either browse_button or drop_element.":"browse_button veya drop_element değişkenlerini belirlemelisiniz.","Init error.":"Başlangıç hatası.","Add files to the upload queue and click the start button.":"Dosyaları kuyruğa ekleyin ve başlatma butonuna tıklayın.","List":"Liste","Filename":"Dosya adı","%s specified, but cannot be found.":"%s tanımlandı fakat bulunamadı.","Image format either wrong or not supported.":"Resim formatı yanlış ya da desteklenmiyor.","Status":"Durum","HTTP Error.":"HTTP hatası.","Start Upload":"Yüklemeyi başlat","Error: File too large:":"Hata: Dosya çok büyük:","kb":"kb","Duplicate file error.":"Yinelenen dosya hatası.","File size error.":"Dosya boyutu hatası.","N/A":"-","gb":"gb","Error: Invalid file extension:":"Hata: Geçersiz dosya uzantısı:","Select files":"Dosyaları seç","%s already present in the queue.":"%s kuyrukta zaten mevcut.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Çözünürlük sınırların dışındadır! <b>%s</b> modu en fazla %wx%hpx desteklemektedir.","File: %s":"Dosya: %s","b":"bayt","Uploaded %d/%d files":"%d/%d dosya yüklendi","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Yükleme elemanı aynı anda %d dosya kabul eder. Ekstra dosyalar işleme konulmaz.","%d files queued":"Kuyrukta %d dosya var.","File: %s, size: %d, max file size: %d":"Dosya: %s, boyut: %d, maksimum dosya boyutu: %d","Thumbnails":"Önizlemeler","Drag files here.":"Dosyaları buraya bırakın.","Runtime ran out of available memory.":"İşlem için yeterli bellek yok.","File count error.":"Dosya sayım hatası.","File extension error.":"Dosya uzantısı hatası.","mb":"mb","Add Files":"Dosya ekle"});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/uk_UA.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
app/assets/js/plupload-2.3.7/js/i18n/vi.js


+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/zh_CN.js

@@ -0,0 +1,2 @@
+// Chinese (China) (zh_CN)
+plupload.addI18n({"Stop Upload":"停止上传","Upload URL might be wrong or doesn't exist.":"上传的URL可能是错误的或不存在。","tb":"tb","Size":"大小","Close":"关闭","You must specify either browse_button or drop_element.":"您必须指定 browse_button 或者 drop_element。","Init error.":"初始化错误。","Add files to the upload queue and click the start button.":"将文件添加到上传队列,然后点击”开始上传“按钮。","List":"列表","Filename":"文件名","%s specified, but cannot be found.":"%s 已指定,但是没有找到。","Image format either wrong or not supported.":"图片格式错误或者不支持。","Status":"状态","HTTP Error.":"HTTP 错误。","Start Upload":"开始上传","Error: File too large:":"错误: 文件太大:","kb":"kb","Duplicate file error.":"重复文件错误。","File size error.":"文件大小错误。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"错误:无效的文件扩展名:","Select files":"选择文件","%s already present in the queue.":"%s 已经在当前队列里。","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"超限。<b>%s</b> 支持最大 %wx%hpx 的图片。","File: %s":"文件: %s","b":"b","Uploaded %d/%d files":"已上传 %d/%d 个文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只接受同时上传 %d 个文件,多余的文件将会被删除。","%d files queued":"%d 个文件加入到队列","File: %s, size: %d, max file size: %d":"文件: %s, 大小: %d, 最大文件大小: %d","Thumbnails":"缩略图","Drag files here.":"把文件拖到这里。","Runtime ran out of available memory.":"运行时已消耗所有可用内存。","File count error.":"文件数量错误。","File extension error.":"文件扩展名错误。","mb":"mb","Add Files":"增加文件"});

+ 2 - 0
app/assets/js/plupload-2.3.7/js/i18n/zh_TW.js

@@ -0,0 +1,2 @@
+// Chinese (Taiwan) (zh_TW)
+plupload.addI18n({"Stop Upload":"停止上傳","Upload URL might be wrong or doesn't exist.":"檔案URL可能有誤或者不存在。","tb":"tb","Size":"大小","Close":"關閉","You must specify either browse_button or drop_element.":"您必須指定 browse_button 或 drop_element。","Init error.":"初始化錯誤。","Add files to the upload queue and click the start button.":"將檔案加入上傳序列,然後點選”開始上傳“按鈕。","List":"清單","Filename":"檔案名稱","%s specified, but cannot be found.":"找不到已選擇的 %s。","Image format either wrong or not supported.":"圖片格式錯誤或者不支援。","Status":"狀態","HTTP Error.":"HTTP 錯誤。","Start Upload":"開始上傳","Error: File too large:":"錯誤: 檔案大小太大:","kb":"kb","Duplicate file error.":"錯誤:檔案重複。","File size error.":"錯誤:檔案大小超過限制。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"錯誤:不接受的檔案格式:","Select files":"選擇檔案","%s already present in the queue.":"%s 已經存在目前的檔案序列。","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"圖片解析度超出範圍! <b>%s</b> 最高只支援到 %wx%hpx。","File: %s":"檔案: %s","b":"b","Uploaded %d/%d files":"已上傳 %d/%d 個文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只能上傳 %d 個檔案,超過限制數量的檔案將被忽略。","%d files queued":"%d 個檔案加入到序列","File: %s, size: %d, max file size: %d":"檔案: %s, 大小: %d, 檔案大小上限: %d","Thumbnails":"縮圖","Drag files here.":"把檔案拖曳到這裡。","Runtime ran out of available memory.":"執行時耗盡了所有可用的記憶體。","File count error.":"檔案數量錯誤。","File extension error.":"檔案副檔名錯誤。","mb":"mb","Add Files":"增加檔案"});

+ 185 - 0
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/css/jquery.plupload.queue.css

@@ -0,0 +1,185 @@
+/* 
+   Plupload
+------------------------------------------------------------------- */
+
+.plupload_wrapper * {
+	box-sizing: content-box;
+}
+
+.plupload_button {
+	display: -moz-inline-box; /* FF < 3*/
+	display: inline-block;
+	font: normal 12px sans-serif;
+	text-decoration: none;
+    color: #42454a;
+    border: 1px solid #bababa;
+    padding: 2px 8px 3px 20px;
+	margin-right: 4px;
+    background: #f3f3f3 url('../img/buttons.png') no-repeat 0 center;
+	outline: 0;
+
+    /* Optional rounded corners for browsers that support it */
+    -moz-border-radius: 3px;
+    -khtml-border-radius: 3px;
+    -webkit-border-radius: 3px;
+    border-radius: 3px;
+}
+
+.plupload_button:hover {
+	color: #000;
+	text-decoration: none;
+}
+
+.plupload_disabled, a.plupload_disabled:hover {
+    color: #737373;
+    border-color: #c5c5c5;
+    background: #ededed url('../img/buttons-disabled.png') no-repeat 0 center;
+	cursor: default;
+}
+
+.plupload_add {
+	background-position: -181px center;
+}
+
+.plupload_wrapper {
+	font: normal 11px Verdana,sans-serif;
+	width: 100%;
+}
+
+.plupload_container {
+	padding: 8px;
+	background: url('../img/transp50.png');
+	/*-moz-border-radius: 5px;*/
+}
+
+.plupload_container input {
+	border: 1px solid #DDD;
+	font: normal 11px Verdana,sans-serif;
+	width: 98%;
+}
+
+.plupload_header {background: #2A2C2E url('../img/backgrounds.gif') repeat-x;}
+.plupload_header_content {
+	background: url('../img/backgrounds.gif') no-repeat 0 -317px;
+	min-height: 56px;
+	padding-left: 60px;
+	color: #FFF;
+}
+.plupload_header_title {
+	font: normal 18px sans-serif;
+	padding: 6px 0 3px;
+}
+.plupload_header_text {
+	font: normal 12px sans-serif;
+}
+
+.plupload_filelist {
+	margin: 0;
+	padding: 0;
+	list-style: none;
+}
+
+.plupload_scroll .plupload_filelist {
+	height: 185px;
+	background: #F5F5F5;
+	overflow-y: scroll;
+}
+
+.plupload_filelist li {
+	padding: 10px 8px;
+	background: #F5F5F5 url('../img/backgrounds.gif') repeat-x 0 -156px;
+	border-bottom: 1px solid #DDD;
+}
+
+.plupload_filelist_header, .plupload_filelist_footer {
+	background: #DFDFDF;
+	padding: 8px 8px;
+	color: #42454A;
+}
+.plupload_filelist_header {	
+	border-top: 1px solid #EEE;
+	border-bottom: 1px solid #CDCDCD;
+}
+
+.plupload_filelist_footer {border-top: 1px solid #FFF; height: 22px; line-height: 20px; vertical-align: middle;}
+.plupload_file_name {float: left; overflow: hidden}
+.plupload_file_status {color: #777;}
+.plupload_file_status span {color: #42454A;}
+.plupload_file_size, .plupload_file_status, .plupload_progress {
+	float: right;
+	width: 80px;
+}
+.plupload_file_size, .plupload_file_status, .plupload_file_action {text-align: right;}
+
+.plupload_filelist .plupload_file_name {
+	width: 205px;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+.plupload_file_action {
+	float: right;
+	width: 16px;
+	height: 16px;
+	margin-left: 15px;
+}
+
+.plupload_file_action * {
+	display: none;
+	width: 16px;
+	height: 16px;
+}
+
+li.plupload_uploading {background: #ECF3DC url('../img/backgrounds.gif') repeat-x 0 -238px;}
+li.plupload_done {color:#AAA}
+
+li.plupload_delete a {
+	background: url('../img/delete.gif');
+}
+
+li.plupload_failed a {
+	background: url('../img/error.gif');
+	cursor: default;
+}
+
+li.plupload_done a {
+	background: url('../img/done.gif');
+	cursor: default;
+}
+
+.plupload_progress, .plupload_upload_status {
+	display: none;
+}
+
+.plupload_progress_container {
+	margin-top: 3px;
+	border: 1px solid #CCC;
+	background: #FFF;
+	padding: 1px;
+}
+.plupload_progress_bar {
+	width: 0px;
+	height: 7px;
+	background: #CDEB8B;
+}
+
+.plupload_scroll .plupload_filelist_header .plupload_file_action, .plupload_scroll .plupload_filelist_footer .plupload_file_action {
+	margin-right: 17px;
+}
+
+/* Floats */
+
+.plupload_clear,.plupload_clearer {clear: both;}
+.plupload_clearer, .plupload_progress_bar {
+	display: block;
+	font-size: 0;
+	line-height: 0;	
+}
+
+li.plupload_droptext {
+	background: transparent;
+	text-align: center;
+	vertical-align: middle;
+	border: 0;
+	line-height: 165px;
+}

BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/backgrounds.gif


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/buttons-disabled.png


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/buttons.png


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/delete.gif


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/done.gif


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/error.gif


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/throbber.gif


BIN
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/img/transp50.png


+ 433 - 0
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/jquery.plupload.queue.js

@@ -0,0 +1,433 @@
+/**
+ * jquery.plupload.queue.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ */
+
+/* global jQuery:true, alert:true */
+
+/**
+jQuery based implementation of the Plupload API - multi-runtime file uploading API.
+
+To use the widget you must include _jQuery_. It is not meant to be extended in any way and is provided to be
+used as it is.
+
+@example
+	<!-- Instantiating: -->
+	<div id="uploader">
+		<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
+	</div>
+
+	<script>
+		$('#uploader').pluploadQueue({
+			url : '../upload.php',
+			filters : [
+				{title : "Image files", extensions : "jpg,gif,png"}
+			],
+			rename: true,
+			flash_swf_url : '../../js/Moxie.swf',
+			silverlight_xap_url : '../../js/Moxie.xap',
+		});
+	</script>
+
+@example
+	// Retrieving a reference to plupload.Uploader object
+	var uploader = $('#uploader').pluploadQueue();
+
+	uploader.bind('FilesAdded', function() {
+
+		// Autostart
+		setTimeout(uploader.start, 1); // "detach" from the main thread
+	});
+
+@class pluploadQueue
+@constructor
+@param {Object} settings For detailed information about each option check documentation.
+	@param {String} settings.url URL of the server-side upload handler.
+	@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
+	@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
+	@param {Array} [settings.filters=[]] Set of file type filters, each one defined by hash of title and extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
+	@param {String} [settings.flash_swf_url] URL of the Flash swf.
+	@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
+	@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
+	@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
+	@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
+	@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
+	@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
+	@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
+	@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
+	@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
+		@param {Number} [settings.resize.width] If image is bigger, it will be resized.
+		@param {Number} [settings.resize.height] If image is bigger, it will be resized.
+		@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
+		@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
+	@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
+	@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
+	@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
+
+	@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
+	@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
+	@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
+*/
+;(function($, plupload) {
+	var uploaders = {};
+
+	function _(str) {
+		return plupload.translate(str) || str;
+	}
+
+	function renderUI(id, target) {
+		// Remove all existing non plupload items
+		target.contents().each(function(i, node) {
+			node = $(node);
+
+			if (!node.is('.plupload')) {
+				node.remove();
+			}
+		});
+
+		target.prepend(
+			'<div class="plupload_wrapper plupload_scroll">' +
+				'<div id="' + id + '_container" class="plupload_container">' +
+					'<div class="plupload">' +
+						'<div class="plupload_header">' +
+							'<div class="plupload_header_content">' +
+								'<div class="plupload_header_title">' + _('Select files') + '</div>' +
+								'<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
+							'</div>' +
+						'</div>' +
+
+						'<div class="plupload_content">' +
+							'<div class="plupload_filelist_header">' +
+								'<div class="plupload_file_name">' + _('Filename') + '</div>' +
+								'<div class="plupload_file_action">&nbsp;</div>' +
+								'<div class="plupload_file_status"><span>' + _('Status') + '</span></div>' +
+								'<div class="plupload_file_size">' + _('Size') + '</div>' +
+								'<div class="plupload_clearer">&nbsp;</div>' +
+							'</div>' +
+
+							'<ul id="' + id + '_filelist" class="plupload_filelist"></ul>' +
+
+							'<div class="plupload_filelist_footer">' +
+								'<div class="plupload_file_name">' +
+									'<div class="plupload_buttons">' +
+										'<a href="#" class="plupload_button plupload_add" id="' + id + '_browse">' + _('Add Files') + '</a>' +
+										'<a href="#" class="plupload_button plupload_start">' + _('Start Upload') + '</a>' +
+									'</div>' +
+									'<span class="plupload_upload_status"></span>' +
+								'</div>' +
+								'<div class="plupload_file_action"></div>' +
+								'<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>' +
+								'<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>' +
+								'<div class="plupload_progress">' +
+									'<div class="plupload_progress_container">' +
+										'<div class="plupload_progress_bar"></div>' +
+									'</div>' +
+								'</div>' +
+								'<div class="plupload_clearer">&nbsp;</div>' +
+							'</div>' +
+						'</div>' +
+					'</div>' +
+				'</div>' +
+				'<input type="hidden" id="' + id + '_count" name="' + id + '_count" value="0" />' +
+			'</div>'
+		);
+	}
+
+	$.fn.pluploadQueue = function(settings) {
+		if (settings) {
+			this.each(function() {
+				var uploader, target, id, contents_bak;
+
+				target = $(this);
+				id = target.attr('id');
+
+				if (!id) {
+					id = plupload.guid();
+					target.attr('id', id);
+				}
+
+				contents_bak = target.html();
+				renderUI(id, target);
+
+				settings = $.extend({
+					dragdrop : true,
+					browse_button : id + '_browse',
+					container : id
+				}, settings);
+
+				// Enable drag/drop (see PostInit handler as well)
+				if (settings.dragdrop) {
+					settings.drop_element = id + '_filelist';
+				}
+
+				uploader = new plupload.Uploader(settings);
+
+				uploaders[id] = uploader;
+
+				function handleStatus(file) {
+					var actionClass;
+
+					if (file.status == plupload.DONE) {
+						actionClass = 'plupload_done';
+					}
+
+					if (file.status == plupload.FAILED) {
+						actionClass = 'plupload_failed';
+					}
+
+					if (file.status == plupload.QUEUED) {
+						actionClass = 'plupload_delete';
+					}
+
+					if (file.status == plupload.UPLOADING) {
+						actionClass = 'plupload_uploading';
+					}
+
+					var icon = $('#' + file.id).attr('class', actionClass).find('a').css('display', 'block');
+					if (file.hint) {
+						icon.attr('title', file.hint);
+					}
+				}
+
+				function updateTotalProgress() {
+					$('span.plupload_total_status', target).html(uploader.total.percent + '%');
+					$('div.plupload_progress_bar', target).css('width', uploader.total.percent + '%');
+					$('span.plupload_upload_status', target).html(
+						plupload.sprintf(_('Uploaded %d/%d files'), uploader.total.uploaded, uploader.files.length)
+					);
+				}
+
+				function updateList() {
+					var fileList = $('ul.plupload_filelist', target).html(''), inputCount = 0, inputHTML;
+
+					$.each(uploader.files, function(i, file) {
+						inputHTML = '';
+
+						if (file.status == plupload.DONE) {
+							if (file.target_name) {
+								inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_tmpname" value="' + plupload.xmlEncode(file.target_name) + '" />';
+							}
+
+							inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_name" value="' + plupload.xmlEncode(file.name) + '" />';
+							inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_status" value="' + (file.status == plupload.DONE ? 'done' : 'failed') + '" />';
+
+							inputCount++;
+
+							$('#' + id + '_count').val(inputCount);
+						}
+
+						fileList.append(
+							'<li id="' + file.id + '">' +
+								'<div class="plupload_file_name"><span>' + file.name + '</span></div>' +
+								'<div class="plupload_file_action"><a href="#"></a></div>' +
+								'<div class="plupload_file_status">' + file.percent + '%</div>' +
+								'<div class="plupload_file_size">' + plupload.formatSize(file.size) + '</div>' +
+								'<div class="plupload_clearer">&nbsp;</div>' +
+								inputHTML +
+							'</li>'
+						);
+
+						handleStatus(file);
+
+						$('#' + file.id + '.plupload_delete a').click(function(e) {
+							$('#' + file.id).remove();
+							uploader.removeFile(file);
+
+							e.preventDefault();
+						});
+					});
+
+					$('span.plupload_total_file_size', target).html(plupload.formatSize(uploader.total.size));
+
+					if (uploader.total.queued === 0) {
+						$('span.plupload_add_text', target).html(_('Add Files'));
+					} else {
+						$('span.plupload_add_text', target).html(plupload.sprintf(_('%d files queued'), uploader.total.queued));
+					}
+
+					$('a.plupload_start', target).toggleClass('plupload_disabled', uploader.files.length == (uploader.total.uploaded + uploader.total.failed));
+
+					// Scroll to end of file list
+					fileList[0].scrollTop = fileList[0].scrollHeight;
+
+					updateTotalProgress();
+
+					// Re-add drag message if there is no files
+					if (!uploader.files.length && uploader.features.dragdrop && uploader.settings.dragdrop) {
+						$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
+					}
+				}
+
+				function destroy() {
+					delete uploaders[id];
+					uploader.destroy();
+					target.html(contents_bak);
+					uploader = target = contents_bak = null;
+				}
+
+				uploader.bind("UploadFile", function(up, file) {
+					$('#' + file.id).addClass('plupload_current_file');
+				});
+
+				uploader.bind('Init', function(up, res) {
+					// Enable rename support
+					if (!settings.unique_names && settings.rename) {
+						target.on('click', '#' + id + '_filelist div.plupload_file_name span', function(e) {
+							var targetSpan = $(e.target), file, parts, name, ext = "";
+							var fileContainer = targetSpan.closest('li');
+
+							if (!fileContainer.hasClass('plupload_delete')) {
+								return;
+							}
+
+							// Get file name and split out name and extension
+							file = up.getFile(targetSpan.parents('li')[0].id);
+							name = file.name;
+							parts = /^(.+)(\.[^.]+)$/.exec(name);
+							if (parts) {
+								name = parts[1];
+								ext = parts[2];
+							}
+
+							// Display input element
+							targetSpan.hide().after('<input type="text" />');
+							targetSpan.next().val(name).focus().blur(function() {
+								targetSpan.show().next().remove();
+							}).keydown(function(e) {
+								var targetInput = $(this);
+
+								if (e.keyCode == 13) {
+									e.preventDefault();
+
+									// Rename file and glue extension back on
+									file.name = targetInput.val() + ext;
+									targetSpan.html(file.name);
+									targetInput.blur();
+								}
+							});
+						});
+					}
+
+					$('#' + id + '_container').attr('title', 'Using runtime: ' + res.runtime);
+
+					$('a.plupload_start', target).click(function(e) {
+						if (!$(this).hasClass('plupload_disabled')) {
+							uploader.start();
+						}
+
+						e.preventDefault();
+					});
+
+					$('a.plupload_stop', target).click(function(e) {
+						e.preventDefault();
+						uploader.stop();
+					});
+
+					$('a.plupload_start', target).addClass('plupload_disabled');
+				});
+
+				uploader.bind("Error", function(up, err) {
+					var file = err.file, message;
+
+					if (file) {
+						message = err.message;
+
+						if (err.details) {
+							message += " (" + err.details + ")";
+						}
+
+						if (err.code == plupload.FILE_SIZE_ERROR) {
+							alert(_("Error: File too large:") + " " + file.name);
+						}
+
+						if (err.code == plupload.FILE_EXTENSION_ERROR) {
+							alert(_("Error: Invalid file extension:") + " " + file.name);
+						}
+
+						file.hint = message;
+						$('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'block').attr('title', message);
+					}
+
+					if (err.code === plupload.INIT_ERROR) {
+						setTimeout(function() {
+							destroy();
+						}, 1);
+					}
+				});
+
+				uploader.bind("PostInit", function(up) {
+					// features are populated only after input components are fully instantiated
+					if (up.settings.dragdrop && up.features.dragdrop) {
+						$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
+					}
+				});
+
+				uploader.init();
+
+				uploader.bind('StateChanged', function() {
+					if (uploader.state === plupload.STARTED) {
+						$('li.plupload_delete a,div.plupload_buttons', target).hide();
+						uploader.disableBrowse(true);
+
+						$('span.plupload_upload_status,div.plupload_progress,a.plupload_stop', target).css('display', 'block');
+						$('span.plupload_upload_status', target).html('Uploaded ' + uploader.total.uploaded + '/' + uploader.files.length + ' files');
+
+						if (settings.multiple_queues) {
+							$('span.plupload_total_status,span.plupload_total_file_size', target).show();
+						}
+					} else {
+						updateList();
+						$('a.plupload_stop,div.plupload_progress', target).hide();
+						$('a.plupload_delete', target).css('display', 'block');
+
+						if (settings.multiple_queues && uploader.total.uploaded + uploader.total.failed == uploader.files.length) {
+							$(".plupload_buttons,.plupload_upload_status", target).css("display", "inline");
+							uploader.disableBrowse(false);
+
+							$(".plupload_start", target).addClass("plupload_disabled");
+							$('span.plupload_total_status,span.plupload_total_file_size', target).hide();
+						}
+					}
+				});
+
+				uploader.bind('FilesAdded', updateList);
+
+				uploader.bind('FilesRemoved', function() {
+					// since the whole file list is redrawn for every change in the queue
+					// we need to scroll back to the file removal point to avoid annoying
+					// scrolling to the bottom bug (see #926)
+					var scrollTop = $('#' + id + '_filelist').scrollTop();
+					updateList();
+					$('#' + id + '_filelist').scrollTop(scrollTop);
+				});
+
+				uploader.bind('FileUploaded', function(up, file) {
+					handleStatus(file);
+				});
+
+				uploader.bind("UploadProgress", function(up, file) {
+					// Set file specific progress
+					$('#' + file.id + ' div.plupload_file_status', target).html(file.percent + '%');
+
+					handleStatus(file);
+					updateTotalProgress();
+				});
+
+				// Call setup function
+				if (settings.setup) {
+					settings.setup(uploader);
+				}
+			});
+
+			return this;
+		} else {
+			// Get uploader instance for specified element
+			return uploaders[$(this[0]).attr('id')];
+		}
+	};
+})(jQuery, plupload);

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
app/assets/js/plupload-2.3.7/js/jquery.plupload.queue/jquery.plupload.queue.min.js


+ 379 - 0
app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/css/jquery.ui.plupload.css

@@ -0,0 +1,379 @@
+/*
+   Plupload
+------------------------------------------------------------------- */
+
+.plupload_wrapper * {
+	box-sizing: content-box;
+}
+
+.plupload_button {
+	cursor: pointer;
+	outline: none;
+}
+
+.plupload_wrapper {
+	font: normal 11px Verdana,sans-serif;
+	width: 100%;
+	min-width: 520px;
+	line-height: 12px;
+}
+
+.plupload_container {
+	_height: 300px;
+	min-height: 300px;
+	position: relative;
+}
+
+.plupload_filelist_footer {border-width: 1px 0 0 0}
+.plupload_file {border-width: 0 0 1px 0}
+.plupload_container .plupload_header {border-width: 0 0 1px 0; position: relative;}
+
+.plupload_delete .ui-icon,
+.plupload_done .ui-icon,
+.plupload_failed .ui-icon {
+	cursor:pointer;
+}
+
+.plupload_header_content {
+	height: 56px;
+	padding: 0 160px 0 60px;
+	position: relative;
+}
+
+.plupload_logo {
+	width: 40px;
+	height: 40px;
+	background: url('../img/plupload.png') no-repeat 0 0;
+	position: absolute;
+	top: 8px;
+	left: 8px;
+}
+
+.plupload_header_content_bw .plupload_logo {
+	background-position: -40px 0;
+}
+
+.plupload_header_title {
+	font: normal 18px sans-serif;
+	line-height: 19px;
+	padding: 6px 0 3px;
+}
+
+.plupload_header_text {
+	font: normal 12px sans-serif;
+}
+
+.plupload_view_switch {
+	position: absolute;
+	right: 16px;
+	bottom: 8px;
+	margin: 0;
+	display: none;
+}
+
+.plupload_view_switch .ui-button {
+	margin-right: -0.31em;
+}
+
+.plupload_content {
+	position: absolute;
+	top: 86px;
+	bottom: 44px;
+	left: 0;
+	right: 0;
+	overflow-y: auto;
+	width: 100%;
+}
+
+.plupload_filelist {
+	border-collapse: collapse;
+	border-left: none;
+	border-right: none;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+.plupload_filelist_content {
+	padding: 0;
+	margin: 0;
+}
+
+.plupload_cell {padding: 8px 6px;}
+
+.plupload_file {
+	list-style: none;
+	display: block;
+	position: relative;
+	overflow: hidden;
+	line-height: 12px;
+}
+
+.plupload_file_thumb {
+	position: relative;
+	background-image: none;
+	background-color: #eee;
+}
+
+.plupload_thumb_loading {
+	background: #eee url(../img/loading.gif) center no-repeat;
+}
+
+.plupload_thumb_loading .plupload_file_dummy,
+.plupload_thumb_embedded .plupload_file_dummy {
+	display: none;
+}
+
+.plupload_file_name {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.plupload_filelist_header {
+	border-top: none;
+}
+
+.plupload_filelist_footer {
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+}
+
+.plupload_buttons {
+	position: relative;
+}
+
+/* list view */
+.plupload_view_list .plupload_file {
+	border-left: none;
+	border-right: none;
+	border-top: none;
+	height: 29px;
+	width: 100% !important;
+	/* fix IE6 vertical white-space bug */
+	_float: left;
+	_clear: left;
+}
+
+.plupload_view_list div.plupload_file_size,
+.plupload_view_list div.plupload_file_status,
+.plupload_view_list div.plupload_file_action {
+	padding: 8px 6px;
+	position: absolute;
+	top: 0;
+	right: 0;
+}
+
+.plupload_view_list div.plupload_file_name {
+	margin-right: 156px;
+	padding: 8px 6px;
+	_width: 75%;
+}
+
+.plupload_view_list div.plupload_file_size {
+	right: 28px;
+}
+
+.plupload_view_list div.plupload_file_status {
+	right: 82px;
+}
+
+.plupload_view_list .plupload_file_rename {
+	margin-left: -2px;
+}
+
+.plupload_view_list .plupload_file_size,
+.plupload_view_list .plupload_file_status,
+.plupload_filelist_footer .plupload_file_size,
+.plupload_filelist_footer .plupload_file_status {
+	text-align: right;
+	width: 52px;
+}
+
+.plupload_view_list .plupload_file_thumb {
+	position: absolute;
+	top: -999px;
+}
+
+.plupload_view_list .plupload_file_progress {
+	display: none;
+}
+
+
+/* thumbs view */
+.plupload_view_thumbs .plupload_content {
+	top: 57px;
+}
+
+.plupload_view_thumbs .plupload_filelist_header {
+	display: none;
+}
+
+.plupload_view_thumbs .plupload_file {
+	padding: 6px;
+	margin: 10px;
+	border: 1px solid #fff;
+	float: left;
+}
+
+.plupload_view_thumbs .plupload_file_thumb,
+.plupload_view_thumbs .plupload_file_dummy {
+	text-align: center;
+	overflow: hidden;
+}
+
+.plupload_view_thumbs .plupload_file_dummy {
+	font-size: 21px;
+	font-weight: bold;
+	text-transform: lowercase;
+	overflow: hidden;
+	border: none;
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.plupload_view_thumbs div.plupload_file_action {
+	position: absolute;
+	top: 0;
+	right: 0;
+}
+
+.plupload_view_thumbs div.plupload_file_name {
+	padding: 0;
+	font-weight: bold;
+}
+
+.plupload_view_thumbs .plupload_file_rename {
+	padding: 1px 0;
+	width: 100% !important;
+}
+
+.plupload_view_thumbs div.plupload_file_size {
+	font-size: 0.8em;
+	font-weight: normal;
+}
+
+.plupload_view_thumbs div.plupload_file_status {
+	position: relative;
+	height: 3px;
+	overflow: hidden;
+	text-indent: -999px;
+	margin-bottom: 3px;
+}
+
+.plupload_view_thumbs div.plupload_file_progress {
+	border: none;
+	height: 100%;
+}
+
+.plupload .ui-sortable-helper,
+.plupload .ui-sortable .plupload_file {
+	cursor:move;
+}
+
+.plupload_file_action {width: 16px;}
+.plupload_file_name {
+	overflow: hidden;
+	padding-left: 10px;
+}
+
+.plupload_file_rename {
+	border: none;
+	font: normal 11px Verdana, sans-serif;
+	padding: 1px 2px;
+	line-height: 11px;
+	height: 11px;
+}
+
+.plupload_progress {width: 60px;}
+.plupload_progress_container {padding: 1px;}
+
+
+/* Floats */
+
+.plupload_right {float: right;}
+.plupload_left {float: left;}
+.plupload_clear,.plupload_clearer {clear: both;}
+.plupload_clearer, .plupload_progress_bar {
+	display: block;
+	font-size: 0;
+	line-height: 0;
+}
+.plupload_clearer {height: 0;}
+
+/* Misc */
+.plupload_hidden {display: none !important;}
+
+.plupload_droptext {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	background: transparent;
+	text-align: center;
+	vertical-align: middle;
+	border: 0;
+	line-height: 160px;
+	display: none;
+}
+
+.plupload_dropbox .plupload_droptext {
+	display: block;
+}
+
+.plupload_files_queued .plupload_droptext {
+	display: none;
+}
+
+.plupload_buttons, .plupload_upload_status {float: left}
+
+.plupload_message {
+	position: absolute;
+	top: -1px;
+	left: -1px;
+	height: 100%;
+	width: 100%;
+}
+
+.plupload_message p {
+	padding:0.7em;
+	margin:0;
+}
+
+.plupload_message strong {
+	font-weight: bold;
+}
+
+.plupload_message i {
+	font-style: italic;
+}
+
+.plupload_message p span.ui-icon {
+	float: left;
+	margin-right: 0.3em;
+}
+
+.plupload_header_content .ui-state-error,
+.plupload_header_content .ui-state-highlight {
+	border:none;
+}
+
+.plupload_message_close {
+	position:absolute;
+	top:5px;
+	right:5px;
+	cursor:pointer;
+}
+
+.plupload .ui-sortable-placeholder {
+	height:35px;
+}

BIN
app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/img/loading.gif


BIN
app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/img/plupload.png


+ 1358 - 0
app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/jquery.ui.plupload.js

@@ -0,0 +1,1358 @@
+/**
+ * jquery.ui.plupload.js
+ *
+ * Copyright 2013, Moxiecode Systems AB
+ * Released under GPL License.
+ *
+ * License: http://www.plupload.com/license
+ * Contributing: http://www.plupload.com/contributing
+ *
+ * Depends:
+ *	jquery.ui.core.js
+ *	jquery.ui.widget.js
+ *	jquery.ui.button.js
+ *	jquery.ui.progressbar.js
+ *
+ * Optionally:
+ *	jquery.ui.sortable.js
+ */
+
+ /* global jQuery:true */
+
+/**
+jQuery UI based implementation of the Plupload API - multi-runtime file uploading API.
+
+To use the widget you must include _jQuery_ and _jQuery UI_ bundle (including `ui.core`, `ui.widget`, `ui.button`,
+`ui.progressbar` and `ui.sortable`).
+
+In general the widget is designed the way that you do not usually need to do anything to it after you instantiate it.
+But! You still can intervenue, to some extent, in case you need to. Although, due to the fact that widget is based on
+_jQuery UI_ widget factory, there are some specifics. See examples below for more details.
+
+@example
+	<!-- Instantiating: -->
+	<div id="uploader">
+		<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
+	</div>
+
+	<script>
+		$('#uploader').plupload({
+			url : '../upload.php',
+			filters : [
+				{title : "Image files", extensions : "jpg,gif,png"}
+			],
+			rename: true,
+			sortable: true,
+			flash_swf_url : '../../js/Moxie.swf',
+			silverlight_xap_url : '../../js/Moxie.xap',
+		});
+	</script>
+
+@example
+	// Invoking methods:
+	$('#uploader').plupload(options);
+
+	// Display welcome message in the notification area
+	$('#uploader').plupload('notify', 'info', "This might be obvious, but you need to click 'Add Files' to add some files.");
+
+@example
+	// Subscribing to the events...
+	// ... on initialization:
+	$('#uploader').plupload({
+		...
+		viewchanged: function(event, args) {
+			// stuff ...
+		}
+	});
+	// ... or after initialization
+	$('#uploader').on("viewchanged", function(event, args) {
+		// stuff ...
+	});
+
+@class UI.Plupload
+@constructor
+@param {Object} settings For detailed information about each option check documentation.
+	@param {String} settings.url URL of the server-side upload handler.
+	@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
+	@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
+	@param {Object} [settings.filters={}] Set of file type filters.
+		@param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
+		@param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
+		@param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
+		@param {Number} [settings.filters.max_file_count=0] Limit the number of files that can reside in the queue at the same time (default is 0 - no limit).
+	@param {String} [settings.flash_swf_url] URL of the Flash swf.
+	@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
+	@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
+	@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
+	@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
+	@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
+	@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
+	@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
+	@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
+	@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
+		@param {Number} [settings.resize.width] If image is bigger, it will be resized.
+		@param {Number} [settings.resize.height] If image is bigger, it will be resized.
+		@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
+		@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
+	@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
+	@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
+	@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
+
+	@param {Boolean} [settings.autostart=false] Whether to auto start uploading right after file selection.
+	@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
+	@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
+	@param {Boolean} [settings.sortable=false] Enable ability to sort files in the queue, changing their uploading priority.
+	@param {Object} [settings.buttons] Control the visibility of functional buttons.
+		@param {Boolean} [settings.buttons.browse=true] Display browse button.
+		@param {Boolean} [settings.buttons.start=true] Display start button.
+		@param {Boolean} [settings.buttons.stop=true] Display stop button.
+	@param {Object} [settings.views] Control various views of the file queue.
+		@param {Boolean} [settings.views.list=true] Enable list view.
+		@param {Boolean} [settings.views.thumbs=false] Enable thumbs view.
+		@param {String} [settings.views.default='list'] Default view.
+		@param {Boolean} [settings.views.remember=true] Whether to remember the current view (requires jQuery Cookie plugin).
+	@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
+*/
+;(function(window, document, plupload, o, $) {
+
+/**
+Dispatched when the widget is initialized and ready.
+
+@event ready
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+*/
+
+/**
+Dispatched when file dialog is closed.
+
+@event selected
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {Array} files Array of selected files represented by plupload.File objects
+*/
+
+/**
+Dispatched when file dialog is closed.
+
+@event removed
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {Array} files Array of removed files represented by plupload.File objects
+*/
+
+/**
+Dispatched when upload is started.
+
+@event started
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+*/
+
+/**
+Dispatched when upload is stopped.
+
+@event stopped
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+*/
+
+/**
+Dispatched during the upload process.
+
+@event progress
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {plupload.File} file File that is being uploaded (includes loaded and percent properties among others).
+	@param {Number} size Total file size in bytes.
+	@param {Number} loaded Number of bytes uploaded of the files total size.
+	@param {Number} percent Number of percentage uploaded of the file.
+*/
+
+/**
+Dispatched when file is uploaded.
+
+@event uploaded
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {plupload.File} file File that was uploaded.
+	@param {Enum} status Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
+*/
+
+/**
+Dispatched when upload of the whole queue is complete.
+
+@event complete
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {Array} files Array of uploaded files represented by plupload.File objects
+*/
+
+/**
+Dispatched when the view is changed, e.g. from `list` to `thumbs` or vice versa.
+
+@event viewchanged
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {String} type Current view type.
+*/
+
+/**
+Dispatched when error of some kind is detected.
+
+@event error
+@param {plupload.Uploader} uploader Uploader instance sending the event.
+@param {String} error Error message.
+@param {plupload.File} file File that was uploaded.
+	@param {Enum} status Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
+*/
+
+var uploaders = {};
+
+function _(str) {
+	return plupload.translate(str) || str;
+}
+
+function renderUI(obj) {
+	obj.id = obj.attr('id');
+
+	obj.html(
+		'<div class="plupload_wrapper">' +
+			'<div class="ui-widget-content plupload_container">' +
+				'<div class="ui-state-default ui-widget-header plupload_header">' +
+					'<div class="plupload_header_content">' +
+						'<div class="plupload_logo"> </div>' +
+						'<div class="plupload_header_title">' + _("Select files") + '</div>' +
+						'<div class="plupload_header_text">' + _("Add files to the upload queue and click the start button.") + '</div>' +
+						'<div class="plupload_view_switch">' +
+							'<input type="radio" id="'+obj.id+'_view_list" name="view_mode_'+obj.id+'" checked="checked" /><label class="plupload_button" for="'+obj.id+'_view_list" data-view="list">' + _('List') + '</label>' +
+							'<input type="radio" id="'+obj.id+'_view_thumbs" name="view_mode_'+obj.id+'" /><label class="plupload_button"  for="'+obj.id+'_view_thumbs" data-view="thumbs">' + _('Thumbnails') + '</label>' +
+						'</div>' +
+					'</div>' +
+				'</div>' +
+
+				'<table class="plupload_filelist plupload_filelist_header ui-widget-header">' +
+				'<tr>' +
+					'<td class="plupload_cell plupload_file_name">' + _('Filename') + '</td>' +
+					'<td class="plupload_cell plupload_file_status">' + _('Status') + '</td>' +
+					'<td class="plupload_cell plupload_file_size">' + _('Size') + '</td>' +
+					'<td class="plupload_cell plupload_file_action">&nbsp;</td>' +
+				'</tr>' +
+				'</table>' +
+
+				'<div class="plupload_content">' +
+					'<div class="plupload_droptext">' + _("Drag files here.") + '</div>' +
+					'<ul class="plupload_filelist_content"> </ul>' +
+					'<div class="plupload_clearer">&nbsp;</div>' +
+				'</div>' +
+
+				'<table class="plupload_filelist plupload_filelist_footer ui-widget-header">' +
+				'<tr>' +
+					'<td class="plupload_cell plupload_file_name">' +
+						'<div class="plupload_buttons"><!-- Visible -->' +
+							'<a class="plupload_button plupload_add">' + _("Add Files") + '</a>&nbsp;' +
+							'<a class="plupload_button plupload_start">' + _("Start Upload") + '</a>&nbsp;' +
+							'<a class="plupload_button plupload_stop plupload_hidden">'+_("Stop Upload") + '</a>&nbsp;' +
+						'</div>' +
+
+						'<div class="plupload_started plupload_hidden"><!-- Hidden -->' +
+							'<div class="plupload_progress plupload_right">' +
+								'<div class="plupload_progress_container"></div>' +
+							'</div>' +
+
+							'<div class="plupload_cell plupload_upload_status"></div>' +
+
+							'<div class="plupload_clearer">&nbsp;</div>' +
+						'</div>' +
+					'</td>' +
+					'<td class="plupload_file_status"><span class="plupload_total_status">0%</span></td>' +
+					'<td class="plupload_file_size"><span class="plupload_total_file_size">0 kb</span></td>' +
+					'<td class="plupload_file_action"></td>' +
+				'</tr>' +
+				'</table>' +
+
+			'</div>' +
+			'<input class="plupload_count" value="0" type="hidden">' +
+		'</div>'
+	);
+}
+
+
+$.widget("ui.plupload", {
+
+	widgetEventPrefix: '',
+
+	contents_bak: '',
+
+	options: {
+		browse_button_hover: 'ui-state-hover',
+		browse_button_active: 'ui-state-active',
+
+		filters: {},
+
+		// widget specific
+		buttons: {
+			browse: true,
+			start: true,
+			stop: true
+		},
+
+		views: {
+			list: true,
+			thumbs: false,
+			active: 'list',
+			remember: true // requires: https://github.com/carhartl/jquery-cookie, otherwise disabled even if set to true
+		},
+
+		thumb_width: 100,
+		thumb_height: 60,
+
+		multiple_queues: true, // re-use widget by default
+		dragdrop : true,
+		autostart: false,
+		sortable: false,
+		rename: false
+	},
+
+	FILE_COUNT_ERROR: -9001,
+
+	_create: function() {
+		var id = this.element.attr('id');
+		if (!id) {
+			id = plupload.guid();
+			this.element.attr('id', id);
+		}
+		this.id = id;
+
+		// backup the elements initial state
+		this.contents_bak = this.element.html();
+		renderUI(this.element);
+
+		// container, just in case
+		this.container = $('.plupload_container', this.element).attr('id', id + '_container');
+
+		this.content = $('.plupload_content', this.element);
+
+		if ($.fn.resizable) {
+			this.container.resizable({
+				handles: 's',
+				minHeight: 300
+			});
+		}
+
+		// list of files, may become sortable
+		this.filelist = $('.plupload_filelist_content', this.container)
+			.attr({
+				id: id + '_filelist',
+				unselectable: 'on'
+			});
+
+
+		// buttons
+		this.browse_button = $('.plupload_add', this.container).attr('id', id + '_browse');
+		this.start_button = $('.plupload_start', this.container).attr('id', id + '_start');
+		this.stop_button = $('.plupload_stop', this.container).attr('id', id + '_stop');
+		this.thumbs_switcher = $('#' + id + '_view_thumbs');
+		this.list_switcher = $('#' + id + '_view_list');
+
+		if ($.ui.button) {
+			this.browse_button.button({
+				icons: { primary: 'ui-icon-circle-plus' },
+				disabled: true
+			});
+
+			this.start_button.button({
+				icons: { primary: 'ui-icon-circle-arrow-e' },
+				disabled: true
+			});
+
+			this.stop_button.button({
+				icons: { primary: 'ui-icon-circle-close' }
+			});
+
+			this.list_switcher.button({
+				text: false,
+				icons: { secondary: "ui-icon-grip-dotted-horizontal" }
+			});
+
+			this.thumbs_switcher.button({
+				text: false,
+				icons: { secondary: "ui-icon-image" }
+			});
+		}
+
+		// progressbar
+		this.progressbar = $('.plupload_progress_container', this.container);
+
+		if ($.ui.progressbar) {
+			this.progressbar.progressbar();
+		}
+
+		// counter
+		this.counter = $('.plupload_count', this.element)
+			.attr({
+				id: id + '_count',
+				name: id + '_count'
+			});
+
+		// initialize uploader instance
+		this._initUploader();
+	},
+
+	_initUploader: function() {
+		var self = this
+		, id = this.id
+		, uploader
+		, options = {
+			container: id + '_buttons',
+			browse_button: id + '_browse'
+		}
+		;
+
+		$('.plupload_buttons', this.element).attr('id', id + '_buttons');
+
+		if (self.options.dragdrop) {
+			this.filelist.parent().attr('id', this.id + '_dropbox');
+			options.drop_element = this.id + '_dropbox';
+		}
+
+		this.filelist.on('click', function(e) {
+			var me = $(e.target), fileContainer;
+			if (me.hasClass('plupload_action_icon')) {
+				fileContainer = me.closest('.plupload_file');
+				if (fileContainer.hasClass('plupload_delete')) {
+					self.removeFile(fileContainer.attr('id'));
+					e.preventDefault();
+				}
+			}
+		});
+
+		uploader = this.uploader = uploaders[id] = new plupload.Uploader($.extend(this.options, options));
+
+		// retrieve full normalized set of options
+		this.options = uploader.getOption();
+
+		if (self.options.views.thumbs) {
+			uploader.settings.required_features.display_media = true;
+		}
+
+		// for backward compatibility
+		if (self.options.max_file_count) {
+			plupload.extend(uploader.getOption('filters'), {
+				max_file_count: self.options.max_file_count
+			});
+		}
+
+		plupload.addFileFilter('max_file_count', function(maxCount, file, cb) {
+			if (maxCount <= this.files.length - (this.total.uploaded + this.total.failed)) {
+				self.browse_button.button('disable');
+				this.disableBrowse();
+
+				this.trigger('Error', {
+					code : self.FILE_COUNT_ERROR,
+					message : _("File count error."),
+					file : file
+				});
+				cb(false);
+			} else {
+				cb(true);
+			}
+		});
+
+
+		uploader.bind('Error', function(up, err) {
+			var message, details = "";
+
+			message = '<strong>' + err.message + '</strong>';
+
+			switch (err.code) {
+				case plupload.FILE_EXTENSION_ERROR:
+					details = plupload.sprintf(_("File: %s"), err.file.name);
+					break;
+
+				case plupload.FILE_SIZE_ERROR:
+					details = plupload.sprintf(_("File: %s, size: %d, max file size: %d"), err.file.name,  plupload.formatSize(err.file.size), plupload.formatSize(plupload.parseSize(up.getOption('filters').max_file_size)));
+					break;
+
+				case plupload.FILE_DUPLICATE_ERROR:
+					details = plupload.sprintf(_("%s already present in the queue."), err.file.name);
+					break;
+
+				case self.FILE_COUNT_ERROR:
+					details = plupload.sprintf(_("Upload element accepts only %d file(s) at a time. Extra files were stripped."), up.getOption('filters').max_file_count || 0);
+					break;
+
+				case plupload.IMAGE_FORMAT_ERROR :
+					details = _("Image format either wrong or not supported.");
+					break;
+
+				case plupload.IMAGE_MEMORY_ERROR :
+					details = _("Runtime ran out of available memory.");
+					break;
+
+				/* // This needs a review
+				case plupload.IMAGE_DIMENSIONS_ERROR :
+					details = plupload.sprintf(_('Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.'), up.runtime, up.features.maxWidth, up.features.maxHeight);
+					break;	*/
+
+				case plupload.HTTP_ERROR:
+					details = _("Upload URL might be wrong or doesn't exist.");
+					break;
+			}
+
+			message += " <br /><i>" + details + "</i>";
+
+			self._trigger('error', null, { up: up, error: err } );
+
+			// do not show UI if no runtime can be initialized
+			if (err.code === plupload.INIT_ERROR) {
+				setTimeout(function() {
+					self.destroy();
+				}, 1);
+			} else {
+				self.notify('error', message);
+			}
+		});
+
+
+		uploader.bind('PostInit', function(up) {
+			// all buttons are optional, so they can be disabled and hidden
+			if (!self.options.buttons.browse) {
+				self.browse_button.button('disable').hide();
+				up.disableBrowse(true);
+			} else {
+				self.browse_button.button('enable');
+			}
+
+			if (!self.options.buttons.start) {
+				self.start_button.button('disable').hide();
+			}
+
+			if (!self.options.buttons.stop) {
+				self.stop_button.button('disable').hide();
+			}
+
+			if (!self.options.unique_names && self.options.rename) {
+				self._enableRenaming();
+			}
+
+			if (self.options.dragdrop && up.features.dragdrop) {
+				self.filelist.parent().addClass('plupload_dropbox');
+			}
+
+			self._enableViewSwitcher();
+
+			self.start_button.click(function(e) {
+				if (!$(this).button('option', 'disabled')) {
+					self.start();
+				}
+				e.preventDefault();
+			});
+
+			self.stop_button.click(function(e) {
+				self.stop();
+				e.preventDefault();
+			});
+
+			self._trigger('ready', null, { up: up });
+		});
+
+		// uploader internal events must run first
+		uploader.init();
+
+		uploader.bind('FileFiltered', function(up, file) {
+			self._addFiles(file);
+		});
+
+		uploader.bind('FilesAdded', function(up, files) {
+			self._trigger('selected', null, { up: up, files: files } );
+
+			// re-enable sortable
+			if (self.options.sortable && $.ui.sortable) {
+				self._enableSortingList();
+			}
+
+			self._trigger('updatelist', null, { filelist: self.filelist });
+
+			if (self.options.autostart) {
+				// set a little delay to make sure that QueueChanged triggered by the core has time to complete
+				setTimeout(function() {
+					self.start();
+				}, 10);
+			}
+		});
+
+		uploader.bind('FilesRemoved', function(up, files) {
+			// destroy sortable if enabled
+			if ($.ui.sortable && self.options.sortable) {
+				$('tbody', self.filelist).sortable('destroy');
+			}
+
+			$.each(files, function(i, file) {
+				$('#' + file.id).toggle("highlight", function() {
+					$(this).remove();
+				});
+			});
+
+			if (up.files.length) {
+				// re-initialize sortable
+				if (self.options.sortable && $.ui.sortable) {
+					self._enableSortingList();
+				}
+			}
+
+			self._trigger('updatelist', null, { filelist: self.filelist });
+			self._trigger('removed', null, { up: up, files: files } );
+		});
+
+		uploader.bind('QueueChanged', function() {
+			self._handleState();
+		});
+
+		uploader.bind('StateChanged', function(up) {
+			self._handleState();
+			if (plupload.STARTED === up.state) {
+				self._trigger('started', null, { up: this.uploader });
+			} else if (plupload.STOPPED === up.state) {
+				self._trigger('stopped', null, { up: this.uploader });
+			}
+		});
+
+		uploader.bind('UploadFile', function(up, file) {
+			self._handleFileStatus(file);
+		});
+
+		uploader.bind('FileUploaded', function(up, file, result) {
+			self._handleFileStatus(file);
+			self._trigger('uploaded', null, { up: up, file: file, result: result } );
+		});
+
+		uploader.bind('UploadProgress', function(up, file) {
+			self._handleFileStatus(file);
+			self._updateTotalProgress();
+			self._trigger('progress', null, { up: up, file: file } );
+		});
+
+		uploader.bind('UploadComplete', function(up, files) {
+			self._addFormFields();
+			self._trigger('complete', null, { up: up, files: files } );
+		});
+	},
+
+
+	_setOption: function(key, value) {
+		var self = this;
+
+		if (key == 'buttons' && typeof(value) == 'object') {
+			value = $.extend(self.options.buttons, value);
+
+			if (!value.browse) {
+				self.browse_button.button('disable').hide();
+				self.uploader.disableBrowse(true);
+			} else {
+				self.browse_button.button('enable').show();
+				self.uploader.disableBrowse(false);
+			}
+
+			if (!value.start) {
+				self.start_button.button('disable').hide();
+			} else {
+				self.start_button.button('enable').show();
+			}
+
+			if (!value.stop) {
+				self.stop_button.button('disable').hide();
+			} else {
+				self.start_button.button('enable').show();
+			}
+		}
+
+		self.uploader.setOption(key, value);
+	},
+
+
+	/**
+	Start upload. Triggers `start` event.
+
+	@method start
+	*/
+	start: function() {
+		this.uploader.start();
+	},
+
+
+	/**
+	Stop upload. Triggers `stop` event.
+
+	@method stop
+	*/
+	stop: function() {
+		this.uploader.stop();
+	},
+
+
+	/**
+	Enable browse button.
+
+	@method enable
+	*/
+	enable: function() {
+		this.browse_button.button('enable');
+		this.uploader.disableBrowse(false);
+	},
+
+
+	/**
+	Disable browse button.
+
+	@method disable
+	*/
+	disable: function() {
+		this.browse_button.button('disable');
+		this.uploader.disableBrowse(true);
+	},
+
+
+	/**
+	Retrieve file by its unique id.
+
+	@method getFile
+	@param {String} id Unique id of the file
+	@return {plupload.File}
+	*/
+	getFile: function(id) {
+		var file;
+
+		if (typeof id === 'number') {
+			file = this.uploader.files[id];
+		} else {
+			file = this.uploader.getFile(id);
+		}
+		return file;
+	},
+
+	/**
+	Return array of files currently in the queue.
+
+	@method getFiles
+	@return {Array} Array of files in the queue represented by plupload.File objects
+	*/
+	getFiles: function() {
+		return this.uploader.files;
+	},
+
+
+	/**
+	Remove the file from the queue.
+
+	@method removeFile
+	@param {plupload.File|String} file File to remove, might be specified directly or by its unique id
+	*/
+	removeFile: function(file) {
+		if (plupload.typeOf(file) === 'string') {
+			file = this.getFile(file);
+		}
+		this.uploader.removeFile(file);
+	},
+
+
+	/**
+	Clear the file queue.
+
+	@method clearQueue
+	*/
+	clearQueue: function() {
+		this.uploader.splice();
+	},
+
+
+	/**
+	Retrieve internal plupload.Uploader object (usually not required).
+
+	@method getUploader
+	@return {plupload.Uploader}
+	*/
+	getUploader: function() {
+		return this.uploader;
+	},
+
+
+	/**
+	Trigger refresh procedure, specifically browse_button re-measure and re-position operations.
+	Might get handy, when UI Widget is placed within the popup, that is constantly hidden and shown
+	again - without calling this method after each show operation, dialog trigger might get displaced
+	and disfunctional.
+
+	@method refresh
+	*/
+	refresh: function() {
+		this.uploader.refresh();
+	},
+
+
+	/**
+	Display a message in notification area.
+
+	@method notify
+	@param {Enum} type Type of the message, either `error` or `info`
+	@param {String} message The text message to display.
+	*/
+	notify: function(type, message) {
+		var popup = $(
+			'<div class="plupload_message">' +
+				'<span class="plupload_message_close ui-icon ui-icon-circle-close" title="'+_('Close')+'"></span>' +
+				'<p><span class="ui-icon"></span>' + message + '</p>' +
+			'</div>'
+		);
+
+		popup
+			.addClass('ui-state-' + (type === 'error' ? 'error' : 'highlight'))
+			.find('p .ui-icon')
+				.addClass('ui-icon-' + (type === 'error' ? 'alert' : 'info'))
+				.end()
+			.find('.plupload_message_close')
+				.click(function() {
+					popup.remove();
+				})
+				.end();
+
+		$('.plupload_header', this.container).append(popup);
+	},
+
+
+	/**
+	Destroy the widget, the uploader, free associated resources and bring back original html.
+
+	@method destroy
+	*/
+	destroy: function() {
+		// destroy uploader instance
+		this.uploader.destroy();
+
+		// unbind all button events
+		$('.plupload_button', this.element).unbind();
+
+		// destroy buttons
+		if ($.ui.button) {
+			$('.plupload_add, .plupload_start, .plupload_stop', this.container)
+				.button('destroy');
+		}
+
+		// destroy progressbar
+		if ($.ui.progressbar) {
+			this.progressbar.progressbar('destroy');
+		}
+
+		// destroy sortable behavior
+		if ($.ui.sortable && this.options.sortable) {
+			$('tbody', this.filelist).sortable('destroy');
+		}
+
+		// restore the elements initial state
+		this.element
+			.empty()
+			.html(this.contents_bak);
+		this.contents_bak = '';
+
+		$.Widget.prototype.destroy.apply(this);
+	},
+
+
+	_handleState: function() {
+		var up = this.uploader
+		, filesPending = up.files.length - (up.total.uploaded + up.total.failed)
+		, maxCount = up.getOption('filters').max_file_count || 0
+		;
+
+		if (plupload.STARTED === up.state) {
+			$([])
+				.add(this.stop_button)
+				.add('.plupload_started')
+					.removeClass('plupload_hidden');
+
+			this.start_button.button('disable');
+
+			if (!this.options.multiple_queues) {
+				this.browse_button.button('disable');
+				up.disableBrowse();
+			}
+
+			$('.plupload_upload_status', this.element).html(plupload.sprintf(_('Uploaded %d/%d files'), up.total.uploaded, up.files.length));
+			$('.plupload_header_content', this.element).addClass('plupload_header_content_bw');
+		}
+		else if (plupload.STOPPED === up.state) {
+			$([])
+				.add(this.stop_button)
+				.add('.plupload_started')
+					.addClass('plupload_hidden');
+
+			if (filesPending) {
+				this.start_button.button('enable');
+			} else {
+				this.start_button.button('disable');
+			}
+
+			if (this.options.multiple_queues) {
+				$('.plupload_header_content', this.element).removeClass('plupload_header_content_bw');
+			}
+
+			// if max_file_count defined, only that many files can be queued at once
+			if (this.options.multiple_queues && maxCount && maxCount > filesPending) {
+				this.browse_button.button('enable');
+				up.disableBrowse(false);
+			}
+
+			this._updateTotalProgress();
+		}
+
+		if (up.total.queued === 0) {
+			$('.ui-button-text', this.browse_button).html(_('Add Files'));
+		} else {
+			$('.ui-button-text', this.browse_button).html(plupload.sprintf(_('%d files queued'), up.total.queued));
+		}
+
+		// have a helper class on a container expressing whether it has files queued or not
+		this.container.toggleClass('plupload_files_queued', up.files.length);
+
+		up.refresh();
+	},
+
+
+	_handleFileStatus: function(file) {
+		var $file = $('#' + file.id), actionClass, iconClass;
+
+		// since this method might be called asynchronously, file row might not yet be rendered
+		if (!$file.length) {
+			return;
+		}
+
+		switch (file.status) {
+			case plupload.DONE:
+				actionClass = 'plupload_done';
+				iconClass = 'plupload_action_icon ui-icon ui-icon-circle-check';
+				break;
+
+			case plupload.FAILED:
+				actionClass = 'ui-state-error plupload_failed';
+				iconClass = 'plupload_action_icon ui-icon ui-icon-alert';
+				break;
+
+			case plupload.QUEUED:
+				actionClass = 'plupload_delete';
+				iconClass = 'plupload_action_icon ui-icon ui-icon-circle-minus';
+				break;
+
+			case plupload.UPLOADING:
+				actionClass = 'ui-state-highlight plupload_uploading';
+				iconClass = 'plupload_action_icon ui-icon ui-icon-circle-arrow-w';
+
+				// scroll uploading file into the view if its bottom boundary is out of it
+				var scroller = $('.plupload_scroll', this.container)
+				, scrollTop = scroller.scrollTop()
+				, scrollerHeight = scroller.height()
+				, rowOffset = $file.position().top + $file.height()
+				;
+
+				if (scrollerHeight < rowOffset) {
+					scroller.scrollTop(scrollTop + rowOffset - scrollerHeight);
+				}
+
+				// Set file specific progress
+				$file
+					.find('.plupload_file_percent')
+						.html(file.percent + '%')
+						.end()
+					.find('.plupload_file_progress')
+						.css('width', file.percent + '%')
+						.end()
+					.find('.plupload_file_size')
+						.html(plupload.formatSize(file.size));
+				break;
+		}
+		actionClass += ' ui-state-default plupload_file';
+
+		$file
+			.attr('class', actionClass)
+			.find('.plupload_action_icon')
+				.attr('class', iconClass);
+	},
+
+
+	_updateTotalProgress: function() {
+		var up = this.uploader;
+
+		// Scroll to end of file list
+		this.filelist[0].scrollTop = this.filelist[0].scrollHeight;
+
+		this.progressbar.progressbar('value', up.total.percent);
+
+		this.element
+			.find('.plupload_total_status')
+				.html(up.total.percent + '%')
+				.end()
+			.find('.plupload_total_file_size')
+				.html(plupload.formatSize(up.total.size))
+				.end()
+			.find('.plupload_upload_status')
+				.html(plupload.sprintf(_('Uploaded %d/%d files'), up.total.uploaded, up.files.length));
+	},
+
+
+	_displayThumbs: function() {
+		var self = this
+		, tw, th // thumb width/height
+		, cols
+		, num = 0 // number of simultaneously visible thumbs
+		, thumbs = [] // array of thumbs to preload at any given moment
+		, loading = false
+		;
+
+		if (!this.options.views.thumbs) {
+			return;
+		}
+
+
+		function onLast(el, eventName, cb) {
+			var timer;
+
+			el.on(eventName, function() {
+				clearTimeout(timer);
+				timer = setTimeout(function() {
+					clearTimeout(timer);
+					cb();
+				}, 300);
+			});
+		}
+
+
+		// calculate number of simultaneously visible thumbs
+		function measure() {
+			if (!tw || !th) {
+				var wrapper = $('.plupload_file:eq(0)', self.filelist);
+				tw = wrapper.outerWidth(true);
+				th = wrapper.outerHeight(true);
+			}
+
+			var aw = self.content.width(), ah = self.content.height();
+			cols = Math.floor(aw / tw);
+			num =  cols * (Math.ceil(ah / th) + 1);
+		}
+
+
+		function pickThumbsToLoad() {
+			// calculate index of virst visible thumb
+			var startIdx = Math.floor(self.content.scrollTop() / th) * cols;
+			// get potentially visible thumbs that are not yet visible
+			thumbs = $('.plupload_file .plupload_file_thumb', self.filelist)
+				.slice(startIdx, startIdx + num)
+				.filter('.plupload_thumb_toload')
+				.get();
+		}
+
+
+		function init() {
+			function mpl() { // measure, pick, load
+				if (self.view_mode !== 'thumbs') {
+					return;
+				}
+				measure();
+				pickThumbsToLoad();
+				lazyLoad();
+			}
+
+			if ($.fn.resizable) {
+				onLast(self.container, 'resize', mpl);
+			}
+
+			onLast(self.window, 'resize', mpl);
+			onLast(self.content, 'scroll',  mpl);
+
+			self.element.on('viewchanged selected', mpl);
+
+			mpl();
+		}
+
+
+		function preloadThumb(file, cb) {
+			var img = new o.image.Image();
+			var resolveUrl = o.core.utils.Url.resolveUrl;
+
+			img.onload = function() {
+				var thumb = $('#' + file.id + ' .plupload_file_thumb', self.filelist);
+				this.embed(thumb[0], {
+					width: self.options.thumb_width,
+					height: self.options.thumb_height,
+					crop: true,
+					fit: true,
+					preserveHeaders: false,
+					swf_url: resolveUrl(self.options.flash_swf_url),
+					xap_url: resolveUrl(self.options.silverlight_xap_url)
+				});
+			};
+
+			img.bind("embedded error", function(e) {
+				$('#' + file.id, self.filelist)
+					.find('.plupload_file_thumb')
+						.removeClass('plupload_thumb_loading')
+						.addClass('plupload_thumb_' + e.type)
+					;
+				this.destroy();
+				setTimeout(cb, 1); // detach, otherwise ui might hang (in SilverLight for example)
+			});
+
+			$('#' + file.id, self.filelist)
+				.find('.plupload_file_thumb')
+					.removeClass('plupload_thumb_toload')
+					.addClass('plupload_thumb_loading')
+				;
+			img.load(file.getSource());
+		}
+
+
+		function lazyLoad() {
+			if (self.view_mode !== 'thumbs' || loading) {
+				return;
+			}
+
+			pickThumbsToLoad();
+			if (!thumbs.length) {
+				return;
+			}
+
+			loading = true;
+
+			preloadThumb(self.getFile($(thumbs.shift()).closest('.plupload_file').attr('id')), function() {
+				loading = false;
+				lazyLoad();
+			});
+		}
+
+		// this has to run only once to measure structures and bind listeners
+		this.element.on('selected', function onselected() {
+			self.element.off('selected', onselected);
+			init();
+		});
+	},
+
+
+	_addFiles: function(files) {
+		var self = this, file_html, html = '';
+
+		file_html = '<li class="plupload_file ui-state-default plupload_delete" id="{id}" style="width:{thumb_width}px;">' +
+			'<div class="plupload_file_thumb plupload_thumb_toload" style="width: {thumb_width}px; height: {thumb_height}px;">' +
+				'<div class="plupload_file_dummy ui-widget-content" style="line-height: {thumb_height}px;"><span class="ui-state-disabled">{ext} </span></div>' +
+			'</div>' +
+			'<div class="plupload_file_status">' +
+				'<div class="plupload_file_progress ui-widget-header" style="width: 0%"> </div>' +
+				'<span class="plupload_file_percent">{percent} </span>' +
+			'</div>' +
+			'<div class="plupload_file_name" title="{name}">' +
+				'<span class="plupload_file_name_wrapper">{name} </span>' +
+			'</div>' +
+			'<div class="plupload_file_action">' +
+				'<div class="plupload_action_icon ui-icon ui-icon-circle-minus"> </div>' +
+			'</div>' +
+			'<div class="plupload_file_size">{size} </div>' +
+			'<div class="plupload_file_fields"> </div>' +
+		'</li>';
+
+		if (plupload.typeOf(files) !== 'array') {
+			files = [files];
+		}
+
+		$.each(files, function(i, file) {
+			var ext = o.core.utils.Mime.getFileExtension(file.name) || 'none';
+
+			html += file_html.replace(/\{(\w+)\}/g, function($0, $1) {
+				switch ($1) {
+					case 'thumb_width':
+					case 'thumb_height':
+						return self.options[$1];
+
+					case 'size':
+						return plupload.formatSize(file.size);
+
+					case 'ext':
+						return ext;
+
+					default:
+						return file[$1] || '';
+				}
+			});
+		});
+
+		self.filelist.append(html);
+	},
+
+
+	_addFormFields: function() {
+		var self = this;
+
+		// re-add from fresh
+		$('.plupload_file_fields', this.filelist).html('');
+
+		plupload.each(this.uploader.files, function(file, count) {
+			var fields = ''
+			, id = self.id + '_' + count
+			;
+
+			if (file.target_name) {
+				fields += '<input type="hidden" name="' + id + '_tmpname" value="'+plupload.xmlEncode(file.target_name)+'" />';
+			}
+			fields += '<input type="hidden" name="' + id + '_name" value="'+plupload.xmlEncode(file.name)+'" />';
+			fields += '<input type="hidden" name="' + id + '_status" value="' + (file.status === plupload.DONE ? 'done' : 'failed') + '" />';
+
+			$('#' + file.id).find('.plupload_file_fields').html(fields);
+		});
+
+		this.counter.val(this.uploader.files.length);
+	},
+
+
+	_viewChanged: function(view) {
+		// update or write a new cookie
+		if (this.options.views.remember && $.cookie) {
+			$.cookie('plupload_ui_view', view, { expires: 7, path: '/' });
+		}
+
+		// ugly fix for IE6 - make content area stretchable
+		if (plupload.ua.browser === 'IE' && plupload.ua.version < 7) {
+			this.content.attr('style', 'height:expression(document.getElementById("' + this.id + '_container' + '").clientHeight - ' + (view === 'list' ? 132 : 102) + ')');
+		}
+
+		this.container.removeClass('plupload_view_list plupload_view_thumbs').addClass('plupload_view_' + view);
+		this.view_mode = view;
+		this._trigger('viewchanged', null, { view: view });
+	},
+
+
+	_enableViewSwitcher: function() {
+		var self = this
+		, view
+		, switcher = $('.plupload_view_switch', this.container)
+		, buttons
+		, button
+		;
+
+		plupload.each(['list', 'thumbs'], function(view) {
+			if (!self.options.views[view]) {
+				switcher.find('[for="' + self.id + '_view_' + view + '"], #'+ self.id +'_view_' + view).remove();
+			}
+		});
+
+		// check if any visible left
+		buttons = switcher.find('.plupload_button');
+
+		if (buttons.length === 1) {
+			switcher.hide();
+			view = buttons.eq(0).data('view');
+			this._viewChanged(view);
+		} else if ($.ui.button && buttons.length > 1) {
+			if (this.options.views.remember && $.cookie) {
+				view = $.cookie('plupload_ui_view');
+			}
+
+			// if wierd case, bail out to default
+			if (!~plupload.inArray(view, ['list', 'thumbs'])) {
+				view = this.options.views.active;
+			}
+
+			switcher
+				.show()
+				.buttonset()
+				.find('.ui-button')
+					.click(function(e) {
+						view = $(this).data('view');
+						self._viewChanged(view);
+						e.preventDefault(); // avoid auto scrolling to widget in IE and FF (see #850)
+					});
+
+			// if view not active - happens when switcher wasn't clicked manually
+			button = switcher.find('[for="' + self.id + '_view_'+view+'"]');
+			if (button.length) {
+				button.trigger('click');
+			}
+		} else {
+			switcher.show();
+			this._viewChanged(this.options.views.active);
+		}
+
+		// initialize thumb viewer if requested
+		if (this.options.views.thumbs) {
+			this._displayThumbs();
+		}
+	},
+
+
+	_enableRenaming: function() {
+		var self = this;
+
+		this.filelist.dblclick(function(e) {
+			var nameInput, fileContainer, file, parts, name, ext = "";
+			var nameSpan = $(e.target);
+
+			if (!nameSpan.hasClass('plupload_file_name_wrapper')) {
+				return;
+			}
+
+			fileContainer = nameSpan.closest('.plupload_file');
+			if (!fileContainer.hasClass('plupload_delete')) {
+				return;
+			}
+
+			// Get file name and split out name and extension
+			file = self.uploader.getFile(fileContainer[0].id);
+			name = file.name;
+			parts = /^(.+)(\.[^.]+)$/.exec(name);
+			if (parts) {
+				name = parts[1];
+				ext = parts[2];
+			}
+
+			// Display input element
+			nameInput = $('<input class="plupload_file_rename" type="text" />').width(nameSpan.width()).insertAfter(nameSpan.hide());
+			nameInput.val(name).blur(function() {
+				nameSpan.show().parent().scrollLeft(0).end().next().remove();
+			}).keydown(function(e) {
+				var nameInput = $(this);
+
+				if ($.inArray(e.keyCode, [13, 27]) !== -1) {
+					e.preventDefault();
+
+					// Rename file and glue extension back on
+					if (e.keyCode === 13) {
+						file.name = nameInput.val() + ext;
+						nameSpan.html(file.name);
+					}
+					nameInput.blur();
+				}
+			})[0].focus();
+		});
+	},
+
+
+	_enableSortingList: function() {
+		var self = this;
+
+		if ($('.plupload_file', this.filelist).length < 2) {
+			return;
+		}
+
+		// destroy sortable if enabled
+		$('tbody', this.filelist).sortable('destroy');
+
+		// enable
+		this.filelist.sortable({
+			items: '.plupload_delete',
+
+			cancel: 'object, .plupload_clearer',
+
+			stop: function() {
+				var files = [];
+
+				$.each($(this).sortable('toArray'), function(i, id) {
+					files[files.length] = self.uploader.getFile(id);
+				});
+
+				files.unshift(files.length);
+				files.unshift(0);
+
+				// re-populate files array
+				Array.prototype.splice.apply(self.uploader.files, files);
+			}
+		});
+	}
+});
+
+} (window, document, plupload, moxie, jQuery));

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
app/assets/js/plupload-2.3.7/js/jquery.ui.plupload/jquery.ui.plupload.min.js


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio