diff --git a/docs/nginx.conf b/docs/nginx.conf new file mode 100644 index 0000000..8b8a89a --- /dev/null +++ b/docs/nginx.conf @@ -0,0 +1,51 @@ +server { + listen localhost; + server_name daapr.localhost; + + root /home/www-data/daapr; + index index.html; + + location ~ ^/favicon.ico$ { + root /home/www-data/roundcube/web/skins/default/images; + log_not_found off; + access_log off; + expires max; + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). + location ~ /(\.|temp|logs) { + deny all; + access_log off; + log_not_found off; + } +} + +server { + listen 80; + server_name daap.localhost; + + add_header Access-Control-Allow-Origin "*"; + + location / { + proxy_pass http://localhost:3689; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; + proxy_redirect off; + #proxy_buffering off; + proxy_buffering on; + #proxy_buffers 128k; + proxy_cache daap; + proxy_cache_valid 6d; + proxy_cache_valid 404 1m; + proxy_ignore_headers Cache-Control Expires DAAP-Server; + + #proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} diff --git a/index.html b/index.html index bb8e156..340cc4a 100644 --- a/index.html +++ b/index.html @@ -1,12 +1,293 @@ - - Backbone.js/Underscore.js via Require.js Learning Page - - - - -
Backbone.js/Underscore.js via Require.js Learning Page
-
- - \ No newline at end of file + + DAAPr + + + + + + + + + + +
+
+ + + +
+ + + +
+
+
+ +
+

DAAPr3

+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + +
+
+ 0 items +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/resources/css/app.css b/resources/css/app.css new file mode 100644 index 0000000..5815388 --- /dev/null +++ b/resources/css/app.css @@ -0,0 +1,426 @@ +body { + background: #909090 url('../img/body_background.png') repeat; + margin: 0; + padding: 0; + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 11px; +} + +.loading { + background-image: url(data:image/gif;base64,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); + background-attachment: fixed; + background-color: #909090; + background-position: center center; + background-repeat: no-repeat; +} +/* +body.loading > * { + display: none; +} + */ +/** + * JLayout + */ +.ui-layout-pane { /* all 'panes' */ + background: transparent; + border: none; + padding: 0; + margin: 0; + overflow: hidden; +} + +.ui-layout-resizer { + background: url('../img/viewport_background.png') repeat-x !important; + cursor: row-resize !important;; +} + +.ui-layout-toggler { + background-color: #BBB; +} + +.ui-layout-toggler:hover { + background-color: #4966B1;/* Old browsers */ + background: -moz-linear-gradient(top, #6086e5 0%, #6086e5 39%, #4966b1 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6086e5), color-stop(39%,#6086e5), color-stop(100%,#4966b1)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* IE10+ */ + background: linear-gradient(to bottom, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6086e5', endColorstr='#4966b1',GradientType=0 ); /* IE6-9 */ +} + +/** + * Elements + */ +div#wrapperPlayer { + margin: 0; + padding: 0; + /*height: 75px;*/ + /*position: fixed; + top: 0; + left: 0; + bottom: 75px; + right: 0;*/ +} + + form#wrapperSearchWidget { + display: inline-block; + float: right; + clear: right; + padding: 0; + margin: 10px 10px 0 0; + z-index: 100; + } + + form#wrapperSearchWidget button { + height: 20px; + width: 25px; + line-height: 0px; + padding: 0; + } + + form#wrapperSearchWidget button [class*=" icon-"] { + margin-top: 0; + } + + form#wrapperSearchWidget input { + height: 18px; + padding: 0; + padding-left: 3px; + font-size: 12px; + line-height: 21px; + } + +body > .ui-layout-west #wrapperSideBar { + margin: 0; + padding: 0; + min-width: 100px; + max-width: 175px; + background: #fff; + overflow-y: scroll; + overflow-x: hidden; + height: 100%; +} + +body > .ui-layout-west > #wrapperSideBar ul, +body > .ui-layout-west > #wrapperSideBar ul li { + margin: 0; + padding: 0; + list-style: none; + list-style-type: none; +} + + body > .ui-layout-west > #wrapperSideBar ul li { + vertical-align: bottom; + margin-bottom: 5px; + } + + body > .ui-layout-west > #wrapperSideBar ul li > span { + display: block; + line-height: 16px; + height: 16px; + vertical-align: bottom; + padding-bottom: 2px; + padding-left: 5px; + } + + body > .ui-layout-west > #wrapperSideBar ul li > span > span { + overflow: hidden; + text-overflow: ellipsis; + height: 16px; + line-height: 16px; + max-height: 16px; + display: inline-block; + max-width: 70%; + vertical-align: middle; + } + + body > .ui-layout-west > #wrapperSideBar ul li > span:hover { + color: #FFF; + background-color: #4966B1;/* Old browsers */ + background: -moz-linear-gradient(top, #6086e5 0%, #6086e5 39%, #4966b1 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6086e5), color-stop(39%,#6086e5), color-stop(100%,#4966b1)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* IE10+ */ + background: linear-gradient(to bottom, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6086e5', endColorstr='#4966b1',GradientType=0 ); /* IE6-9 */ + } + + body > .ui-layout-west > #wrapperSideBar ul li ul { + margin-left: 10px; + } + + body > .ui-layout-west > #wrapperSideBar ul li .sidebar-list-action { + display: none; + height: 14px; + } + + body > .ui-layout-west > #wrapperSideBar ul li > span:hover > .sidebar-list-action { + display: inline-block; + } + +div#wrapperBrowser { + margin: 0; + padding: 0; + background: #FFF url(../img/grid3-hrow2.gif) repeat-x; +} + div#wrapperBrowser > div.third { + width: 33.3333%; + float: left; + clear: none; + } + + div#wrapperBrowser > div.third:first-child { + clear: left; + } + + div#wrapperBrowser > div.third:last-child { + clear: right; + } + + div#wrapperBrowser > div.third > div.dataTables_wrapper, + div#wrapperBrowser > div.third > div.dataTables_wrapper { + border-left: 1px solid #C6C6C6; + } + + div#wrapperBrowser > div:first-child > div.dataTables_wrapper, + div#wrapperBrowser > div:first-child > div.dataTables_wrapper { + border-left: none; + padding-left: 1px; + } + + div#wrapperBrowser > div.third > div.dataTables_wrapper table td { + padding-left: 4px; + } + + div#wrapperBrowser table.dataTable tr td.sorting_1 { background-color: transparent; } + div#wrapperBrowser table.dataTable tr td.sorting_2 { background-color: transparent; } + div#wrapperBrowser table.dataTable tr td.sorting_3 { background-color: transparent; } + + +div#wrapperList { + margin: 0; + padding: 0; + width: 100%; + background: #FFF url(../img/grid3-hrow2.gif) repeat-x; +} + + div#wrapperList table#tableList { + margin: 0; + padding: 0; + width: 100%; + } + + div#listItemDetails table tr td:first-child { + width: 110px; + font-weight: bold; + padding-left: 10px; + } + + div#listItemDetails table tr:first-child td { + border-top: none; + } + + div#listItemDetails div.modal-body { + padding: 0; + } + +/* +div#wrapperList table#tableList tr td { + text-overflow: ellipsis; + max-width: 20%; + overflow: hidden; + white-space: nowrap; +} +*/ +div#wrapperFooter { + margin: 0; + padding: 0; + background: url('../img/viewport_background.png') repeat-x left bottom; + text-align: center; + height: 30px; + line-height: 25px; +} + div#wrapperFooter .btn-inverse { + line-height: 12px; + } + + div#wrapperFooter > div#wrapperFooterRight { + text-align: right; + padding-right: 10px; + padding-top: 3px; + } + + div#wrapperFooter > div#wrapperFooterRight div.btn-group { + height: 25px; + } + + div#wrapperFooter > div#wrapperFooterLeft { + text-align: left; + padding-left: 10px; + padding-top: 2px; + } + + +table.dataTable tbody tr { + display: table-row; + height: 17px; + margin: 0; + padding: 0; + background-color: #FFF; + border: none; +} + +table.dataTable tbody td { + display: table-cell; + margin: 0; + padding: 0 2px; + height: 16px; + background-color: #FFF; + border-bottom: 1px solid #EDEDED; +} + +table.dataTable div.dataTables_scrollHeadInner { + cursor: default; + display: block; + height: 22px; + border: none; +} + +table.dataTable tr td, +table.dataTable tr th { + overflow: hidden !important; + text-overflow: ellipsis !important; + -o-text-overflow: ellipsis !important; + -webkit-text-overflow: ellipsis !important; +} + +table.dataTable tbody tr { + height: 20px !important; + max-height: 20px !important; + overflow: hidden !important; + text-overflow: ellipsis !important; + -o-text-overflow: ellipsis !important; + -webkit-text-overflow: ellipsis !important; + white-space: nowrap !important; +} + +div.dataTables_scrollHeadInner th { + -webkit-background-clip: border-box; + -webkit-background-origin: padding-box; + -webkit-background-size: auto; + font-size: 11px; + font-style: normal; + font-variant: normal; + font-weight: bold; + height: 22px; + line-height: 22px; + overflow-x: hidden; + overflow-y: hidden; + text-align: left; + text-overflow: clip; + white-space: nowrap; + color: #000; + border: none; +} + + div#wrapperBrowser div.dataTables_scrollHeadInner th { + padding-left: 4px; + } + +div.dataTables_scrollBody table tbody tr:last-child td { + border: none; +} + +div.dataTables_scrollHead table thead th.center, +div.dataTables_scrollBody table tbody td.center { + text-align: center; +} + +table.dataTable tbody tr.selected td, +table.dataTable tbody tr.selected td.sorting_1, +table.dataTable tbody tr.selected td.sorting_2, +table.dataTable tbody tr.selected td.sorting_3, +div#wrapperBrowser > div.third > div.dataTables_wrapper table tr.selected td, +div#wrapperBrowser > div.third > div.dataTables_wrapper table tr.selected td.sorting_1, +div#wrapperBrowser > div.third > div.dataTables_wrapper table tr.selected td.sorting_2, +div#wrapperBrowser > div.third > div.dataTables_wrapper table tr.selected td.sorting_3, +.dropdown-menu * a:hover, +.dropdown-menu * a:focus, +.dropdown-menu * li:hover, +.dropdown-menu * li:hover a, +.dropdown-menu * li:hover a:hover, +.dropdown-menu > ul > li:hover, +.dropdown-menu li:hover, +.dropdown-menu .active > a:hover { + color: #FFF; + background-color: #4966B1;/* Old browsers */ + background: -moz-linear-gradient(top, #6086e5 0%, #6086e5 39%, #4966b1 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6086e5), color-stop(39%,#6086e5), color-stop(100%,#4966b1)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* IE10+ */ + background: linear-gradient(to bottom, #6086e5 0%,#6086e5 39%,#4966b1 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6086e5', endColorstr='#4966b1',GradientType=0 ); /* IE6-9 */ +} + +div#wrapperPlayer { + background: url('../img/viewport_background.png') repeat-x; + height: 50px; +} + +div#wrapperFooter, +table.dataTable tr td, +table.dataTable tr th { + -webkit-user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + cursor: default; +} + +.clearfix { + float: none; + clear: both; + font-style: oblique; +} + +div.overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #000; + opacity: 0.7; + z-index: 1000; + width: 100%; +} + +div.overlay > div { + z-index: 1001; +} + + +div#screen, +div#screen canvas#processcanvas { + width : 512px; + height : 512px; + top: 0; + margin: 0 auto; + position : absolute; + z-index : 2000; +} + +.icon-loading { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-repeat: no-repeat; + background-position: 0 0; + background-image: url(data:image/gif;base64,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); +} \ No newline at end of file diff --git a/resources/css/datatables.css b/resources/css/datatables.css new file mode 100644 index 0000000..a40843a --- /dev/null +++ b/resources/css/datatables.css @@ -0,0 +1,46 @@ +/** + * DataTables + */ +table.dataTable { + margin: 0 auto; + clear: both; + width: 100%; +} + +table.dataTable thead th, +table.dataTable tbody td { + height: ; + padding: 0px 2px; +} + +table.dataTable thead th { + cursor: pointer; + *cursor: hand; +} + +table.dataTable td.center, +table.dataTable td.dataTables_empty { + text-align: center; +} + + +table.dataTable tr td.sorting_1 { background-color: #EBEBEB; } +table.dataTable tr td.sorting_2 { background-color: #EBEBEB; } +table.dataTable tr td.sorting_3 { background-color: #EBEBEB; } +/* +table.dataTable tr.odd { background-color: #E2E4FF; } +table.dataTable tr.even { background-color: white; } + +table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } +table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } +table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } +table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } +table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } +table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } +*/ +/*.sorting { background: url('../vendors/DataTables-1.9.4/media/images/sort_both.png') no-repeat center right; }*/ +.sorting_asc { background: url('../vendors/DataTables-1.9.4/media/images/sort_asc.png') no-repeat center right; } +.sorting_desc { background: url('../vendors/DataTables-1.9.4/media/images/sort_desc.png') no-repeat center right; } + +.sorting_asc_disabled { background: url('../vendors/DataTables-1.9.4/media/images/sort_asc_disabled.png') no-repeat center right; } +.sorting_desc_disabled { background: url('../vendors/DataTables-1.9.4/media/images/sort_desc_disabled.png') no-repeat center right; } diff --git a/resources/css/normalize.css b/resources/css/normalize.css new file mode 100644 index 0000000..73abb76 --- /dev/null +++ b/resources/css/normalize.css @@ -0,0 +1,375 @@ +/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/* + * Corrects `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/* + * Prevents modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/* + * Addresses styling for `hidden` attribute not present in IE 8/9. + */ + +[hidden] { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/* + * 1. Sets default font family to sans-serif. + * 2. Prevents iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -ms-text-size-adjust: 100%; /* 2 */ +} + +/* + * Removes default margin. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/* + * Addresses `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/* + * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, + * Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; +} + +/* + * Addresses styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/* + * Addresses styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + + +/* + * Corrects font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/* + * Improves readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +/* + * Sets consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/* + * Addresses inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/* + * Prevents `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/* + * Removes border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/* + * Corrects overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/* + * Addresses margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/* + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Corrects font family not being inherited in all browsers. + * 2. Corrects font size not being inherited in all browsers. + * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/* + * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/* + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Corrects inability to style clickable `input` types in iOS. + * 3. Improves usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/* + * Re-set default cursor for disabled elements. + */ + +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to `content-box` in IE 8/9. + * 2. Removes excess padding in IE 8/9. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/* + * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE 8/9. + * 2. Improves readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/* + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/resources/css/player.css b/resources/css/player.css new file mode 100644 index 0000000..3642e45 --- /dev/null +++ b/resources/css/player.css @@ -0,0 +1,247 @@ + +div#wrapperPlayer #daaprPlayerViewport { + margin: 6px auto 0 auto; + background: transparent url('../img/player_background.png') repeat-x; + height: 40px; + width: 450px; + border: 1px solid #6B6D5E; + border-bottom-color: #DCDDDE; + border-left-color: #939885; + border-right-color: #939885; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + z-index: 10; +} + +div#wrapperPlayer #daaprPlayerViewport h1 { + color: #5F5F5F; + font-size: 2em; + font-style: oblique; + font-variant: small-caps; + font-weight: bold; + line-height: 40px; + text-align: center; + text-shadow: #ACACAC 2px 2px 2px; + margin: 0; + -webkit-gradient( + linear, + left top, + left bottom, + color-stop(0.3, rgb(0,0,0)), + color-stop(0.27, rgb(46,46,46)), + color-stop(0.83, rgb(0,0,0)) + ); + -moz-linear-gradient( + center top, + rgb(0,0,0) 30%, + rgb(46,46,46) 27%, + rgb(0,0,0) 83% + ); +} + +.daaprPlayerTitleIndicator, +.daaprPlayerInfoIndicator { + height: 12px; + line-height: 12px; + font-size: 0.7em; + text-align: center; + margin-bottom: 2px; +} + +.daaprPlayerTitleIndicator { + font-size: 0.7em; + font-weight: bold; +} + +#daaprProgressTimeRemain, +#daaprProgressTimeElapsed { + font-size: 0.7em; +} + +#daaprProgressTimeRemain { + vertical-align: top; + height: 7px; + line-height: 7px; + padding-right: 5px; +} + +#daaprProgressTimeElapsed { + vertical-align: top; + height: 7px; + line-height: 7px; + padding-left: 5px; +} + +.daaprProgressWrap { + width: auto; + text-align: center; + margin: 0 auto; + height: 9px; +} + +.daaprControlsWrap { + float: left; + clear: left; + margin-top: 8px; + margin-left: 25px; +} + +.daaprControlsWrap #buttonPlay { + float: left; + clear: none; + display: block; + width: 37px; + height: 38px; + margin-left: 4px; + margin-right: 4px; + background: transparent url('../img/button_play.png') no-repeat left top; +} +.daaprControlsWrap #buttonPlay.playing { + background-image: url('../img/button_pause.png'); +} + +.daaprControlsWrap #buttonPlay.stopped { + background-image: url('../img/button_stop.png'); +} + +.daaprControlsWrap #buttonVolume, +.daaprControlsWrap #buttonPrev, +.daaprControlsWrap #buttonNext { + float: left; + clear: none; + display: block; + width: 31px; + height: 32px; + margin-top: 3px; +} + +.daaprControlsWrap #buttonPrev { + background: url('../img/button_prev.png') no-repeat left top; +} + +.daaprControlsWrap #buttonNext { + background: url('../img/button_next.png') no-repeat left top; +} + +.daaprControlsWrap #buttonNext:active, +.daaprControlsWrap #buttonPrev:active, +.daaprControlsWrap #buttonPlay:active, +.daaprControlsWrap #buttonNext.disabled:active, +.daaprControlsWrap #buttonPrev.disabled:active, +.daaprControlsWrap #buttonPlay.disabled:active { + background-position: left bottom; +} + +progress, +progress::-webkit-progress-bar-value, +progress::-webkit-progress-value, +progress::-moz-progress-bar { + -webkit-appearance: progress-bar; + /*background-color: #BFBFBF;*/ +} + +progress#daaprPlayerProgress { + vertical-align: top; + /*-moz-border-radius: 7px; + -webkit-border-radius: 7px;*/ + display: inline-block; + /*height: 7px;*/ + margin-top: -3px; + padding: 0; + width: 350px; + /*border: 1px solid #393939;*/ +} +/* +progress#daaprPlayerProgress, progress#daaprPlayerProgress span { + -moz-border-radius: 7px; + -webkit-border-radius: 7px; +} +progress#daaprPlayerProgress span { + background: url('../img/progressbar_fg.png') repeat-x; + display: block; + height: 7px; + margin: 0; + padding: 0; +} +*/ +#volumeWrapper { + float: left; + clear: none; + margin-left: 25px; + margin-top: 16px; +} + +#volumeWrapper input#buttonVolume { + float: left; + clear: none; + vertical-align: bottom; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + /*background: url('../img/volume_bg.png') repeat-x;*/ + display: block; + height: 6px; + line-height: 6px; + padding: 0; + width: 74px; + border: 1px solid #393939; + border-top: none; + margin-left: 3px; + margin-right: 3px; + margin-top: 2px; +} + +#volumeWrapper input#buttonVolume, +#volumeWrapper input#buttonVolume span { + -moz-border-radius: 6px; + -webkit-border-radius: 6px; +} +/* +#volumeWrapper progress#buttonVolume span { + background: url('../img/volume_fg.png') repeat-x; + display: block; + height: 6px; + width: 0%; + margin: 0; + padding: 0; +} + +#volumeWrapper progress#buttonVolume span a { + display: none; +} +*/ + +#volumeWrapper a#buttonVolDown { + vertical-align: top; + display:block; + float: left; + clear: left; + height: 10px; + width: 9px; + background: transparent url('../img/volume_minus.png') no-repeat; +} + + +#volumeWrapper a#buttonVolUp { + vertical-align: top; + display:block; + float: left; + clear: right; + height: 10px; + width: 13px; + background: transparent url('../img/volume_plus.png') no-repeat; +} + +table tbody tr.itemplaying td:first-child span { + display: inline-block; + background-color: transparent; + background-image: url('../img/playicon2.png'); + background-repeat: no-repeat; + background-position: left bottom; + width: 12px; + height: 12px; + line-height: 14px; +} + +table tbody tr.itemplaying.itempaused td:first-child span { + background-image: url('../img/playicon.png'); +} diff --git a/resources/img/animation.gif b/resources/img/animation.gif new file mode 100644 index 0000000..b3310ec Binary files /dev/null and b/resources/img/animation.gif differ diff --git a/resources/img/body_background.png b/resources/img/body_background.png new file mode 100644 index 0000000..52a51c0 Binary files /dev/null and b/resources/img/body_background.png differ diff --git a/resources/img/button_next.png b/resources/img/button_next.png new file mode 100644 index 0000000..cef2ca9 Binary files /dev/null and b/resources/img/button_next.png differ diff --git a/resources/img/button_pause.png b/resources/img/button_pause.png new file mode 100644 index 0000000..bf7114f Binary files /dev/null and b/resources/img/button_pause.png differ diff --git a/resources/img/button_play.png b/resources/img/button_play.png new file mode 100644 index 0000000..cd997fa Binary files /dev/null and b/resources/img/button_play.png differ diff --git a/resources/img/button_prev.png b/resources/img/button_prev.png new file mode 100644 index 0000000..cdb2fa5 Binary files /dev/null and b/resources/img/button_prev.png differ diff --git a/resources/img/button_stop.png b/resources/img/button_stop.png new file mode 100644 index 0000000..f62f43a Binary files /dev/null and b/resources/img/button_stop.png differ diff --git a/resources/img/grid3-hrow2.gif b/resources/img/grid3-hrow2.gif new file mode 100644 index 0000000..423b507 Binary files /dev/null and b/resources/img/grid3-hrow2.gif differ diff --git a/resources/img/loading.png b/resources/img/loading.png new file mode 100644 index 0000000..5f4d84d Binary files /dev/null and b/resources/img/loading.png differ diff --git a/resources/img/player_background.png b/resources/img/player_background.png new file mode 100644 index 0000000..0985283 Binary files /dev/null and b/resources/img/player_background.png differ diff --git a/resources/img/playicon.png b/resources/img/playicon.png new file mode 100644 index 0000000..0786ec9 Binary files /dev/null and b/resources/img/playicon.png differ diff --git a/resources/img/playicon2.png b/resources/img/playicon2.png new file mode 100644 index 0000000..71c841f Binary files /dev/null and b/resources/img/playicon2.png differ diff --git a/resources/img/progessbar_fg.png b/resources/img/progessbar_fg.png new file mode 100644 index 0000000..420392c Binary files /dev/null and b/resources/img/progessbar_fg.png differ diff --git a/resources/img/progressbar_bg.png b/resources/img/progressbar_bg.png new file mode 100644 index 0000000..f4a6c3a Binary files /dev/null and b/resources/img/progressbar_bg.png differ diff --git a/resources/img/progressbar_fg.png b/resources/img/progressbar_fg.png new file mode 100644 index 0000000..8fb98bc Binary files /dev/null and b/resources/img/progressbar_fg.png differ diff --git a/resources/img/progressbar_indicator.png b/resources/img/progressbar_indicator.png new file mode 100644 index 0000000..7337b62 Binary files /dev/null and b/resources/img/progressbar_indicator.png differ diff --git a/resources/img/viewport_background.png b/resources/img/viewport_background.png new file mode 100644 index 0000000..391960b Binary files /dev/null and b/resources/img/viewport_background.png differ diff --git a/resources/img/volume_bg.png b/resources/img/volume_bg.png new file mode 100644 index 0000000..192b5b4 Binary files /dev/null and b/resources/img/volume_bg.png differ diff --git a/resources/img/volume_fg.png b/resources/img/volume_fg.png new file mode 100644 index 0000000..9fbf313 Binary files /dev/null and b/resources/img/volume_fg.png differ diff --git a/resources/img/volume_knob.png b/resources/img/volume_knob.png new file mode 100644 index 0000000..055541e Binary files /dev/null and b/resources/img/volume_knob.png differ diff --git a/resources/img/volume_minus.png b/resources/img/volume_minus.png new file mode 100644 index 0000000..d98f4f6 Binary files /dev/null and b/resources/img/volume_minus.png differ diff --git a/resources/img/volume_plus.png b/resources/img/volume_plus.png new file mode 100644 index 0000000..29717e8 Binary files /dev/null and b/resources/img/volume_plus.png differ diff --git a/resources/js/app.js b/resources/js/app.js index 2a63ef8..aa4a654 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -7,17 +7,37 @@ // Filename: app.js define([ - "jquery" - , "underscore" - , "backbone" + "views/app" + , "views/footer" + , "views/sidebar" + , "views/player" + , "views/main" + , "models/client" + , "models/dmap" ], -function( $, _, Backbone, ClientModel ) { - "use strict"; +function( +AppView +, FooterView +, SideBarView +, PlayerView +, MainView + +, ClientModel +, DMAPModel +) { +"use strict"; - var init = function(){ + var init = function() { + console.log("app.js::init()"); - console.log( "app.js > init()" ); + this.Views = {}; + + this.Views.Footer = new FooterView(); + this.Views.SideBar = new SideBarView(); + this.Views.Player = new PlayerView(); + this.Views.Main = new MainView(); + this.Views.App = new AppView(); var client = new ClientModel({ hostname: "daap.localhost" @@ -25,19 +45,21 @@ function( $, _, Backbone, ClientModel ) { , port: 80 , password: "lawl" }); - console.log(client.attributes); client.on("unauthorized", function __client_unauthorized() { console.log(arguments); }); - client.on("inited", function () { + client.on("inited", function (collections) { console.log(client.url(), arguments); + + var item = collections.databases[collections.databasesInfo.get("dmap_listing").at(0).id].get("dmap_listing").get(107); + console.log(item, item.toJSON(), collections.databases[collections.databasesInfo.get("dmap_listing").at(0).id].get("dmap_listing").toJSON()); }); - console.log(client); + //client.init(); - client.init(); + return this; }; return { init: init }; diff --git a/resources/js/collections/dmap.js b/resources/js/collections/dmap.js index 2f145dd..2f2083c 100644 --- a/resources/js/collections/dmap.js +++ b/resources/js/collections/dmap.js @@ -1,26 +1,51 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ define([ - "backbone" + "underscore" + , "backbone" , "models/dmap" ] -, function (Backbone, DMAPModel) { +, function (_, Backbone, DMAPModel) { + "use strict"; + var that , Collection = Backbone.Collection.extend({ - model: DMAPModel - - , attributes: {} + attributes: {} + , model: DMAPModel , initialize: function (attributes, options) { - that = this; - - options.fetch && that.fetch = options.fetch && delete options.fetch; + that = this + ; + + if (!_.isObject(options)) { + options = {}; + } - _.extend({}, that.attributes, attributes); + if (_.isFunction(options.fetch)) { + that.fetch = options.fetch; + delete options.fetch; + } + + if (!_.isUndefined(options.model)) { + that.model = options.model; + delete options.model; + } + + Collection.__super__.initialize.call(that, [attributes, options]); - Model.__super__.set(that, [undefined, options]); - return that; } +/* + , toJSON: function(options) { + return this.map(function(model){ return model.toJSON(options); }); + } +*/ + , parse: function () {console.error("PARSE", arguments);} , fetch: function (options) { that.trigger("dmap.collection.fetch", this, arguments); diff --git a/resources/js/collections/server.js b/resources/js/collections/server.js new file mode 100644 index 0000000..9d11c00 --- /dev/null +++ b/resources/js/collections/server.js @@ -0,0 +1,22 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ +define([ + "underscore" + , "backbone" + , "backbone-localstorage" +] +, function (_, Backbone) { + "use strict"; + + return Backbone.Collection.extend({ + localStorage: new Backbone.LocalStorage("daap-servers") + + , initialize: function () { + return this.__super__.initialize.call(this, arguments); + } + }); +}); \ No newline at end of file diff --git a/resources/js/main.js b/resources/js/main.js index 2ed38db..f62db60 100644 --- a/resources/js/main.js +++ b/resources/js/main.js @@ -12,7 +12,7 @@ require.config({ , "bootstrap-contextmenu": ["bootstrap"] , "jquery": { - exports: "jQuery.fn" + exports: "$" } , "backbone": { @@ -26,6 +26,10 @@ require.config({ , exports: "Backbone" } + , "backbone-localstorage": { + deps: ["backbone"] + } + , "underscore": { exports: "_" } @@ -47,12 +51,13 @@ require.config({ , "jquery-layout": "../vendors/jquery/layout/1.2.0/jquery.layout.min" , "datatables": "../vendors/jquery/datatables/1.9.4/media/js/jquery.dataTables.min" - , "bootstrap": "../vendors/backbone/2.1.1/js/bootstrap.min" - , "bootstrap-contextmenu": "../vendors/backbone/contextmenu/59986df48f/js/bootstrap-contextmenu" + , "bootstrap": "../vendors/bootstrap/2.1.1/js/bootstrap.min" + , "bootstrap-contextmenu": "../vendors/bootstrap/contextmenu/59986df48f/js/bootstrap-contextmenu" , "underscore": "../vendors/lodash/0.9.0/lodash.underscore.min" , "backbone": "../vendors/backbone/0.9.2/backbone-min" + , "backbone-localstorage": "../vendors/backbone/localstorage/8651291560/backbone.localStorage-min" , "toolbox": "../vendors/backbone/toolbox/e0cac9f/toolbox" , "toolbox-extras": "../vendors/backbone/toolbox/e0cac9f/toolbox.extra" } @@ -70,6 +75,9 @@ require( , function ( App, $ ) { "use strict"; + // JQuery Backwords compatibility fix + $.curCSS = $.css; + $("body").ready(function(){ App.init(); }); diff --git a/resources/js/models/client.js b/resources/js/models/client.js index 6768a5f..c818c8b 100644 --- a/resources/js/models/client.js +++ b/resources/js/models/client.js @@ -30,26 +30,20 @@ define([ xhr.open("GET", url, true); xhr.responseType = responseType; + xhr.timeout = 2000; xhr.setRequestHeader("Content-type", contentType); + xhr.overrideMimeType("text/plain; charset=x-user-defined"); // Technically not need with v2 and responseType but for good measures - // TODO: Add this: - // xhr.timeout = 4000; - // xhr.ontimeout = function () { alert("Timed out!!!"); } - - console.log(that.attributes.password, that.attributes.username, window.btoa((that.attributes.username || "") + ":" + (that.attributes.password || ""))); - - if (!_.isEmpty(that.attributes.password) || !_.isEmpty(that.attributes.username)) { - var basicAuth = window.btoa((that.attributes.username || "") + ":" + (that.attributes.password || "")); - + if (!_.isEmpty(that.attributes.basicauth)) { xhr.withCredentials = true; - xhr.setRequestHeader("Authorization", "Basic " + basicAuth); + xhr.setRequestHeader("Authorization", "Basic " + that.attributes.basicauth); } - //xhr.overrideMimeType('text/plain; charset=x-user-defined'); try { - xhr.onerror = function() {console.log(arguments, this);}; - xhr.onabort = function() {console.log(arguments, this);}; - xhr.onload = function(e) { + xhr.onerror = function () {console.log("Error", arguments, this);}; + xhr.onabort = function () {console.log("Abort", arguments, this);}; + xhr.ontimeout = function () {console.log("Timeout", arguments, this);}; + xhr.onload = function (e) { if (this.status === 200) { callback(null, this.response); } else if (this.status === 401) { @@ -66,53 +60,172 @@ define([ } } - , fetchContentTypes = function (success, error) { - xhr(that.url("/content-codes?"), function (err, content) { + , fetchXHR = function (path, success, error) { + xhr(that.url(path), function __fetchXHRCallback(err, content) { if (err) { - error || (error = function (err) {throw [err, content]}()); + if (!_.isFunction(error)) { + error = function (err, cont) { + throw [err, cont]; + }; + } error(err, content); - } else { - that.collections.contentCodes = new DMAPModel([], { - buffer: content - }); - success && success(content); + success(content); } }); } + , fetchContentTypes = function (success, error) { + fetchXHR("/content-codes", function __fetchContentTypesCallback(content) { + that.collections.contentCodes = new DMAPModel(content); + if (_.isFunction(success)) { + success(content); + } + }, error); + } + , fetchServerInfo = function (success, error) { - xhr(that.url("/server-info?"), function (err, content) { - if (err) { - error || error = function (err) {throw [err, content]}(); + fetchXHR("/server-info", function __fetchServerInfoCallback(content) { + that.collections.serverInfo = new DMAPModel(content, { + contentCodes: that.collections.contentCodes + }); - error(err, content); + if (_.isFunction(success)) { + success(content); + } + }, error); + } - } else { - that.collections.serverInfo = new DMAPModel([], { - buffer: content - , contentCodes: that.collections.contentCodes - }); - success && success(content); + , fetchLogin = function (success, error) { + fetchXHR("/login", success, error); + } + + , fetchDatabases = function (success, error) { + fetchXHR("/databases", function __fetchDatabasesCallback(content) { + that.collections.databasesInfo = new DMAPModel(content, { + contentCodes: that.collections.contentCodes + }); + + if (_.isFunction(success)) { + success(content); } - }); + }, error); } - , fetchLogin = function () { + , fetchDatabase = function (success, error, dbId) { + if (_.isUndefined(dbId) || !_.isNumeric(dbId)) { + dbId = 1; + } + + fetchXHR("/databases/" + dbId + "/items", function __fetchDatabaseCallback(content) { + that.collections.databases[dbId] = new DMAPModel(content, { + contentCodes: that.collections.contentCodes + }); + + if (_.isFunction(success)) { + success(content); + } + }, error); + } + + , fetchPlaylists = function (success, error, dbId) { + if (_.isUndefined(dbId) || !_.isNumeric(dbId)) { + dbId = 1; + } + + fetchXHR("/databases/" + dbId + "/containers", function __fetchPlaylistsCallback(content) { + that.collections.playlistsInfo = new DMAPModel(content, { + contentCodes: that.collections.contentCodes + }); + + if (_.isFunction(success)) { + success(content); + } + }, error); + } + + , fetchPlaylist = function (success, error, playlistId, dbId) { + if (_.isUndefined(playlistId) || !_.isNumeric(playlistId)) { + playlistId = 1; + } + + if (_.isUndefined(dbId) || !_.isNumeric(dbId)) { + dbId = 1; + } + + var requestUri = "/databases/" + ; + + requestUri += dbId; + requestUri += "/containers/"; + requestUri += playlistId; + requestUri += "/items"; + requestUri += "?meta=dmap.itemid,dmap.persistentid,dmap.containeritemid"; + + fetchXHR(requestUri, function __fetchPlaylistCallback(content) { + if (!_.isArray(that.collections.playlists[dbId])) { + that.collections.playlists[dbId] = []; + } + + that.collections.playlists[dbId][playlistId] = new DMAPModel(content, { + contentCodes: that.collections.contentCodes + }); + + if (_.isFunction(success)) { + success(content); + } + }, error); + } + + , fetchBrowse = function (success, error, dbId, type) { + // TODO: We need to detect if the server supports browsing or not an implement our own otherwise. + if (_.isEmpty(type) || !_.isString(type) || !_.isArray(that.collections.browser[type])) { + throw new Error("INVALID_BROWSE_TYPE"); + } + + var requestUri = "/databases/" + ; + + requestUri += dbId; + requestUri += "/browse/"; + requestUri += type; + requestUri += "?meta=dmap.itemid,dmap.persistentid,dmap.containeritemid"; + + fetchXHR(requestUri, function __fetchBrowseCallback(content) { + that.collections.browser[type][dbId] = new DMAPModel(content, { + contentCodes: that.collections.contentCodes + }); + + if (_.isFunction(success)) { + success(content); + } + }, error); } - , fetchDatabases = function () { + , fetchGenres = function (success, error, dbId) { + if (_.isUndefined(dbId) || !_.isNumeric(dbId)) { + dbId = 1; + } + return fetchBrowse(success, error, dbId, "genres"); } - , fetchDatabase = function () { + , fetchArtists = function (success, error, dbId) { + if (_.isUndefined(dbId) || !_.isNumeric(dbId)) { + dbId = 1; + } + return fetchBrowse(success, error, dbId, "artists"); } - , fetchPlaylists = function () { + , fetchAlbums = function (success, error, dbId) { + if (_.isUndefined(dbId) || !_.isNumeric(dbId)) { + dbId = 1; + } + return fetchBrowse(success, error, dbId, "albums"); } , Client = Toolbox.Base.extend({ @@ -123,13 +236,60 @@ define([ _.extend(that, Client.defaults); _.extend(that.attributes, attributes); + that.setAuth(); + return this; } + , setAuth: function(username, password) { + if (!_.isUndefined(username)) { + that.attributes.username = username; + } + + if (!_.isUndefined(password)) { + that.attributes.password = password; + } + + if (!_.isEmpty(that.attributes.password) || !_.isEmpty(that.attributes.username)) { + that.attributes.basicauth = window.btoa((that.attributes.username || "") + ":" + (that.attributes.password || "")); + } + + } + , init: function () { + var that = this + ; + + that.console.debug("Fetching content types"); fetchContentTypes(function () { + that.console.debug("Fetching server info"); fetchServerInfo(function () { - that.trigger("inited", that.collections); + that.console.debug("Fetching login"); + fetchLogin(function () { + // TODO: Here we need to request /update for the database version + that.console.debug("Fetching databases info"); + fetchDatabases(function () { + //that.console.debug("Fetching database 1"); + //fetchDatabase(function () { + that.console.debug("Fetching playlists info"); + fetchPlaylists(function () { + //that.console.debug("Fetching playlist 1 of db 1"); + //fetchPlaylist(function () { + //that.console.debug("Fetching genres of db 1"); + //fetchGenres(function () { + //that.console.debug("Fetching artists of db 1"); + //fetchArtists(function () { + //that.console.debug("Fetching albums of db 1"); + //fetchAlbums(function () { + that.trigger("inited", that.collections); + //}); + //}); + //}); + //}); + }); + //}); + }); + }); }); }); @@ -138,6 +298,22 @@ define([ ,logout: function () { + } + + , buildRequestUid: function(path, fields, query) { + if (_.isEmpty(path) || !_.isString(path)) { + throw new Error("INVALID_TYPE_ERROR"); + } + + if (!_.isArray(fields)) { + fields = []; + } + + if (!_.isArray(query)) { + query = []; + } + + } ,url: function (request) { @@ -148,17 +324,58 @@ define([ uri = request; // Add leading slash here! } + if (_.isNumber(this.collections.session.id)) { + var prefix = "?"; + + if (uri.indexOf("?") >= 0) { + prefix = "&"; + } + + uri += prefix + "session-id=" + this.collections.session.id; + } + return this.attributes.protocol + "://" + this.attributes.hostname + ":" + this.attributes.port + uri; } + + , console: { + log: function() { + var args = arguments; + + if (_.isString(args[0])) { + args[0] = that.url() + " " + args[0]; + } + + console.log(args); + } + , debug: function() { + var args = arguments; + + if (_.isString(args[0])) { + args[0] = that.url() + " " + args[0]; + } + + console.debug(args); + } + } }, { defaults: { attributes: { protocol: window.location.protocol.replace(":", "") , hostname: window.location.hostname , port: 3689 - , path: "" - , username: "" - , password: "" + , path: "" + , username: "" + , password: "" + } + + , status: 0 + + , statusCodes: { + disconnected: 0 + , connecting: 1 + , timedout: 2 + , unauthorized: 3 + , connected: 4 } , collections: { @@ -172,20 +389,20 @@ define([ , databasesInfo:null - , databases: null + , databases: [] , playlistsInfo:null - , genres: null + , playlists: [] - , artists: null + , browser: { + genres: [] - , albums: null - } - } + , artists: [] - , lawl: function() { - console.info(arguments); + , albums: [] + } + } } }); diff --git a/resources/js/models/dmap-type.js b/resources/js/models/dmap-type.js index 407d33a..4edaaf1 100644 --- a/resources/js/models/dmap-type.js +++ b/resources/js/models/dmap-type.js @@ -11,157 +11,62 @@ define([ , function (_, Toolbox) { "use strict"; - var that - - , Types = Toolbox.Base.extend({ - constructor: function (code) { - this.code = code - , this.length = null - ; - - if (_.isNumber(code)) { - if (!_.isUndefined(Types.typeMap[code])) { - _.extend(this, Types.typeMap[code]); - } else { - - } - } - - return this; - } - - , code: null - , length: null - , unpack: null - - , getCode: function() { + var + Types = function(code) { + this.code = code; + this.length = null; + this.unpack = null; + this.typeMap = typeMap; + + this.getCode = function() { return this.code; - } + }; - , getByteLength: function() { + this.getByteLength = function() { return this.length; - } - - } - , { - - - typeMap: { - 1: { - length: 1 - , unpack: function (chunk) { - Types.getInt8(chunk); - } - } - - , 2: { - length: 1 - , unpack: function (chunk) { - Types.getUint8(chunk); - } - } - - , 3: { - length: 2 - , unpack: function (chunk) { - Types.getInt16(chunk); - } - } - - , 4: { - length: 2 - , unpack: function (chunk) { - Types.getUint16(chunk); - } - } - - , 5: { - length: 4 - , unpack: function (chunk) { - Types.getInt32(chunk); - } - } - - , 6: { - length: 4 - , unpack: function (chunk) { - Types.getUint32(chunk); - } - } - - , 7: { - length: 8 - , unpack: function (chunk) { - Types.getFloat64(chunk); - } - } - - // There is no unsigned 64bit integer in JS. - , 8: { - length: 8 - , unpack: function (chunk) { - Types.getFloat64(chunk); - } - } - - , 9: { - length: null - , unpack: function (chunk, length) { - Types.getUTFString(chunk, length); - } - } + }; - , 10: { - length: 4 - , unpack: function (chunk) { - Types.getDate(chunk); - } - } + if (_.isNumber(this.code)) { + if (!_.isUndefined(typeMap[this.code])) { + _.extend(this, typeMap[this.code]); + } else { - , 11: { - length: 2 - , unpack: function (chunk) { - Types.getVersion(chunk); - } - } - - , 12: { - length: null - , unpack: function (chunk, length) { - Types.getModel(chunk, length); - } } } - , getInt8: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[1].length)).getInt8(0, false); + return this; + } + + , TypesPrototype = { + getInt8: function (chunk) { + return new DataView(chunk.slice(0,typeMap[1].length)).getInt8(0, false); } - , getUint8: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[2].length)).getUint8(0, false); + , getUint8: function (chunk) { + return new DataView(chunk.slice(0,typeMap[2].length)).getUint8(0, false); } - , getInt16: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[3].length)).getInt16(0, false); + , getInt16: function (chunk) { + return new DataView(chunk.slice(0,typeMap[3].length)).getInt16(0, false); } - , getUint16: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[4].length)).getUint16(0, false); + , getUint16: function (chunk) { + return new DataView(chunk.slice(0,typeMap[4].length)).getUint16(0, false); } - , getInt32: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[5].length)).getInt32(0, false); + , getInt32: function (chunk) { + return new DataView(chunk.slice(0,typeMap[5].length)).getInt32(0, false); } - , getUint32: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[6].length)).getUint32(0, false); + , getUint32: function (chunk) { + return new DataView(chunk.slice(0,typeMap[6].length)).getUint32(0, false); } - , getFloat64: function (chunk) { - return new DataView(chunk.slice(0,Types.typeMap[7].length)).getFloat64(0, false); + , getFloat64: function (chunk) { + return new DataView(chunk.slice(0,typeMap[7].length)).getFloat64(0, false); } - , getString: function(chunk, length) { + , getString: function(chunk, length) { if (!_.isNumber(length) || length > chunk.byteLength) { length = chunk.byteLength; } @@ -170,7 +75,7 @@ define([ } // TODO: This might be optimizable - , getUTFString: function (chunk, length) { + , getUTFString: function (chunk, length) { var str = ''; if (!_.isNumber(length) || length > chunk.byteLength) { length = chunk.byteLength; @@ -189,36 +94,100 @@ define([ return decodeURIComponent(str); } - , getDate: function (chunk) { - return new Date(Types.getUint32(chunk)); + , getDate: function (chunk) { + return new Date(TypesPrototype.getUint32(chunk) * 1000); } - , getVersion: function (chunk) { - return Types.getInt8(chunk.slice(0,1)) + "." + Types.getInt8(chunk.slice(1,2)); + , getVersion: function (chunk) { + return TypesPrototype.getInt8(chunk.slice(0,1)) + "." + TypesPrototype.getInt8(chunk.slice(1,2)); } - , getModel: function (chunk) { + , getModel: function (chunk) { return chunk; } - , getUnknown: function (chunk) { + , getUnknown: function (chunk) { // Unimplemented throw "ERROR_UNIMPLEMENTED"; - /* - switch (chunk.byteLength) { - // We can tring a string - default: - break; - } - */ +// switch (chunk.byteLength) { +// // We can tring a string +// default: +// +// break; +// } + + } + + , getType: function (chunk) { + return TypesPrototype.getString(chunk.slice(0, 4)).toLowerCase(); + } + } + + , typeMap = { + 1: { + length: 1 + , unpack: TypesPrototype.getInt8 + } + + , 2: { + length: 1 + , unpack: TypesPrototype.getUint8 + } + + , 3: { + length: 2 + , unpack: TypesPrototype.getInt16 + } + + , 4: { + length: 2 + , unpack: TypesPrototype.getUint16 + } + + , 5: { + length: 4 + , unpack: TypesPrototype.getInt32 + } + + , 6: { + length: 4 + , unpack: TypesPrototype.getUint32 + } + + , 7: { + length: 8 + , unpack: TypesPrototype.getFloat64 + } + + // There is no unsigned 64bit integer in JS. + , 8: { + length: 8 + , unpack: TypesPrototype.getFloat64 + } + + , 9: { + length: null + , unpack: TypesPrototype.getUTFString + } + + , 10: { + length: 4 + , unpack: TypesPrototype.getDate + } + + , 11: { + length: 2 + , unpack: TypesPrototype.getVersion } - , getType: function (chunk) { - return Types.getString(chunk.slice(0, 4)).toLowerCase(); + , 12: { + length: null + , unpack: TypesPrototype.getModel } + }; - }); + Types.prototype = TypesPrototype; return Types; }); diff --git a/resources/js/models/dmap.js b/resources/js/models/dmap.js index 6e47cbf..eb25ba0 100644 --- a/resources/js/models/dmap.js +++ b/resources/js/models/dmap.js @@ -7,43 +7,61 @@ define([ "underscore" , "backbone" + , "toolbox" , "models/dmap-type" , "collections/dmap" ] -, function (_, Backbone, DMAPType, DMAPCollection) { +, function (_, Backbone, Toolbox, DMAPType, DMAPCollection) { "use strict"; var that + , browserTags = { + "abal": "abal" + , "abar": "abar" + , "abcp": "abcp" + , "abgn": "abgn" + , "abro": "abro" + } + , Model = Backbone.Model.extend({ idAttribute: "_id" , initialize: function (attributes, options) { that = this; - this.contentCodes = options && options.contentCodes || null; - console.log("Initial", options, this.contentCodes); + var contentCodes = options && options.contentCodes || null; - if (options.buffer instanceof ArrayBuffer) { - attributes = parseWrapper(options.buffer); - delete options.buffer; + if (attributes instanceof ArrayBuffer) {//(options.buffer instanceof ArrayBuffer) { + attributes = parseWrapper(attributes, contentCodes); + } - this.set(attributes); + if (attributes && attributes.byteLength) { + delete attributes.byteLength; } + attributes._id = that.getAttributesId(attributes); + + this.set(attributes); + return this; } -/* - , set: function (attributes, options) { - console.log(attributes, options); - - this._id = attributes["dmap.persistentid"] || attributes["dmap.itemid"] || attributes["dmap.containeritemid"]; - - Model.__super__.set(this, arguments); - - return this; + + , getAttributesId: function(attributes) { + return /*attributes["dmap_persistentid"] || */attributes["dmap_itemid"] || attributes["dmap_containeritemid"] || null; } -*/ + + , toJSON: function(options) { + var attrs = _.clone(this.attributes); + + if (!_.isUndefined(attrs._id)) { + attrs.id = attrs._id; + delete attrs._id; + } + + return attrs; + } + , update: function (attributes, options) { that.trigger("dmap.model.update", this, arguments); @@ -85,76 +103,98 @@ define([ } }) - , parseCodeDictionnary = function(dictChunk) { + , parseContentCode = function(dictChunk) { var codeElement = {}; - + while (dictChunk.byteLength > 8) { - var contentCode = DMAPType.getType(dictChunk); - var contentLength = DMAPType.getInt32(dictChunk.slice(4,8)); + var contentCode = DMAPType.prototype.getType(dictChunk); + var contentLength = DMAPType.prototype.getInt32(dictChunk.slice(4,8)); //console.log(contentLength); switch (contentCode) { case 'mcnm': - codeElement.code = DMAPType.getString(dictChunk.slice(8, 8+contentLength)); + codeElement.code = DMAPType.prototype.getString(dictChunk.slice(8, 8+contentLength)); break; - + case 'mcna': - var codeName = DMAPType.getString(dictChunk.slice(8, 8+contentLength)); + var codeName = DMAPType.prototype.getString(dictChunk.slice(8, 8+contentLength)); codeElement.name = codeName.replace(/\./g, '_'); - //console.log(codeElement.name); break; - + case 'mcty': - var typeData = DMAPType.getInt16(dictChunk.slice(8, 8+contentLength)); + var typeData = DMAPType.prototype.getInt16(dictChunk.slice(8, 8+contentLength)); codeElement.type = new DMAPType(typeData); break; } - + dictChunk = dictChunk.slice(8+contentLength); } - + return codeElement; } - , parseBinaryChunk = function (binaryChunk) { + , parseBinaryChunk = function (binaryChunk, contentCodes) { var entry = {}; - + while (binaryChunk.byteLength > 8) { - var tagName = DMAPType.getType(binaryChunk); - var tagLength = DMAPType.getInt32(binaryChunk.slice(4,8)); - //console.debug(codeInfo, tagName, tagLength); - - if (that.contentCodes === null) { - switch (tagName) { - case 'mdcl': - var contentCode = parseCodeDictionnary(binaryChunk.slice(8, 8+tagLength)); - var codeId = contentCode.code.toLowerCase(); - - entry[codeId] = _.extend({}, contentCode, contentCode.type); - break; - - case 'mstt': - // Nothing to do with the status, skip it - break; - } - } else { - var codeInfo = that.contentCodes.get(tagName); - - if (codeInfo) { - if (codeInfo.type === 12) { - if (typeof entry[codeInfo.name] === "undefined") { - // Here we might want to select different collection types depending on the tag - entry[codeInfo.name] = new DMAPCollection(); - } + var tagName = DMAPType.prototype.getType(binaryChunk); + var tagLength = DMAPType.prototype.getInt32(binaryChunk.slice(4,8)); + + if (tagName !== "mstt") { // Skip the status code, we really don't care for it. + if (tagName === "mdcl") { // Our contentCodes is probably empty as we found the content codes + var contentCode = parseContentCode(binaryChunk.slice(8, 8+tagLength)); + var codeId = contentCode.code.toLowerCase(); - entry[codeInfo.name].add(binaryChunk.slice(8, tagLength), {silent: true}); + entry[codeId] = _.extend({}, contentCode, contentCode.type); + } else { + var codeInfo = contentCodes.get(tagName); + + if (!_.isObject(codeInfo)) { + console.info("Unknow content code: " + tagName, tagLength); } else { - //console.log(codeInfo); - entry[codeInfo.name] = codeInfo.unpack(binaryChunk.slice(8), tagLength); + if (codeInfo.getCode() !== 12 ) { + entry[codeInfo.name] = codeInfo.unpack(binaryChunk.slice(8), tagLength); + } else if ((tagName in browserTags) === true) { + tagLength = binaryChunk.byteLength; // This is how fucked DAAP is, we overwrite the length because + // in this specific case 'mlit' which is reported as a container is in fact a string + var browserList = binaryChunk.slice(8); + entry[codeInfo.name] = []; + + while (browserList.byteLength > 8) { + var itemTag = DMAPType.prototype.getType(browserList); + var itemLength = DMAPType.prototype.getInt32(browserList.slice(4,8)); + + entry[codeInfo.name].push(DMAPType.prototype.getUTFString(browserList.slice(8), itemLength)); + + browserList = browserList.slice(8 + itemLength); + } + } else if (codeInfo.getCode() === 12) { + var result = parseBinaryChunk(binaryChunk.slice(8, tagLength), contentCodes); + + if (result) { + var keys = null; + + if (_.isString(result)) { + if ( !(entry[codeInfo.name] instanceof DMAPCollection) ) { + entry[codeInfo.name] = []; + } + + entry[codeInfo.name].push(result); + } else if (getItemId(result) !== null) { + if ( !(entry[codeInfo.name] instanceof DMAPCollection) ) { + entry[codeInfo.name] = new DMAPCollection(); + } + + entry[codeInfo.name].add(new Model(result)); + // Here we found a listing item and we are going to squash the single item array + } else if (_.isObject(result) && Object.keys(result).length === 1) { + entry[codeInfo.name] = result[Object.keys(result)[0]]; + } + } else { + // We could alternatively autodetect the type here + } + } } - } else { - // TODO: we should try to guess. - console.info("Unknown type: " + tagName + "(" + tagLength + ")"); } } @@ -164,39 +204,49 @@ define([ return entry; } - , parseWrapper = function(binaryData) { - var containerType = DMAPType.getType(binaryData); - //var binaryLength = DMAPType.getUint32(binaryData.slice(4,8)); - var contentData = binaryData.slice(8); - - switch (containerType) { - // Update - case "mupd": - // Unsupported - return; - break; - - default: - console.info("Unknown type: " + containerType/*, binaryLength*/, contentData); - // Content codes - case "mccr": - // Server Info - case "msrv": - // Login - case "mlog": - // Database - case "adbs": - // Database info - case "avdb": - // Playlist info - case "aply": - // List of songs - case "apso": - return parseBinaryChunk(contentData); - break; + , parseWrapper = function(binaryData, contentCodes) { + if (binaryData.byteLength <= 8) { + return parseBinaryChunk(binaryData, contentCodes); + } else { + var containerType = DMAPType.prototype.getType(binaryData); + //var binaryLength = DMAPType.prototype.getUint32(binaryData.slice(4,8)); + var contentData = binaryData.slice(8); + switch (containerType) { + // Update + //case "mupd": + // // Unsupported + // return; + //break; + // Browsing list + case "abro": + // Content codes + case "mccr": + // Server Info + case "msrv": + // Login + case "mlog": + // Item listing + case "mlit": + // Database + case "adbs": + // Database info + case "avdb": + // Playlist info + case "aply": + // List of songs + case "apso": + return parseBinaryChunk(contentData, contentCodes); + default: + console.info("Unknown type: " + containerType, contentData); + return parseBinaryChunk(binaryData, contentCodes); + } } } -; + + , getItemId = function (item) { + return item["dmap_persistentid"] || item["dmap_itemid"] || item["dmap_containeritemid"] || null; + } + ; return Model; }); \ No newline at end of file diff --git a/resources/js/models/dmap2 b/resources/js/models/dmap2 new file mode 100644 index 0000000..c12bc3f --- /dev/null +++ b/resources/js/models/dmap2 @@ -0,0 +1,71 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ +define([ + "underscore" + , "backbone" + , "toolbox" + , "models/dmap-type" +] +, function (_, Backbone, Toolbox, DMAPType) { + "use strict"; + + var that + + , set = function (attributes) { + + } + + , DMAP = Toolbox.Base.extend({ + id: null + , attributes: false + , collection: false + , parentid: null + , index: {} + , items: [] + + , constructor: function (buffer, parent, options) { + + } + + , set: function () { + + } + + , get: function () { + + } + + , getItem: function () { + + } + + , getItemByIndex: function () { + + } + + , parseBinary: function () { + + } + + , parseContentCode: function () { + + } + + , addItem: function (item) { + + } + + , remove: function (items) { + + } + }); + + _.extend(DMAP.prototype, Backbone.Events, {}); + + return DMAP; + +}); \ No newline at end of file diff --git a/resources/js/views/app.js b/resources/js/views/app.js new file mode 100644 index 0000000..1c46f73 --- /dev/null +++ b/resources/js/views/app.js @@ -0,0 +1,59 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ + +define([ + "jquery" + , "backbone" + , "jquery-layout" +] +, function ($, Backbone) { + "use strict"; + + return Backbone.View.extend({ + el: $("body") + + , layout: null + , layoutItems: null + + , events: { + } + + , initialize: function() { + //_.bindAll(this); + + var that = this; + + that.layout = that.$el.layout({ + //applyDefaultStyles: true + defaults: { + closable: false + , resizable: false + , slidable: false + , spacing_open: 0 + , spacing_closed: 0 + } + + , north: { + size: 52 + } + + , west: { + size: 150 + , closable: true + } + + , center: { + resizable: false + } + + , south: { + size: 30 + } + }); + } + }); +}); \ No newline at end of file diff --git a/resources/js/views/apps.js b/resources/js/views/apps.js deleted file mode 100644 index e69de29..0000000 diff --git a/resources/js/views/client.js b/resources/js/views/client.js new file mode 100644 index 0000000..be3337e --- /dev/null +++ b/resources/js/views/client.js @@ -0,0 +1,32 @@ +/* + +that.layoutItems = $(that.layout.panes.center).layout({ + defaults: { + closable: false + , resizable: true + , slidable: true + , spacing_open: 5 + , spacing_closed: 5 + } + + , north: { + minSize: 100 + , size: 200 + , closable: true + //, onresize: function (pane, $pane, state, options) { + // var viewportHeight = $pane.innerHeight() - App.BrowserView.$el.find(".dataTables_scrollHead").height(); + // App.BrowserView.$el.find(".dataTables_scrollBody").height(viewportHeight); + // //App.BrowserView.reDraw(); + // } + } + + , center: { + minSize: 200 + //, onresize: function (pane, $pane, state, options) { + // var viewportHeight = $pane.innerHeight() - App.ListView.$el.find(".dataTables_scrollHead").height(); + // App.ListView.$el.find(".dataTables_scrollBody").height(viewportHeight); + // //App.ListView.render(); + // } + } +}); + */ \ No newline at end of file diff --git a/resources/js/views/footer.js b/resources/js/views/footer.js index e69de29..0cefaf4 100644 --- a/resources/js/views/footer.js +++ b/resources/js/views/footer.js @@ -0,0 +1,14 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ +define([ + "bootstrap" +] +, function (Bootstrap) { + "use strict"; + + return function() {}; +}); \ No newline at end of file diff --git a/resources/js/views/main.js b/resources/js/views/main.js index e69de29..a9c4497 100644 --- a/resources/js/views/main.js +++ b/resources/js/views/main.js @@ -0,0 +1,13 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ +define([ +] +, function () { + "use strict"; + + return function() {}; +}); \ No newline at end of file diff --git a/resources/js/views/player.js b/resources/js/views/player.js index e69de29..a9c4497 100644 --- a/resources/js/views/player.js +++ b/resources/js/views/player.js @@ -0,0 +1,13 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ +define([ +] +, function () { + "use strict"; + + return function() {}; +}); \ No newline at end of file diff --git a/resources/js/views/sidebar.js b/resources/js/views/sidebar.js new file mode 100644 index 0000000..a9c4497 --- /dev/null +++ b/resources/js/views/sidebar.js @@ -0,0 +1,13 @@ +/*jslint laxbreak:true */ +/*jslint laxcomma:true */ +/*jslint loopfunc:true */ +/*jslint strict:true */ +/*jslint browser:true */ +/*jslint devel:true */ +define([ +] +, function () { + "use strict"; + + return function() {}; +}); \ No newline at end of file diff --git a/resources/js/views/siderbar.js b/resources/js/views/siderbar.js deleted file mode 100644 index e69de29..0000000 diff --git a/resources/vendors/backbone/localstorage/8651291560 b/resources/vendors/backbone/localstorage/8651291560 new file mode 160000 index 0000000..8651291 --- /dev/null +++ b/resources/vendors/backbone/localstorage/8651291560 @@ -0,0 +1 @@ +Subproject commit 8651291560d37403bf347466213bd8b900b0a501 diff --git a/resources/vendors/lodash/string/2.3.0/underscore.string.min.js b/resources/vendors/lodash/string/2.3.0/underscore.string.min.js new file mode 100644 index 0000000..8fc1e2d --- /dev/null +++ b/resources/vendors/lodash/string/2.3.0/underscore.string.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";var n=t.prototype.trim,r=t.prototype.trimRight,i=t.prototype.trimLeft,s=function(e){return e*1||0},o=function(e,t){if(t<1)return"";var n="";while(t>0)t&1&&(n+=e),t>>=1,e+=e;return n},u=[].slice,a=function(e){return e==null?"\\s":e.source?e.source:"["+p.escapeRegExp(e)+"]"},f={lt:"<",gt:">",quot:'"',apos:"'",amp:"&"},l={};for(var c in f)l[f[c]]=c;var h=function(){function e(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}var n=o,r=function(){return r.cache.hasOwnProperty(arguments[0])||(r.cache[arguments[0]]=r.parse(arguments[0])),r.format.call(null,r.cache[arguments[0]],arguments)};return r.format=function(r,i){var s=1,o=r.length,u="",a,f=[],l,c,p,d,v,m;for(l=0;l=0?"+"+a:a,v=p[4]?p[4]=="0"?"0":p[4].charAt(1):" ",m=p[6]-t(a).length,d=p[6]?n(v,m):"",f.push(p[5]?a+d:d+a)}}return f.join("")},r.cache={},r.parse=function(e){var t=e,n=[],r=[],i=0;while(t){if((n=/^[^\x25]+/.exec(t))!==null)r.push(n[0]);else if((n=/^\x25{2}/.exec(t))!==null)r.push("%");else{if((n=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(t))===null)throw new Error("[_.sprintf] huh?");if(n[2]){i|=1;var s=[],o=n[2],u=[];if((u=/^([a-z_][a-z_\d]*)/i.exec(o))===null)throw new Error("[_.sprintf] huh?");s.push(u[1]);while((o=o.substring(u[0].length))!=="")if((u=/^\.([a-z_][a-z_\d]*)/i.exec(o))!==null)s.push(u[1]);else{if((u=/^\[(\d+)\]/.exec(o))===null)throw new Error("[_.sprintf] huh?");s.push(u[1])}n[2]=s}else i|=2;if(i===3)throw new Error("[_.sprintf] mixing positional and named placeholders is not (yet) supported");r.push(n)}t=t.substring(n[0].length)}return r},r}(),p={VERSION:"2.3.0",isBlank:function(e){return e==null&&(e=""),/^\s*$/.test(e)},stripTags:function(e){return e==null?"":t(e).replace(/<\/?[^>]+>/g,"")},capitalize:function(e){return e=e==null?"":t(e),e.charAt(0).toUpperCase()+e.slice(1)},chop:function(e,n){return e==null?[]:(e=t(e),n=~~n,n>0?e.match(new RegExp(".{1,"+n+"}","g")):[e])},clean:function(e){return p.strip(e).replace(/\s+/g," ")},count:function(e,n){return e==null||n==null?0:t(e).split(n).length-1},chars:function(e){return e==null?[]:t(e).split("")},swapCase:function(e){return e==null?"":t(e).replace(/\S/g,function(e){return e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()})},escapeHTML:function(e){return e==null?"":t(e).replace(/[&<>"']/g,function(e){return"&"+l[e]+";"})},unescapeHTML:function(e){return e==null?"":t(e).replace(/\&([^;]+);/g,function(e,n){var r;return n in f?f[n]:(r=n.match(/^#x([\da-fA-F]+)$/))?t.fromCharCode(parseInt(r[1],16)):(r=n.match(/^#(\d+)$/))?t.fromCharCode(~~r[1]):e})},escapeRegExp:function(e){return e==null?"":t(e).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")},splice:function(e,t,n,r){var i=p.chars(e);return i.splice(~~t,~~n,r),i.join("")},insert:function(e,t,n){return p.splice(e,t,0,n)},include:function(e,n){return n===""?!0:e==null?!1:t(e).indexOf(n)!==-1},join:function(){var e=u.call(arguments),t=e.shift();return t==null&&(t=""),e.join(t)},lines:function(e){return e==null?[]:t(e).split("\n")},reverse:function(e){return p.chars(e).reverse().join("")},startsWith:function(e,n){return n===""?!0:e==null||n==null?!1:(e=t(e),n=t(n),e.length>=n.length&&e.slice(0,n.length)===n)},endsWith:function(e,n){return n===""?!0:e==null||n==null?!1:(e=t(e),n=t(n),e.length>=n.length&&e.slice(e.length-n.length)===n)},succ:function(e){return e==null?"":(e=t(e),e.slice(0,-1)+t.fromCharCode(e.charCodeAt(e.length-1)+1))},titleize:function(e){return e==null?"":t(e).replace(/(?:^|\s)\S/g,function(e){return e.toUpperCase()})},camelize:function(e){return p.trim(e).replace(/[-_\s]+(.)?/g,function(e,t){return t.toUpperCase()})},underscored:function(e){return p.trim(e).replace(/([a-z\d])([A-Z]+)/g,"$1_$2").replace(/[-\s]+/g,"_").toLowerCase()},dasherize:function(e){return p.trim(e).replace(/([A-Z])/g,"-$1").replace(/[-_\s]+/g,"-").toLowerCase()},classify:function(e){return p.titleize(t(e).replace(/_/g," ")).replace(/\s/g,"")},humanize:function(e){return p.capitalize(p.underscored(e).replace(/_id$/,"").replace(/_/g," "))},trim:function(e,r){return e==null?"":!r&&n?n.call(e):(r=a(r),t(e).replace(new RegExp("^"+r+"+|"+r+"+$","g"),""))},ltrim:function(e,n){return e==null?"":!n&&i?i.call(e):(n=a(n),t(e).replace(new RegExp("^"+n+"+"),""))},rtrim:function(e,n){return e==null?"":!n&&r?r.call(e):(n=a(n),t(e).replace(new RegExp(n+"+$"),""))},truncate:function(e,n,r){return e==null?"":(e=t(e),r=r||"...",n=~~n,e.length>n?e.slice(0,n)+r:e)},prune:function(e,n,r){if(e==null)return"";e=t(e),n=~~n,r=r!=null?t(r):"...";if(e.length<=n)return e;var i=function(e){return e.toUpperCase()!==e.toLowerCase()?"A":" "},s=e.slice(0,n+1).replace(/.(?=\W*\w*$)/g,i);return s.slice(s.length-2).match(/\w\w/)?s=s.replace(/\s*\S+$/,""):s=p.rtrim(s.slice(0,s.length-1)),(s+r).length>e.length?e:e.slice(0,s.length)+r},words:function(e,t){return p.isBlank(e)?[]:p.trim(e,t).split(t||/\s+/)},pad:function(e,n,r,i){e=e==null?"":t(e),n=~~n;var s=0;r?r.length>1&&(r=r.charAt(0)):r=" ";switch(i){case"right":return s=n-e.length,e+o(r,s);case"both":return s=n-e.length,o(r,Math.ceil(s/2))+e+o(r,Math.floor(s/2));default:return s=n-e.length,o(r,s)+e}},lpad:function(e,t,n){return p.pad(e,t,n)},rpad:function(e,t,n){return p.pad(e,t,n,"right")},lrpad:function(e,t,n){return p.pad(e,t,n,"both")},sprintf:h,vsprintf:function(e,t){return t.unshift(e),h.apply(null,t)},toNumber:function(e,n){if(e==null||e=="")return 0;e=t(e);var r=s(s(e).toFixed(~~n));return r===0&&!e.match(/^0+$/)?Number.NaN:r},numberFormat:function(e,t,n,r){if(isNaN(e)||e==null)return"";e=e.toFixed(~~t),r=r||",";var i=e.split("."),s=i[0],o=i[1]?(n||".")+i[1]:"";return s.replace(/(\d)(?=(?:\d{3})+$)/g,"$1"+r)+o},strRight:function(e,n){if(e==null)return"";e=t(e),n=n!=null?t(n):n;var r=n?e.indexOf(n):-1;return~r?e.slice(r+n.length,e.length):e},strRightBack:function(e,n){if(e==null)return"";e=t(e),n=n!=null?t(n):n;var r=n?e.lastIndexOf(n):-1;return~r?e.slice(r+n.length,e.length):e},strLeft:function(e,n){if(e==null)return"";e=t(e),n=n!=null?t(n):n;var r=n?e.indexOf(n):-1;return~r?e.slice(0,r):e},strLeftBack:function(e,t){if(e==null)return"";e+="",t=t!=null?""+t:t;var n=e.lastIndexOf(t);return~n?e.slice(0,n):e},toSentence:function(e,t,n,r){t=t||", ",n=n||" and ";var i=e.slice(),s=i.pop();return e.length>2&&r&&(n=p.rtrim(t)+n),i.length?i.join(t)+n+s:s},toSentenceSerial:function(){var e=u.call(arguments);return e[3]=!0,p.toSentence.apply(p,e)},slugify:function(e){if(e==null)return"";var n="ąà áäâãåæćęèéëêìíïîłńòóöôõøùúüûñçżź",r="aaaaaaaaceeeeeiiiilnoooooouuuunczz",i=new RegExp(a(n),"g");return e=t(e).toLowerCase().replace(i,function(e){var t=n.indexOf(e);return r.charAt(t)||"-"}),p.dasherize(e.replace(/[^\w\s-]/g,""))},surround:function(e,t){return[t,e,t].join("")},quote:function(e){return p.surround(e,'"')},exports:function(){var e={};for(var t in this){if(!this.hasOwnProperty(t)||t.match(/^(?:include|contains|reverse)$/))continue;e[t]=this[t]}return e},repeat:function(e,n,r){if(e==null)return"";n=~~n;if(r==null)return o(t(e),n);for(var i=[];n>0;i[--n]=e);return i.join(r)},levenshtein:function(e,n){if(e==null&&n==null)return 0;if(e==null)return t(n).length;if(n==null)return t(e).length;e=t(e),n=t(n);var r=[],i,s;for(var o=0;o<=n.length;o++)for(var u=0;u<=e.length;u++)o&&u?e.charAt(u-1)===n.charAt(o-1)?s=i:s=Math.min(r[u],r[u-1],i)+1:s=o+u,i=r[u],r[u]=s;return r.pop()}};p.strip=p.trim,p.lstrip=p.ltrim,p.rstrip=p.rtrim,p.center=p.lrpad,p.rjust=p.lpad,p.ljust=p.rpad,p.contains=p.include,p.q=p.quote,typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(module.exports=p),exports._s=p):typeof define=="function"&&define.amd?define("underscore.string",[],function(){return p}):(e._=e._||{},e._.string=e._.str=p)}(this,String); \ No newline at end of file