3 |
4 |
5 |
${title}
6 |
7 |
${'↓ ' + totalDlSpeed} ${'↑ ' + totalUlSpeed}
8 |
more_vert
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/pages/torrent/torrent.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/pages/torrent/torrent.js:
--------------------------------------------------------------------------------
1 | import { inject } from 'aurelia-framework';
2 | import { RuTorrentService } from '../../services/rutorrent-service';
3 | import _ from 'lodash';
4 | import { EventAggregator } from 'aurelia-event-aggregator';
5 |
6 | @inject(RuTorrentService, EventAggregator)
7 | export default class Torrent {
8 | constructor(ruTorrentService, eventAggregator) {
9 | this.title = 'Torrent list';
10 | this.ruTorrentService = ruTorrentService;
11 | this.eventAggregator = eventAggregator;
12 | this.sortBy = 'addtime';
13 | this.order = 'desc';
14 |
15 | let sortParams = [
16 | { 'name': 'Name', 'value': 'name' },
17 | { 'name': 'Status', 'value': 'status' },
18 | { 'name': 'Size', 'value': 'size' },
19 | { 'name': 'Added time', 'value': 'addtime' },
20 | { 'name': 'Remaining time', 'value': 'remaining' },
21 | { 'name': 'Percentage done', 'value': 'percent' },
22 | { 'name': 'Download speed', 'value': 'dl' },
23 | { 'name': 'Upload speed', 'value': 'ul' }
24 | ];
25 |
26 | this.eventAggregator.publish('popoper:source:init', sortParams);
27 | this.eventAggregator.subscribe('popoper:item:click', (item) => this.setSorting(item.value));
28 | // name, status, size, addtime created, remaining, ratio, percent, dl , ul
29 | }
30 |
31 | async activate(params, routeConfig, $navigationInstruction) {
32 | await this.setTorrents(true);
33 |
34 | let self = this;
35 | this.pollInteral = setInterval(() => {
36 | self.setTorrents();
37 | }, 750);
38 | }
39 |
40 | detached() {
41 | clearInterval(this.pollInteral);
42 | }
43 |
44 | async setTorrents(init) {
45 | this.torrentDatas = await this.ruTorrentService.getTorrents();
46 | let torrentsUpdated = this.torrentDatas.torrents;
47 |
48 | if (init === true) {
49 | this.torrents = torrentsUpdated;
50 | this.init = false;
51 | }
52 | else {
53 | for (let currentTorrent of this.torrents) {
54 | if (!_.some(torrentsUpdated, t => t.hash === currentTorrent.hash)) {
55 | _.remove(this.torrents, t => t.hash === currentTorrent.hash);
56 | }
57 | }
58 |
59 | for (let torrentUpdated of torrentsUpdated) {
60 | let torrent = _.find(this.torrents, t => t.hash === torrentUpdated.hash);
61 | if (torrent) {
62 | Object.assign(torrent, torrentUpdated);
63 | }
64 | else {
65 | this.torrents.push(torrentUpdated);
66 | }
67 | }
68 | }
69 | this.torrents.sort(this.sortByFn(this.sortBy, this.order));
70 | }
71 |
72 | setSorting(sortBy) {
73 | if (this.sortBy === sortBy) {
74 | this.order = this.order === 'asc' ? 'desc' : 'asc';
75 | }
76 | else {
77 | this.sortBy = sortBy;
78 | this.order = 'asc';
79 | }
80 | }
81 |
82 | sortByFn(field, order, primer) {
83 | let reverse;
84 | if (order === 'asc') {
85 | reverse = false;
86 | }
87 | else {
88 | reverse = true;
89 | }
90 | var key = primer ?
91 | function (x) { return primer(x[field]) } :
92 | function (x) { return x[field] };
93 |
94 | reverse = !reverse ? 1 : -1;
95 |
96 | return function (a, b) {
97 | return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/resources/elements/popover.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
--------------------------------------------------------------------------------
/src/resources/elements/popover.js:
--------------------------------------------------------------------------------
1 | import {inject} from 'aurelia-framework';
2 | import {EventAggregator} from 'aurelia-event-aggregator';
3 |
4 | @inject(EventAggregator)
5 | export class Popover {
6 | constructor(eventAggregator) {
7 | this.eventAggregator = eventAggregator;
8 | this.source = [];
9 | let self = this;
10 | this.eventAggregator.subscribe('popoper:source:init', items => {
11 | self.items = items;
12 | });
13 | }
14 |
15 | handleClick(item) {
16 | this.eventAggregator.publish('popoper:item:click', item);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/resources/elements/progress-bar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/resources/elements/progress-bar.js:
--------------------------------------------------------------------------------
1 | import {customElement, bindable} from 'aurelia-framework';
2 | import F7 from '../../services/framework7';
3 |
4 | @bindable('percent')
5 | @customElement('progress-bar')
6 | export class ProgressBar {
7 |
8 | constructor() {
9 | this.f7 = new F7();
10 | }
11 |
12 | bind() {
13 | this.updateColor();
14 | this.f7.setProgressbar(this.element, this.percent, 0);
15 | }
16 |
17 | percentChanged(newVal) {
18 | this.updateColor();
19 | this.f7.setProgressbar(this.element, newVal, 0);
20 | }
21 |
22 | updateColor() {
23 | if(this.percent === 100) {
24 | this.color = 'green';
25 | }
26 | else {
27 | this.color = 'blue';
28 | }
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/resources/elements/smart-select.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
${label}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/resources/elements/smart-select.js:
--------------------------------------------------------------------------------
1 | import { bindable } from 'aurelia-framework';
2 | import F7 from '../../services/framework7';
3 |
4 | @bindable('label')
5 | @bindable('source')
6 | @bindable('value')
7 | export class SmartSelect {
8 |
9 | constructor() {
10 | this.f7 = new F7();
11 | }
12 |
13 | bind() {
14 | if(this.source && this.source.length > 0) {
15 | this.value = this.source[0];
16 | this.valueNameElement.innerHTML = this.source[0].name || this.source[0];
17 | }
18 | }
19 |
20 | valueChanged(newValue) {
21 | if (newValue) {
22 | this.valueNameElement.innerHTML = newValue.name || newValue;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/services/framework7.js:
--------------------------------------------------------------------------------
1 | import 'framework7/dist/js/framework7';
2 |
3 | let Instance;
4 | export default class F7 {
5 |
6 | constructor() {
7 | if(!Instance) {
8 | var notificationTemplate =
9 | '{{#if custom}}' +
10 | '
{{custom}}' +
11 | '{{else}}' +
12 | '
' +
13 | '' +
14 | '{{#if material}}' +
15 | '
' +
16 | '
{{js "this.message || this.title || this.subtitle"}}
' +
17 | '{{#if ../button}}{{#button}}' +
18 | '
' +
21 | '{{/button}}{{/if}}' +
22 | '
' +
23 | '{{else}}' +
24 | '{{#if media}}' +
25 | '
{{media}}
' +
26 | '{{/if}}' +
27 | '
' +
28 | '
' +
29 | '{{#if title}}' +
30 | '
{{title}}
' +
31 | '{{/if}}' +
32 | '{{#if closeIcon}}' +
33 | '
' +
34 | '{{/if}}' +
35 | '
' +
36 | '{{#if subtitle}}' +
37 | '
{{subtitle}}
' +
38 | '{{/if}}' +
39 | '{{#if message}}' +
40 | '
{{message}}
' +
41 | '
' +
42 | '{{/if}}' +
43 | '{{/if}}' +
44 | '
' +
45 | '' +
46 | '{{/if}}';
47 | Instance = new Framework7({router: false, material: true, activeState: true, materialRipple: true, notificationTemplate: notificationTemplate});
48 | }
49 |
50 | return Instance;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/services/proxy-service.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 | import {HttpClient} from 'aurelia-http-client';
3 |
4 | export class ProxyService {
5 |
6 | yahooQueryUrl = "https://query.yahooapis.com/v1/public/yql?q="
7 |
8 | constructor() {
9 | this.httpClient = new HttpClient();
10 | }
11 |
12 | async getData(query) {
13 | return this.httpClient.get(this.yahooQueryUrl + query).then((httpResponse) => {
14 | console.log(httpResponse);
15 | let response = httpResponse.response;
16 | let result = response.substring(response.indexOf('
'), response.indexOf(''));
17 | return result;
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/services/rutorrent-service.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 | import { HttpClient } from 'aurelia-http-client';
3 |
4 | export class RuTorrentService {
5 |
6 | constructor() {
7 | this.httpClient = new HttpClient().configure(x => {
8 | x.withHeader('Content-Type', 'application/x-www-form-urlencoded');
9 | });
10 | }
11 |
12 | async request(url) {
13 | return new Promise((resolve, reject) => {
14 | theWebUI.requestWithTimeout(url, resolve, reject, reject);
15 | });
16 | }
17 |
18 | async getTorrentsRaw() {
19 | return await this.request('?list=1&getmsg=1');
20 | }
21 |
22 | async getTorrents() {
23 | let self = this;
24 | let data = await this.getTorrentsRaw();
25 | let tdl = 0;
26 | let tul = 0;
27 | data.torrents = _.map(data.torrents, function (value, hash) {
28 | tdl += iv(value.dl);
29 | tul += iv(value.ul);
30 | value.hash = hash;
31 | value.size = parseInt(value.size);
32 | value.created = parseInt(value.created);
33 | value.addtime = parseInt(value.addtime);
34 | value.remaining = parseInt(value.remaining);
35 | value.percent = Math.trunc(value.done / 10);
36 | value.downloadedHumanized = theConverter.bytes(value.downloaded, 2);
37 | value.uploadedHumanized = theConverter.bytes(value.uploaded, 2);
38 | value.sizeHumanized = theConverter.bytes(value.size, 2);
39 | value.etaHumanized = theConverter.time(value.eta);
40 | value.dlHumanized = theConverter.speed(value.dl);
41 | value.ulHumanized = theConverter.speed(value.ul);
42 | value.status = self.getStatus(value);
43 | value.isStoppable = ((value.state & dStatus.started) || (value.state & dStatus.hashing) || (value.state & dStatus.checking))
44 | value.isFinished = value.done === 1000;
45 |
46 | return value;
47 | });
48 |
49 | let zeroSpeedHumanized = '0 ' + theUILang.KB + "/" + theUILang.s;
50 | let tdlHumanized = tdl !== 0 ? theConverter.speed(tdl) : zeroSpeedHumanized;
51 | let tulHumanized = tul !== 0 ? theConverter.speed(tul) : zeroSpeedHumanized;
52 |
53 | return { torrents: data.torrents, totalDl: tdlHumanized, totalUl: tulHumanized };
54 | }
55 |
56 | async addTorrent(url) {
57 | return this.httpClient.post('php/addtorrent.php', `url=${encodeURIComponent(url)}`)
58 | .then((httpResponse) => {
59 | if (httpResponse.response.indexOf('addTorrentSuccess') !== -1) {
60 | return true;
61 | }
62 | return false;
63 | });
64 | }
65 |
66 | async toggleTorrentState(torrent) {
67 | var status = torrent.state;
68 |
69 | if ((status & dStatus.started) || (status & dStatus.hashing) || (status & dStatus.checking)) {
70 | await this.request('?action=stop&hash=' + torrent.hash);
71 | }
72 | else {
73 | await this.request('?action=start&hash=' + torrent.hash);
74 | }
75 | }
76 |
77 | async deleteTorrent(hash) {
78 | await this.request('?action=removewithdata&hash=' + hash);
79 | }
80 |
81 | async getFiles(hash) {
82 | let result = await this.request('?action=getfiles&hash=' + hash);
83 | return result[hash];
84 | }
85 |
86 | getStatus(torrent) {
87 | return theWebUI.getStatusIcon(torrent)[1];
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/services/torrent-search-service.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 | import { inject } from 'aurelia-framework';
3 | import { ProxyService } from './proxy-service';
4 | import { HttpClient } from 'aurelia-http-client';
5 |
6 | @inject(ProxyService)
7 | export class TorrentSearchService {
8 |
9 | constructor(proxyService) {
10 | this.proxyService = proxyService;
11 | this.httpClient = new HttpClient().configure(x => {
12 | x.withHeader('Content-Type', 'application/x-www-form-urlencoded');
13 | });
14 | }
15 |
16 | async getDetail(torrent) {
17 | if (_.startsWith(torrent.desc, 'https://www.t411')) {
18 | let query = `select * from html where url="${torrent.desc}" and xpath="//article"`;
19 | return await this.proxyService.getData(query);
20 | }
21 | return null;
22 | }
23 |
24 | getProviders() {
25 | let sites = _.map(theSearchEngines.sites, (value, name) => {
26 | value.name = name;
27 | return value;
28 | });
29 |
30 | let publicSites = _.filter(sites, s => s.enabled);
31 | publicSites.splice(0, 0, { value: 'all', name: 'all', cats: ['all'] });
32 |
33 | return publicSites;
34 | }
35 |
36 | async search(siteName, categoryName, queryText) {
37 | let postDatas = `mode=get&eng=${encodeURIComponent(siteName)}&what=${encodeURIComponent(queryText)}&cat=${encodeURIComponent(categoryName)}`;
38 | return this.httpClient.post('plugins/extsearch/action.php', postDatas).then((httpResponse) => {
39 |
40 | let results = JSON.parse(httpResponse.response);
41 | let torrentsSorted = _.orderBy(results.data, ['seeds', 'peers'], ['desc', 'desc']);
42 |
43 | return _.map(torrentsSorted, t => {
44 | t.timeHumanized = theConverter.date(t.time);
45 | t.sizeHumanized = theConverter.bytes(t.size, 2);
46 | return t;
47 | });
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/styles/styles.less:
--------------------------------------------------------------------------------
1 | /* === Pages === */
2 | .list-block-no-top-margin {
3 | margin: 0 0 10px 0;
4 | }
5 |
6 | .nav-bar-small-text {
7 | padding-right: 10px;
8 | font-size: 12px;
9 | }
10 |
11 | img {
12 | display: block;
13 | max-width:100%;
14 | max-height:100%;
15 | width: auto;
16 | height: auto;
17 | margin-left: auto;
18 | margin-right: auto;
19 | }
20 |
21 | .urlIframe {
22 | position: absolute;
23 | top:56px;
24 | left: 0;
25 | width: 100%;
26 | height: 100%;
27 | border: none;
28 | }
29 |
30 | iframe {
31 | position: absolute;
32 | width: 100%;
33 | border: none;
34 | }
35 |
36 | .translate3d(@x:0, @y:0, @z:0) {
37 | -webkit-transform: translate3d(@x,@y,@z);
38 | transform: translate3d(@x,@y,@z);
39 | }
40 | .scrollable(){
41 | overflow: auto;
42 | -webkit-overflow-scrolling: touch;
43 | }
44 | .animation(@a) {
45 | -webkit-animation: @a;
46 | animation: @a;
47 | }
48 | .transition(@d) {
49 | -webkit-transition-duration: @d;
50 | transition-duration: @d;
51 | }
52 | .delay(@d) {
53 | -webkit-transition-delay: @d;
54 | transition-delay: @d;
55 | }
56 | // Pages animations
57 | @pageDuration: 400ms;
58 |
59 | .pages {
60 | position: relative;
61 | width: 100%;
62 | height: 100%;
63 | overflow: hidden;
64 | background: #000;
65 | }
66 | .page {
67 | box-sizing: border-box;
68 | position: absolute;
69 | left: 0;
70 | top: 0;
71 | width: 100%;
72 | height: 100%;
73 | background: #efeff4;
74 | .translate3d(0,0,0);
75 | &.cached {
76 | display: none;
77 | }
78 | }
79 | .page-on-left {
80 | opacity: 0;
81 | .translate3d(-20%);
82 | }
83 | .page-on-center {
84 | .swipeback-page-shadow {
85 | opacity: 1;
86 | }
87 | }
88 | .page-on-right {
89 | .translate3d(100%);
90 | .swipeback-page-shadow {
91 | opacity: 0;
92 | }
93 | }
94 | .page-content {
95 | .scrollable();
96 | box-sizing: border-box;
97 | height: 100%;
98 | position: relative;
99 | z-index: 1;
100 | }
101 |
102 | // Page Shadow
103 | .page-fake-shadow() {
104 | position: absolute;
105 | right: 100%;
106 | top: 0;
107 | width: 16px;
108 | height: 100%;
109 | background: -webkit-linear-gradient(left, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 10%, rgba(0,0,0,0.01) 50%, rgba(0,0,0,0.2) 100%);
110 | background: linear-gradient(to right, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 10%, rgba(0,0,0,0.01) 50%, rgba(0,0,0,0.2) 100%);
111 | z-index: -1;
112 | content: '';
113 | html.android & {
114 | display: none;
115 | .animation(none);
116 | }
117 | }
118 | .swipeback-page-shadow {
119 | .page-fake-shadow();
120 | }
121 |
122 |
123 | //Class that will trigger transition during page custom transitions (like swipe-back)
124 | .page-transitioning {
125 | &, .swipeback-page-shadow {
126 | .transition(@pageDuration);
127 | }
128 | }
129 | .page-from-right-to-center, .page-from-center-to-right {
130 | &:before {
131 | .page-fake-shadow();
132 | }
133 | }
134 | // From/to Right To/from Center animations
135 | .page-from-right-to-center {
136 | &:before {
137 | .animation(pageFromRightToCenterShadow @pageDuration forwards);
138 | }
139 | .animation(pageFromRightToCenter @pageDuration forwards);
140 | }
141 | .page-from-center-to-right {
142 | &:before {
143 | .animation(pageFromCenterToRightShadow @pageDuration forwards);
144 | }
145 | .animation(pageFromCenterToRight @pageDuration forwards);
146 | }
147 | @-webkit-keyframes pageFromRightToCenter {
148 | from {
149 | -webkit-transform: translate3d(100%,0,0);
150 | }
151 | to {
152 | -webkit-transform: translate3d(0,0,0);
153 | }
154 | }
155 | @keyframes pageFromRightToCenter {
156 | from {
157 | transform: translate3d(100%,0,0);
158 | }
159 | to {
160 | transform: translate3d(0,0,0);
161 | }
162 | }
163 | @-webkit-keyframes pageFromRightToCenterShadow {
164 | from {
165 | opacity: 0;
166 | }
167 | to {
168 | opacity: 1;
169 | }
170 | }
171 | @keyframes pageFromRightToCenterShadow {
172 | from {
173 | opacity: 0;
174 | }
175 | to {
176 | opacity: 1;
177 | }
178 | }
179 | @-webkit-keyframes pageFromCenterToRight {
180 | from {
181 | -webkit-transform: translate3d(0,0,0);
182 | }
183 | to {
184 | -webkit-transform: translate3d(100%,0,0);
185 | }
186 | }
187 | @keyframes pageFromCenterToRight {
188 | from {
189 | transform: translate3d(0,0,0);
190 | }
191 | to {
192 | transform: translate3d(100%,0,0);
193 | }
194 | }
195 | @-webkit-keyframes pageFromCenterToRightShadow {
196 | from {
197 | opacity: 1;
198 | }
199 | to {
200 | opacity: 0;
201 | }
202 | }
203 | @keyframes pageFromCenterToRightShadow {
204 | from {
205 | opacity: 1;
206 | }
207 | to {
208 | opacity: 0;
209 | }
210 | }
211 |
212 |
213 | // From/to Center To/from Left animations
214 | .page-from-center-to-left {
215 | .animation(pageFromCenterToLeft @pageDuration forwards);
216 | }
217 | .page-from-left-to-center {
218 | .animation(pageFromLeftToCenter @pageDuration forwards);
219 | }
220 |
221 | @-webkit-keyframes pageFromCenterToLeft {
222 | from {
223 | opacity: 1;
224 | -webkit-transform: translate3d(0,0,0);
225 | }
226 | to {
227 | opacity: 0.9;
228 | -webkit-transform: translate3d(-20%,0,0);
229 | }
230 | }
231 | @keyframes pageFromCenterToLeft {
232 | from {
233 | transform: translate3d(0,0,0);
234 | }
235 | to {
236 | opacity: 0;
237 | transform: translate3d(-20%,0,0);
238 | }
239 | }
240 | @-webkit-keyframes pageFromLeftToCenter {
241 | from {
242 | opacity: 0.9;
243 | -webkit-transform: translate3d(-20%,0,0);
244 | }
245 | to {
246 | opacity: 1;
247 | -webkit-transform: translate3d(0,0,0);
248 | }
249 | }
250 | @keyframes pageFromLeftToCenter {
251 | from {
252 | transform: translate3d(-20%,0,0);
253 | }
254 | to {
255 | opacity: 1;
256 | transform: translate3d(0,0,0);
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/webpack.config.babel.js:
--------------------------------------------------------------------------------
1 | /**
2 | * To learn more about how to use Easy Webpack
3 | * Take a look at the README here: https://github.com/easy-webpack/core
4 | **/
5 | import { generateConfig, get, stripMetadata, EasyWebpackConfig } from '@easy-webpack/core'
6 | import path from 'path'
7 |
8 | import envProd from '@easy-webpack/config-env-production'
9 | import envDev from '@easy-webpack/config-env-development'
10 | import aurelia from '@easy-webpack/config-aurelia'
11 | import babel from '@easy-webpack/config-babel'
12 | import html from '@easy-webpack/config-html'
13 | import css from '@easy-webpack/config-css'
14 | import less from '@easy-webpack/config-less'
15 | import fontAndImages from '@easy-webpack/config-fonts-and-images'
16 | import globalBluebird from '@easy-webpack/config-global-bluebird'
17 | import globalJquery from '@easy-webpack/config-global-jquery'
18 | import globalRegenerator from '@easy-webpack/config-global-regenerator'
19 | import generateIndexHtml from '@easy-webpack/config-generate-index-html'
20 | import commonChunksOptimize from '@easy-webpack/config-common-chunks-simple'
21 | import copyFiles from '@easy-webpack/config-copy-files'
22 | import uglify from '@easy-webpack/config-uglify'
23 | import generateCoverage from '@easy-webpack/config-test-coverage-istanbul'
24 |
25 | process.env.BABEL_ENV = 'webpack'
26 | const ENV = process.env.NODE_ENV && process.env.NODE_ENV.toLowerCase() || (process.env.NODE_ENV = 'development')
27 |
28 | // basic configuration:
29 | const title = 'RuMobile'
30 | const baseUrl = 'plugins/rumobile/dist/'
31 | const rootDir = path.resolve()
32 | const srcDir = path.resolve('src')
33 | const outDir = path.resolve('dist')
34 |
35 | const coreBundles = {
36 | bootstrap: [
37 | 'aurelia-bootstrapper-webpack',
38 | 'aurelia-polyfills',
39 | 'aurelia-pal',
40 | 'aurelia-pal-browser',
41 | 'regenerator-runtime',
42 | 'bluebird'
43 | ],
44 | // these will be included in the 'aurelia' bundle (except for the above bootstrap packages)
45 | aurelia: [
46 | 'aurelia-bootstrapper-webpack',
47 | 'aurelia-binding',
48 | 'aurelia-dependency-injection',
49 | 'aurelia-event-aggregator',
50 | 'aurelia-framework',
51 | 'aurelia-history',
52 | 'aurelia-history-browser',
53 | 'aurelia-loader',
54 | 'aurelia-loader-webpack',
55 | 'aurelia-logging',
56 | 'aurelia-logging-console',
57 | 'aurelia-metadata',
58 | 'aurelia-pal',
59 | 'aurelia-pal-browser',
60 | 'aurelia-path',
61 | 'aurelia-polyfills',
62 | 'aurelia-route-recognizer',
63 | 'aurelia-router',
64 | 'aurelia-task-queue',
65 | 'aurelia-templating',
66 | 'aurelia-templating-binding',
67 | 'aurelia-templating-router',
68 | 'aurelia-templating-resources'
69 | ]
70 | }
71 |
72 | /**
73 | * Main Webpack Configuration
74 | */
75 | let config = generateConfig(
76 | {
77 | entry: {
78 | 'app': ['./src/main' /* this is filled by the aurelia-webpack-plugin */],
79 | 'aurelia-bootstrap': coreBundles.bootstrap,
80 | 'aurelia': coreBundles.aurelia.filter(pkg => coreBundles.bootstrap.indexOf(pkg) === -1)
81 | },
82 | output: {
83 | path: outDir,
84 | publicPath: baseUrl
85 | }
86 | },
87 |
88 | /**
89 | * Don't be afraid, you can put bits of standard Webpack configuration here
90 | * (or at the end, after the last parameter, so it won't get overwritten by the presets)
91 | * Because that's all easy-webpack configs are - snippets of premade, maintained configuration parts!
92 | *
93 | * For Webpack docs, see: https://webpack.js.org/configuration/
94 | */
95 |
96 | ENV === 'test' || ENV === 'development' ?
97 | envDev(ENV !== 'test' ? {} : {devtool: 'inline-source-map'}) :
98 | envProd({ /* devtool: '...' */ }),
99 |
100 | aurelia({root: rootDir, src: srcDir, title: title, baseUrl: baseUrl}),
101 |
102 | babel(),
103 | html(),
104 | css({ filename: 'styles.css', allChunks: true, sourceMap: false }),
105 | less({ filename: 'styles.css'}),
106 | fontAndImages(),
107 | globalBluebird(),
108 | globalJquery(),
109 | globalRegenerator(),
110 | generateIndexHtml({minify: ENV === 'production'}),
111 |
112 | ...(ENV === 'production' || ENV === 'development' ? [
113 | commonChunksOptimize({appChunkName: 'app', firstChunk: 'aurelia-bootstrap'}),
114 | //copyFiles({patterns: [{ from: 'init.js', to: 'init.js' }, { from: 'plugin.info', to: 'plugin.info' }]})
115 | ] : [
116 | /* ENV === 'test' */
117 | generateCoverage({ options: { 'force-sourcemap': true, esModules: true }})
118 | ]),
119 |
120 | ENV === 'production' ?
121 | uglify({debug: false, mangle: { except: ['cb', '__webpack_require__'] }}) : {}
122 | )
123 |
124 | module.exports = stripMetadata(config)
125 |
--------------------------------------------------------------------------------