<commit_before>/**
 * Shopware 4
 * Copyright © shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */

/**
 * Shopware UI - Media Manager Thumbnail Controller
 *
 * The thumbnail controller handles the thumbnail main window,
 * its elements and the batch calls for the thumbnail generation.
 *
 * @category    Shopware
 * @package     MediaManager
 * @copyright   Copyright (c) shopware AG (http://www.shopware.de)
 */

//{namespace name="backend/swag_import_export/view/main"}
//{block name="backend/swag_import_export/controller/import"}
Ext.define('Shopware.apps.SwagImportExport.controller.Import', {
    extend: 'Ext.app.Controller',
    snippets: {
        window: '{s name=swag_import_export/import/window_title}Import window{/s}',
        finished: '{s name=swag_import_export/import/finished}Importing finished successfully {/s}',
        process: '{s name=swag_import_export/import/process}Importing... {/s}',
        start: '{s name=swag_import_export/import/start}Start importing{/s}',
        close: '{s name=swag_import_export/import/close}Close{/s}'
    },
    /**
     * This method creates listener for events fired from the import
     */
    init: function() {
        var me = this;

        me.control({
            // Import button
            'swag-import-export-manager-import button[action=swag-import-export-manager-import-button]': {
                click: me.onImport
            },
            'swag-import-export-manager-window-import': {
                startProcess: me.onStartProcess,
                cancelProcess: me.onCancelProcess
            },
            'swag-import-export-manager-operation': {
                resumeImport: me.onResume
            },
            'swag-import-export-manager-import html5fileupload': {
                uploadReady: me.onReload
            }
        });

        me.callParent(arguments);
    },
    /**
     * Triggers when the file is uploaded via drag and drop
     *
     * @param [object] target
     */
    onReload: function(target){
        var me = this,
            response = Ext.decode(target.responseText);

        if (response.success === false) {
            return;
        }

        var path = response.data.path;

        me.setFilePath(path);
    },
    /**
     *
     * @param object btn
     * @param object Ext.button.Button btn
     */
    onImport: function(btn) {
        var me = this,
                form = btn.up('form').getForm(),
                values = form.getValues();

        if (Ext.isEmpty(values.profile))
        {
            Shopware.Notification.createGrowlMessage(
                    '{s name=swag_import_export/import/error_title}Swag import export{/s}',
                    '{s name=swag_import_export/import/error_msg_profle}Please select a profile{/s}'
            );
            return;
        }

        var localFile = Ext.getCmp('importSelectFile').getValue();

        if (!Ext.isEmpty(values.importFile) && Ext.isEmpty(localFile))
        {
            me.parameters = values;

            me.onCreateImportWindow();
            return;
        }

        if (!Ext.isEmpty(localFile)){

            form.submit({
                url: '{url module=backend controller="swagImportExport" action="uploadFile"}',
                waitMsg: 'Uploading',
                success: function(fp, response) {
                    me.setFilePath(response.result.data.path);
                    me.parameters = btn.up('form').getForm().getValues();
                    me.onCreateImportWindow();
                },
                failure: function(fp, response) {
                    //todo: handle the failure
                    console.log(response);
                }
            });
        } else {
            Shopware.Notification.createGrowlMessage(
                    '{s name=swag_import_export/import/error_title}Swag import export{/s}',
                    '{s name=swag_import_export/import/error_msg_file}No file was selected{/s}'
            );
            return;
        }
    },
    /**
     * Creates batch configuration
     */
    onCreateImportWindow: function() {
        var me = this;

        me.getBatchConfig = me.getConfig();

    },
    onResume: function(record, sessionStore) {
        var me = this;

        me.parameters = {
            sessionId: record.get('id'),
            profile: record.get('profileId'),
            importFile: record.get('fileName'),
            format: record.get('format')
        };

        me.sessionStore = sessionStore;

        me.getConfig();

    },
    /**
     * Triggers if the start exporting button was pressed
     * in the export window.
     *
     * @param object Enlight.app.SubWindow win
     * @param object Ext.button.Button btn
     */
    onStartProcess: function(win, btn) {
        var me = this;

        me.cancelOperation = false;

        me.runRequest(win);

        btn.hide();
        win.cancelButton.show();
//        win.closeButton.disable();
    },
    /**
     * Returns the needed configuration for the next batch call
     */
    getConfig: function() {
        var me = this;

        me.batchConfig = {
            requestUrl: '{url controller="SwagImportExport" action="import"}',
            action: 'close-window-import',
            params: {
                profileId: me.parameters.profile,
                sessionId: me.parameters.sessionId,
                importFile: me.parameters.importFile
            },
            snippets: me.snippets
        };

        Ext.Ajax.request({
            url: '{url controller="SwagImportExport" action="prepareImport"}',
            method: 'POST',
            params: me.batchConfig.params,
            success: function(response) {
                var result = Ext.decode(response.responseText);

                if(result.success === false){
                    Shopware.Msg.createStickyGrowlMessage({
                        title: 'Import Error',
                        text: result.msg
                    });
                    var mask = Ext.get(Ext.getBody().query('.x-mask'));
                    mask.hide();
                    return;
                }

                me.batchConfig.position = result.position;
                me.batchConfig.totalCount = result.count;
                me.batchConfig.snippet = me.snippets.process + me.batchConfig.position + ' / ' + me.batchConfig.totalCount;
                me.batchConfig.progress = me.batchConfig.position / me.batchConfig.totalCount;

                me.window = me.getView('Shopware.apps.SwagImportExport.view.manager.window.Import').create({
                    batchConfig: me.batchConfig
                }).show();

            },
            failure: function(response) {
                Shopware.Msg.createStickyGrowlMessage({
                    title: 'An error occured',
                    text: "The server could not handle the request."
                });
            }
        });
    },
    setFilePath: function(path){
        var fileField = Ext.getCmp('swag-import-export-file');
        fileField.setValue(path);
    },
    /**
     * This function sends a request to export data
     *
     * @param object Enlight.app.SubWindow win
     */
    runRequest: function(win) {
        var me = this,
                config = me.batchConfig,
                params = config.params;

        // if cancel button was pressed
        if (me.cancelOperation) {
            win.closeButton.enable();
            return;
        }

        Ext.Ajax.request({
            url: config.requestUrl,
            method: 'POST',
            params: params,
            timeout: 4000000,
            success: function(response) {
                var result = Ext.decode(response.responseText);

                if(result.success == false){
                    Shopware.Msg.createStickyGrowlMessage({
                        title: 'Import Error',
                        text: result.msg
                    });
                    return;
                }

                me.batchConfig.params = result.data;
                me.batchConfig.position = result.data.position;

                win.importProgress.updateProgress(
                        me.batchConfig.position / me.batchConfig.totalCount,
                        me.snippets.process + me.batchConfig.position + ' / ' + me.batchConfig.totalCount,
                        true
                        );

                if (me.batchConfig.position === me.batchConfig.totalCount) {
                    me.onProcessFinish(win);
                } else {
                    me.runRequest(win);
                }

            },
            failure: function(response) {
                Shopware.Msg.createStickyGrowlMessage({
                    title: 'An error occured',
                    text: "The server could not handle the request."
                });

                me.onProcessFinish(win);
            }
        });
    },
    /**
     * Sets cancelOperation to true which will be checked in the
     * next batch call and will stop.
     *
     * @param btn
     */
    onCancelProcess: function(btn) {
        var me = this;

        btn.disable();

        me.cancelOperation = true;
    },
    /**
     * Will be called when export finish
     *
     * @param object Enlight.app.SubWindow win
     */
    onProcessFinish: function(win) {
        var me = this;

        win.closeButton.enable();
        win.cancelButton.disable();
        win.importProgress.updateText(me.snippets.finished + me.batchConfig.position + ' / ' + me.batchConfig.totalCount);
    }

});
//{/block}<commit_msg>SWEX-122 Fixed showing error msg on upload<commit_after>/**
 * Shopware 4
 * Copyright © shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */

/**
 * Shopware UI - Media Manager Thumbnail Controller
 *
 * The thumbnail controller handles the thumbnail main window,
 * its elements and the batch calls for the thumbnail generation.
 *
 * @category    Shopware
 * @package     MediaManager
 * @copyright   Copyright (c) shopware AG (http://www.shopware.de)
 */

//{namespace name="backend/swag_import_export/view/main"}
//{block name="backend/swag_import_export/controller/import"}
Ext.define('Shopware.apps.SwagImportExport.controller.Import', {
    extend: 'Ext.app.Controller',
    snippets: {
        window: '{s name=swag_import_export/import/window_title}Import window{/s}',
        finished: '{s name=swag_import_export/import/finished}Importing finished successfully {/s}',
        process: '{s name=swag_import_export/import/process}Importing... {/s}',
        start: '{s name=swag_import_export/import/start}Start importing{/s}',
        close: '{s name=swag_import_export/import/close}Close{/s}',
        failure: '{s name=swag_import_export/import/failure-title}An error occured{/s}'
    },
    /**
     * This method creates listener for events fired from the import
     */
    init: function() {
        var me = this;

        me.control({
            // Import button
            'swag-import-export-manager-import button[action=swag-import-export-manager-import-button]': {
                click: me.onImport
            },
            'swag-import-export-manager-window-import': {
                startProcess: me.onStartProcess,
                cancelProcess: me.onCancelProcess
            },
            'swag-import-export-manager-operation': {
                resumeImport: me.onResume
            },
            'swag-import-export-manager-import html5fileupload': {
                uploadReady: me.onReload
            }
        });

        me.callParent(arguments);
    },
    /**
     * Triggers when the file is uploaded via drag and drop
     *
     * @param [object] target
     */
    onReload: function(target){
        var me = this,
            response = Ext.decode(target.responseText);

        if (response.success === false) {
            return;
        }

        var path = response.data.path;

        me.setFilePath(path);
    },
    /**
     *
     * @param object btn
     * @param object Ext.button.Button btn
     */
    onImport: function(btn) {
        var me = this,
                form = btn.up('form').getForm(),
                values = form.getValues();

        if (Ext.isEmpty(values.profile))
        {
            Shopware.Notification.createGrowlMessage(
                    '{s name=swag_import_export/import/error_title}Swag import export{/s}',
                    '{s name=swag_import_export/import/error_msg_profle}Please select a profile{/s}'
            );
            return;
        }

        var localFile = Ext.getCmp('importSelectFile').getValue();

        if (!Ext.isEmpty(values.importFile) && Ext.isEmpty(localFile))
        {
            me.parameters = values;

            me.onCreateImportWindow();
            return;
        }

        if (!Ext.isEmpty(localFile)){
            var me = this;
            form.submit({
                url: '{url module=backend controller="swagImportExport" action="uploadFile"}',
                waitMsg: 'Uploading',
                success: function(fp, response) {
                    me.setFilePath(response.result.data.path);
                    me.parameters = btn.up('form').getForm().getValues();
                    me.onCreateImportWindow();
                },
                failure: function(fp, response) {
                    Shopware.Msg.createStickyGrowlMessage({
                        title: me.snippets.failure,
                        text: response.result.message
                    });
                    var mask = Ext.get(Ext.getBody().query('.x-mask'));
                    mask.hide();
                }
            });
        } else {
            Shopware.Notification.createGrowlMessage(
                    '{s name=swag_import_export/import/error_title}Swag import export{/s}',
                    '{s name=swag_import_export/import/error_msg_file}No file was selected{/s}'
            );
            return;
        }
    },
    /**
     * Creates batch configuration
     */
    onCreateImportWindow: function() {
        var me = this;

        me.getBatchConfig = me.getConfig();

    },
    onResume: function(record, sessionStore) {
        var me = this;

        me.parameters = {
            sessionId: record.get('id'),
            profile: record.get('profileId'),
            importFile: record.get('fileName'),
            format: record.get('format')
        };

        me.sessionStore = sessionStore;

        me.getConfig();

    },
    /**
     * Triggers if the start exporting button was pressed
     * in the export window.
     *
     * @param object Enlight.app.SubWindow win
     * @param object Ext.button.Button btn
     */
    onStartProcess: function(win, btn) {
        var me = this;

        me.cancelOperation = false;

        me.runRequest(win);

        btn.hide();
        win.cancelButton.show();
//        win.closeButton.disable();
    },
    /**
     * Returns the needed configuration for the next batch call
     */
    getConfig: function() {
        var me = this;

        me.batchConfig = {
            requestUrl: '{url controller="SwagImportExport" action="import"}',
            action: 'close-window-import',
            params: {
                profileId: me.parameters.profile,
                sessionId: me.parameters.sessionId,
                importFile: me.parameters.importFile
            },
            snippets: me.snippets
        };

        Ext.Ajax.request({
            url: '{url controller="SwagImportExport" action="prepareImport"}',
            method: 'POST',
            params: me.batchConfig.params,
            success: function(response) {
                var result = Ext.decode(response.responseText);

                if(result.success === false){
                    Shopware.Msg.createStickyGrowlMessage({
                        title: 'Import Error',
                        text: result.msg
                    });
                    var mask = Ext.get(Ext.getBody().query('.x-mask'));
                    mask.hide();
                    return;
                }

                me.batchConfig.position = result.position;
                me.batchConfig.totalCount = result.count;
                me.batchConfig.snippet = me.snippets.process + me.batchConfig.position + ' / ' + me.batchConfig.totalCount;
                me.batchConfig.progress = me.batchConfig.position / me.batchConfig.totalCount;

                me.window = me.getView('Shopware.apps.SwagImportExport.view.manager.window.Import').create({
                    batchConfig: me.batchConfig
                }).show();

            },
            failure: function(response) {
                Shopware.Msg.createStickyGrowlMessage({
                    title: 'An error occured',
                    text: "The server could not handle the request."
                });
            }
        });
    },
    setFilePath: function(path){
        var fileField = Ext.getCmp('swag-import-export-file');
        fileField.setValue(path);
    },
    /**
     * This function sends a request to export data
     *
     * @param object Enlight.app.SubWindow win
     */
    runRequest: function(win) {
        var me = this,
                config = me.batchConfig,
                params = config.params;

        // if cancel button was pressed
        if (me.cancelOperation) {
            win.closeButton.enable();
            return;
        }

        Ext.Ajax.request({
            url: config.requestUrl,
            method: 'POST',
            params: params,
            timeout: 4000000,
            success: function(response) {
                var result = Ext.decode(response.responseText);

                if(result.success == false){
                    Shopware.Msg.createStickyGrowlMessage({
                        title: 'Import Error',
                        text: result.msg
                    });
                    return;
                }

                me.batchConfig.params = result.data;
                me.batchConfig.position = result.data.position;

                win.importProgress.updateProgress(
                        me.batchConfig.position / me.batchConfig.totalCount,
                        me.snippets.process + me.batchConfig.position + ' / ' + me.batchConfig.totalCount,
                        true
                        );

                if (me.batchConfig.position === me.batchConfig.totalCount) {
                    me.onProcessFinish(win);
                } else {
                    me.runRequest(win);
                }

            },
            failure: function(response) {
                Shopware.Msg.createStickyGrowlMessage({
                    title: 'An error occured',
                    text: "The server could not handle the request."
                });

                me.onProcessFinish(win);
            }
        });
    },
    /**
     * Sets cancelOperation to true which will be checked in the
     * next batch call and will stop.
     *
     * @param btn
     */
    onCancelProcess: function(btn) {
        var me = this;

        btn.disable();

        me.cancelOperation = true;
    },
    /**
     * Will be called when export finish
     *
     * @param object Enlight.app.SubWindow win
     */
    onProcessFinish: function(win) {
        var me = this;

        win.closeButton.enable();
        win.cancelButton.disable();
        win.importProgress.updateText(me.snippets.finished + me.batchConfig.position + ' / ' + me.batchConfig.totalCount);
    }

});
//{/block}<|endoftext|>


<commit_before>/*
 * grunt-split-styles
 *
 * Copyright (c) 2014 Dan Bissonnet
 * Licensed under the MIT license.
 */

'use strict';
var postcss = require('postcss');

module.exports = function(grunt) {
	grunt.registerMultiTask('split_styles', 'Split a CSS file based on selectors.', function() {
		// Merge task-specific and/or target-specific options with these defaults.
		var options = this.options({
			pattern: {
				match: false, // The RegExp to match selectors with
				matchParent: false // Should child declarations (eg. in @media blocks) include their parent node.
			},
			remove: true, // Should we strip the matched rules from the src style sheet?
			mediaPattern: false, // RegExp to match @media rules with
			mediaPatternUnwrap: false, // Extract the rules from a matched @media block
		});

		var pattern = {};
		var newCSS = postcss.root();

		if ( options.pattern instanceof RegExp ) {
			pattern.match = options.pattern;
			pattern.matchParent = false;
		} else {
			pattern = options.pattern;
		}

		// Our postCSS processor
		var processor = postcss(function (css) {
			if ( pattern.match ) {
				css.eachRule(function (rule) {
						var parent;

						if ( rule.selector.match(pattern.match) ) {
								if ( options.remove ) {
									rule.removeSelf();
								}

								if ( pattern.matchParent ) {
									parent = rule.parent.clone();

									if ( 'media' === parent.name ) {
										parent.eachRule(function (childRule) {
											childRule.removeSelf();
										});

										parent.append(rule);
										newCSS.append(parent);
									}
								} else {
									newCSS.append(rule);
								}
						}
				});
			}

			if (options.mediaPattern) {
				css.eachAtRule(function (atRule) {
					if ( 'media' === atRule.name && atRule.params.match(options.mediaPattern) ) {

						if ( options.remove ) {
							atRule.removeSelf();
						}

						if ( options.mediaPatternUnwrap ) {
							atRule.eachRule(function (rule) {
								newCSS.append(rule);
							});
						} else {
							newCSS.append(atRule);
						}
					}
				});
			}
		});

		// Iterate over all specified file groups.
		this.files.forEach(function(f) {
			var src = f.src.filter(function(filepath) {
				// Warn on and remove invalid source files (if nonull was set).
				if (!grunt.file.exists(filepath)) {
					grunt.log.warn('Source file "' + filepath + '" not found.');
					return false;
				} else {
					return true;
				}
			}).map(function(filepath) {
				// Read file source.
				var css =  grunt.file.read(filepath),
						processOptions = {},
						output;

				processOptions.from = filepath;
				processOptions.to = f.dest;

				// Run the postprocessor
				output = processor.process(css, processOptions);

				if ( output.map && output.map.length > 0 ) {
					grunt.log.writeln('Sourcemap "' + options.output + '" created.');
					grunt.file.write( f.dest + '.map' , output.map);
				}

				return output.css;
			});

			// Write the newly split file.
			grunt.file.write(options.output, newCSS);

			// Write the destination file
			grunt.file.write(f.dest, src);

			// Print a success message.
			grunt.log.writeln('File "' + options.output + '" created.');
			grunt.log.writeln('File "' + f.dest + '" created.');
		});
	});
};
<commit_msg>Make 'output' optional and fix 'matchParent' option ignoring rules with no parent<commit_after>/*
 * grunt-split-styles
 *
 * Copyright (c) 2014 Dan Bissonnet
 * Licensed under the MIT license.
 */

'use strict';
var postcss = require('postcss');

module.exports = function(grunt) {
	grunt.registerMultiTask('split_styles', 'Split a CSS file based on selectors.', function() {
		// Merge task-specific and/or target-specific options with these defaults.
		var options = this.options({
			pattern: {
				match: false, // The RegExp to match selectors with
				matchParent: false // Should child declarations (eg. in @media blocks) include their parent node.
			},
			remove: true, // Should we strip the matched rules from the src style sheet?
			mediaPattern: false, // RegExp to match @media rules with
			mediaPatternUnwrap: false, // Extract the rules from a matched @media block
		});

		var pattern = {};
		var newCSS = postcss.root();

		if ( options.pattern instanceof RegExp ) {
			pattern.match = options.pattern;
			pattern.matchParent = false;
		} else {
			pattern = options.pattern;
		}

		// Our postCSS processor
		var processor = postcss(function (css) {
			if ( pattern.match ) {
				css.eachRule(function (rule) {
						var parent;

						if ( rule.selector.match(pattern.match) ) {
								if ( options.remove ) {
									rule.removeSelf();
								}

								if ( pattern.matchParent ) {
									parent = rule.parent.clone();

									if ( 'media' === parent.name ) {
										parent.eachRule(function (childRule) {
											childRule.removeSelf();
										});

										parent.append(rule);
										newCSS.append(parent);
									} else {
										newCSS.append(rule);
									}
								} else {
									newCSS.append(rule);
								}
						}
				});
			}

			if (options.mediaPattern) {
				css.eachAtRule(function (atRule) {
					if ( 'media' === atRule.name && atRule.params.match(options.mediaPattern) ) {

						if ( options.remove ) {
							atRule.removeSelf();
						}

						if ( options.mediaPatternUnwrap ) {
							atRule.eachRule(function (rule) {
								newCSS.append(rule);
							});
						} else {
							newCSS.append(atRule);
						}
					}
				});
			}
		});

		// Iterate over all specified file groups.
		this.files.forEach(function(f) {
			var src = f.src.filter(function(filepath) {
				// Warn on and remove invalid source files (if nonull was set).
				if (!grunt.file.exists(filepath)) {
					grunt.log.warn('Source file "' + filepath + '" not found.');
					return false;
				} else {
					return true;
				}
			}).map(function(filepath) {
				// Read file source.
				var css =  grunt.file.read(filepath),
						processOptions = {},
						output;

				processOptions.from = filepath;
				processOptions.to = f.dest;

				// Run the postprocessor
				output = processor.process(css, processOptions);

				if ( options.output && output.map && output.map.length > 0 ) {
					grunt.log.writeln('Sourcemap "' + options.output + '" created.');
					grunt.file.write( f.dest + '.map' , output.map);
				}

				return output.css;
			});

			// Write the newly split file.
			if(options.output) {
				grunt.file.write(options.output, newCSS);
			}

			// Write the destination file
			grunt.file.write(f.dest, src);

			// Print a success message.
			if(options.output) {
				grunt.log.writeln('File "' + options.output + '" created.');
			}
			grunt.log.writeln('File "' + f.dest + '" created.');
		});
	});
};
<|endoftext|>


<commit_before>import React from 'react'
import { Route } from 'react-router-dom'

// Pages
import WidgetsDonationRoutes from '~root/routes-v1/subroutes/widgets-donation'

export default ({ match: { path } }) => (
  <React.Fragment>
    <Route path={`${path}/:widget_id/donation`} component={WidgetsDonationRoutes} />
  </React.Fragment>
)
<commit_msg>chore(routes-v1): save current widget id on widgets route node<commit_after>import React from 'react'
import { connect } from 'react-redux'
import { Route } from 'react-router-dom'

// Components
import { Loading } from '~client/components/await'

// Redux
import { selectWidget } from '~client/mobrender/redux/action-creators'
import MobSelectors from '~client/mobrender/redux/selectors'

// Pages
import WidgetsDonationRoutes from '~root/routes-v1/subroutes/widgets-donation'

const stateToProps = state => ({
  widget: MobSelectors(state).getWidget()
})

const actionsToProps = {
  select: selectWidget
}

export default connect(stateToProps, actionsToProps)(class extends React.Component {
  componentDidMount () {
    const {
      widget,
      select,
      match: { params: { widget_id: id } }
    } = this.props

    if (!widget && id) {
      return Promise.all([select(id)])
    }
  }

  render () {
    const { match: { path }, widget } = this.props

    return !widget ? <Loading /> : (
      <React.Fragment>
        <Route path={`${path}/donation`} component={WidgetsDonationRoutes} />
      </React.Fragment>
    )
  }
})
<|endoftext|>


<commit_before>
;//工具和扩展
(function($){
	/**
	*	模拟下拉框选择，格式如下：
	*

    *
用户名

    *
邮箱

    *
炫ID

    *

    *	目标数据存储：
	*   <input type="hidden" name="select" value="userName" id="target"/>
	*	事件触发和数据显示：
	*	用户名
	*/
	$.fn.selectM = function(list,target){
		var $list = $(list),$this = this;
		$(document).on("click",function(e){
			if( e.target !== $this[0] ){
				$list.hide();
			}
		});
		$(this).on("click",function(){
			$list.toggle();
		});
		$("a[data-value]",$list).on("click",function(){
			$(target).val( $(this).attr("data-value") );
			$this.html($(this).html());
			$list.hide();
		});
	};
})(jQuery);

//页面事件绑定。
(function($){
	//随机背景图：
	$("#loginbg").attr({"src":"http://tmisc.home.news.cn/login/images/loginbg" + ( parseInt(Math.random()*7) + 1 )+".png"});

	//刷新验证码：
	$("#change_register_identify,.identify-change").on("click",function(){
		$("#identify").attr({ "src":"http://login.home.news.cn/captcha.do?random=" + Math.random() }); //验证码保持动态刷新
        $("#register_identify").attr({ "src":"http://login.home.news.cn/rcaptcha.do?random=" + Math.random() }); //验证码保持动态刷新
	}).trigger("click");

	//注册页弹出：
	$("#login-register,#passer").on("click",function(){
		$("#xuan-register").fadeIn();
		//$("#xuan-register :text").filter(":visible").val("");
	});
	//注册页关闭：
	$("#register-cancel").on("click",function(){
		$("#xuan-register").hide();
	});

	//账号类型选择:
	$("#account-bid").selectM("#account-list","#selectOpt");

	var ajax_id = function(nic){
		$("#getXuanID").css({color:"#ccc",cursor:"default"}).off();
		if( $("#register_name").is(":disabled") )return;
		$.ajax({
			url : "/profile/xuanid.do?",
			data: {o:$("[name='o']").val()},
			dataType:"json",
			success:function(data){
				if(200==data.code){
					$("#register_name").val(data.desc).trigger("blur").attr({disabled:true});
					$("[name='hrn']").val(data.desc);
					if(nic){$("#nick_name").val( $("[name='hrn']").val() );}
				}else{
					alert(data.desc);
				}
			}
		});
	};
	//获取系统提供的炫ID
	$("#getXuanID").one("click",function(){
		ajax_id();
	});

	//以炫ID作为昵称:
	$("#niccXuanID").on("click",function(){
		ajax_id(true);
		$("#nick_name").val( $("[name='hrn']").val()).blur();
	});

})(jQuery);

//表单相关
(function($){
	var agent = "/agent?";

	//统一的表单提示
	$.form.settings = {
		initTip: function(input, defaultTip) {
            input.next(".tips")
                .html(defaultTip || " ");
        },
        validTip: function(input, errorInfo, defaultTip) {
            if (errorInfo) {
                input.next(".tips")
                    .removeClass('ok')
                    .addClass("err")
                    .html(errorInfo);
            } else {
                input.next(".tips")
                    .removeClass('err')
                    .addClass("ok")
                    .html(defaultTip || " ");
            }
        }
    };

    //输入框的聚焦提示
    $("#xuan-register input").on("focus",function(){
    	$(this).next(".tips").attr({"class":"tips"})
                    .html( $(this).validAttr("defaultTip") || " " );
    });

    var lowcase = function(input){
    	var val = input.val().toLowerCase();
		input.val( val );
		return val;
	};

    //验证参数绑定
    $.form.render({
    	//注册字段校验
    	"#register_name":{
    		before:lowcase,
    		defaultTip:"登录账号由英文和数字组成6-26位。",
    		errorTip:"登录账号由英文和数字组成6-26位。",
    		regexp:/^\w{6,26}$/,
    		validFun:function(v){
    			var vR = {errorInfo:""};
    			$.ajax({
    				url: agent+"http://login.home.news.cn//profile/passportCheck.do?",
    				data:{name:"userName",value:v,type:"json",t:new Date().getTime()},
    				dataType:"json",
    				success:function(data){
    					if(data.code == 1101){
	    					vR.errorInfo = data.desc;
    					}
    				},
    				async:false
    			});
    			return vR;
    		}
    	},
    	"#nick_name":{
    		defaultTip:"请输入昵称",
    		errorTip:"请输入昵称",
    		validFun:function(v){
    			var vR = {errorInfo:""};
    			$.ajax({
    				url: agent+"http://login.home.news.cn//profile/passportCheck.do?",
    				data:{name:"nickName",value:v,type:"json",t:new Date().getTime()},
    				dataType:"json",
    				success:function(data){
    					if(data.code == 1101){
	    					vR.errorInfo = data.desc;
	    					var html='推荐您选用以下昵称
';
                            var newNickName;
                            for(i=0;i<data.nnList.length;i++){
                                newNickName = v+data.nnList[i];
                                html+='
<input type="radio" id="nn'+i+'" name="nnList" value="'+newNickName+'"> '+newNickName+'
';
                            }
                            html+="
";
                            $("#nnListDiv").html(html);
                            $("#xuan-register").height(660);
    					}
    				},
    				async:false
    			});
    			return vR;
    		}
    	},
		"#register_pass":{
			defaultTip:"6到16个字符,不能全为字母或数字。",
			lenTip:"需要6到16个字符。",
			errorTip:"密码不能全为字母或数字。",
			minlen:6,
			maxlen:16,
			regexp:/[^A-Za-z0-9]+/,
			option:"keyup blur"
		},
		"#register_pass1":{
			defaultTip:"再次输入你设置的密码。",
			validFun:function(v){
				var vR = {errorInfo:""};
				if( v != $("#register_pass").val() ){
					vR.errorInfo = "两次密码输入不一致!";
				}
				return vR;
			}
		},
		"#register_email":{
			defaultTip:"用于召回密码等服务。",
			errorTip:"邮箱格式不正确",
			type:"email",
			validFun:function(v){
				var vR = {errorInfo:""};
    			$.ajax({
    				url: agent+"http://login.home.news.cn//profile/passportCheck.do?",
    				data:{name:"email",value:v,type:"json",t:new Date().getTime()},
    				dataType:"json",
    				success:function(data){
    					if(data.code == 1101){
	    					vR.errorInfo = data.desc;
    					}
    				},
    				async:false
    			});
    			return vR;
			}
		},
		"#agree_input":{
			option:"click",
			end:function(input){
				if( !input.attr("checked") ){
					input.vReturn = "需要同意新华网协议才能注册。"
					alert("需要同意新华网协议才能注册。");
				}
			}
		},
		"#register_code":{
			defaultTip: "正确输入验证码。",
			errorTip: "正确输入验证码。",
			regexp:/^[A-Za-z0-9]{4,5}$/
		},

		//登录字段校验
		"#user_name":{
			before:lowcase,
			option:"valid",
			requiredTip:"用户名需要填写!",
    		regexp:/^\w{4,26}$/,
    		errorTip:"登录账号由英文和数字组成6-26位"
		},
		"#pass":{
			option:"valid",
			requiredTip:"密码需要填写!"
		},
		"#code":{
			option:"valid",
			requiredTip:"验证码需要填写!",
			regexp: /^[A-Za-z0-9]{4,5}$/,
			errorTip:"请输入正确的验证码"
		}
    },{
    	required:true,
    	option:"blur"
    });

	//绑定注册表单的批量验证
	$("#register-form").on("submit",function(){
		return $(this).formValid("input");
	});

	//绑定登录表单的批量验证
	$("#login-form").on("submit",function(){
		return $(this).formValid(":visible",{
			interrupt:true 	//遇到第一个错误即停止继续
		},{
			validTip:function(input,vReturn){
				if(vReturn){
					alert(vReturn);
				}
			}
		});
	});

	//点选系统推荐的昵称：
	$("#nnListDiv").delegate(":radio","click",function(e){
		$("#nick_name").val(this.value);
	});

	$(function(){
		if(location.hash=="#register"){
            $("#xuan-register").show();
            $("#register_name").focus();
        }
	})

})(jQuery);<commit_msg>Signed-off-by: shy2850 <shy2850@163.com><commit_after>
;//工具和扩展
(function($){
	/**
	*	模拟下拉框选择，格式如下：
	*

    *
用户名

    *
邮箱

    *
炫ID

    *

    *	目标数据存储：
	*   <input type="hidden" name="select" value="userName" id="target"/>
	*	事件触发和数据显示：
	*	用户名
	*/
	$.fn.selectM = function(list,target){
		var $list = $(list),$this = this;
		$(document).on("click",function(e){
			if( e.target !== $this[0] ){
				$list.hide();
			}
		});
		$(this).on("click",function(){
			$list.toggle();
		});
		$("a[data-value]",$list).on("click",function(){
			$(target).val( $(this).attr("data-value") );
			$this.html($(this).html());
			$list.hide();
		});
	};
})(jQuery);

//页面事件绑定。
(function($){
	//随机背景图：
	$("#loginbg").attr({"src":"http://tmisc.home.news.cn/login/images/loginbg" + ( parseInt(Math.random()*7) + 1 )+".png"});

	//刷新验证码：
	$("#change_register_identify,.identify-change").on("click",function(){
		$("#identify").attr({ "src":"http://login.home.news.cn/captcha.do?random=" + Math.random() }); //验证码保持动态刷新
        $("#register_identify").attr({ "src":"http://login.home.news.cn/rcaptcha.do?random=" + Math.random() }); //验证码保持动态刷新
	}).trigger("click");

	//注册页弹出：
	$("#login-register,#passer").on("click",function(){
		$("#xuan-register").fadeIn();
		//$("#xuan-register :text").filter(":visible").val("");
	});
	//注册页关闭：
	$("#register-cancel").on("click",function(){
		$("#xuan-register").hide();
	});

	//账号类型选择:
	$("#account-bid").selectM("#account-list","#selectOpt");

	var ajax_id = function(nic){
		$("#getXuanID").css({color:"#ccc",cursor:"default"}).off();
		if( $("#register_name").is(":disabled") )return;
		$.ajax({
			url : "/agent?http://login.home.news.cn/profile/xuanid.do?",
			data: {o:$("[name='o']").val()},
			dataType:"json",
			success:function(data){
				if(200==data.code){
					$("#register_name").val(data.desc).trigger("blur").attr({disabled:true});
					$("[name='hrn']").val(data.desc);
					if(nic){$("#nick_name").val( $("[name='hrn']").val() );}
				}else{
					alert(data.desc);
				}
			}
		});
	};
	//获取系统提供的炫ID
	$("#getXuanID").one("click",function(){
		ajax_id();
	});

	//以炫ID作为昵称:
	$("#niccXuanID").on("click",function(){
		ajax_id(true);
		$("#nick_name").val( $("[name='hrn']").val()).blur();
	});

})(jQuery);

//表单相关
(function($){
	var agent = "/agent?";

	//统一的表单提示
	$.form.settings = {
		initTip: function(input, defaultTip) {
            input.next(".tips")
                .html(defaultTip || " ");
        },
        validTip: function(input, errorInfo, defaultTip) {
            if (errorInfo) {
                input.next(".tips")
                    .removeClass('ok')
                    .addClass("err")
                    .html(errorInfo);
            } else {
                input.next(".tips")
                    .removeClass('err')
                    .addClass("ok")
                    .html(defaultTip || " ");
            }
        }
    };

    //输入框的聚焦提示
    $("#xuan-register input").on("focus",function(){
    	$(this).next(".tips").attr({"class":"tips"})
                    .html( $(this).validAttr("defaultTip") || " " );
    });

    var lowcase = function(input){
    	var val = input.val().toLowerCase();
		input.val( val );
		return val;
	};

    //验证参数绑定
    $.form.render({
    	//注册字段校验
    	"#register_name":{
    		before:lowcase,
    		defaultTip:"登录账号由英文和数字组成6-26位。",
    		errorTip:"登录账号由英文和数字组成6-26位。",
    		regexp:/^\w{6,26}$/,
    		validFun:function(v){
    			var vR = {errorInfo:""};
    			$.ajax({
    				url: agent+"http://login.home.news.cn/profile/passportCheck.do?",
    				data:{name:"userName",value:v,type:"json",t:new Date().getTime()},
    				dataType:"json",
    				success:function(data){
    					if(data.code == 1101){
	    					vR.errorInfo = data.desc;
    					}
    				},
    				async:false
    			});
    			return vR;
    		}
    	},
    	"#nick_name":{
    		defaultTip:"请输入昵称",
    		errorTip:"请输入昵称",
    		validFun:function(v){
    			var vR = {errorInfo:""};
    			$.ajax({
    				url: agent+"http://login.home.news.cn/profile/passportCheck.do?",
    				data:{name:"nickName",value:v,type:"json",t:new Date().getTime()},
    				dataType:"json",
    				success:function(data){
    					if(data.code == 1101){
	    					vR.errorInfo = data.desc;
	    					var html='推荐您选用以下昵称
';
                            var newNickName;
                            for(i=0;i<data.nnList.length;i++){
                                newNickName = v+data.nnList[i];
                                html+='
<input type="radio" id="nn'+i+'" name="nnList" value="'+newNickName+'"> '+newNickName+'
';
                            }
                            html+="
";
                            $("#nnListDiv").html(html);
                            $("#xuan-register").height(660);
    					}
    				},
    				async:false
    			});
    			return vR;
    		}
    	},
		"#register_pass":{
			defaultTip:"6到16个字符,不能全为字母或数字。",
			lenTip:"需要6到16个字符。",
			errorTip:"密码不能全为字母或数字。",
			minlen:6,
			maxlen:16,
			regexp:/[^A-Za-z0-9]+/,
			option:"keyup blur"
		},
		"#register_pass1":{
			defaultTip:"再次输入你设置的密码。",
			validFun:function(v){
				var vR = {errorInfo:""};
				if( v != $("#register_pass").val() ){
					vR.errorInfo = "两次密码输入不一致!";
				}
				return vR;
			}
		},
		"#register_email":{
			defaultTip:"用于召回密码等服务。",
			errorTip:"邮箱格式不正确",
			type:"email",
			validFun:function(v){
				var vR = {errorInfo:""};
    			$.ajax({
    				url: agent+"http://login.home.news.cn//profile/passportCheck.do?",
    				data:{name:"email",value:v,type:"json",t:new Date().getTime()},
    				dataType:"json",
    				success:function(data){
    					if(data.code == 1101){
	    					vR.errorInfo = data.desc;
    					}
    				},
    				async:false
    			});
    			return vR;
			}
		},
		"#agree_input":{
			option:"click",
			end:function(input){
				if( !input.attr("checked") ){
					input.vReturn = "需要同意新华网协议才能注册。"
					alert("需要同意新华网协议才能注册。");
				}
			}
		},
		"#register_code":{
			defaultTip: "正确输入验证码。",
			errorTip: "正确输入验证码。",
			regexp:/^[A-Za-z0-9]{4,5}$/
		},

		//登录字段校验
		"#user_name":{
			before:lowcase,
			option:"valid",
			requiredTip:"用户名需要填写!",
    		regexp:/^\w{4,26}$/,
    		errorTip:"登录账号由英文和数字组成6-26位"
		},
		"#pass":{
			option:"valid",
			requiredTip:"密码需要填写!"
		},
		"#code":{
			option:"valid",
			requiredTip:"验证码需要填写!",
			regexp: /^[A-Za-z0-9]{4,5}$/,
			errorTip:"请输入正确的验证码"
		}
    },{
    	required:true,
    	option:"blur"
    });

	//绑定注册表单的批量验证
	$("#register-form").on("submit",function(){
		return $(this).formValid("input");
	});

	//绑定登录表单的批量验证
	$("#login-form").on("submit",function(){
		return $(this).formValid(":visible",{
			interrupt:true 	//遇到第一个错误即停止继续
		},{
			validTip:function(input,vReturn){
				if(vReturn){
					alert(vReturn);
				}
			}
		});
	});

	//点选系统推荐的昵称：
	$("#nnListDiv").delegate(":radio","click",function(e){
		$("#nick_name").val(this.value);
	});

	$(function(){
		if(location.hash=="#register"){
            $("#xuan-register").show();
            $("#register_name").focus();
        }
	})

})(jQuery);<|endoftext|>


<commit_before>/**
 * User Input Keywords.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import classnames from 'classnames';

/**
 * WordPress dependencies
 */
import { useCallback, useRef, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { ENTER, BACKSPACE } from '@wordpress/keycodes';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { Cell, Input, TextField } from '../../material-components';
import Button from '../Button';
import CloseIcon from '../../../svg/close.svg';
import { COMMA } from '../../util/key-codes';
import VisuallyHiden from '../VisuallyHidden';
const { useSelect, useDispatch } = Data;

export default function UserInputKeywords( { slug, max } ) {
	const keywordsContainer = useRef();
	const [ canDeleteKeyword, setCanDeleteKeyword ] = useState( false );

	const values = useSelect( ( select ) => select( CORE_USER ).getUserInputSetting( slug ) || [] );
	const { setUserInputSetting } = useDispatch( CORE_USER );

	// Add an empty string if the values array is empty.
	if ( values.length === 0 ) {
		values.push( '' );
	}

	// Need to make sure that dependencies list always has the same number of elements.
	const dependencies = values.concat( Array( max ) ).slice( 0, max );

	const updateKeywords = useCallback( ( keywords ) => {
		const EOT = String.fromCharCode( 4 );
		let newKeywords = keywords
			// Trim keywords to allow no empty spaces at the beginning and at max one space at the end.
			.map( ( keyword ) => keyword.replace( /(\S)\s+$/, '$1 ' ).replace( /^\s+/, '' ) )
			// EOT is added to the end to properly combine two sequential empty spaces at the end.
			.concat( [ '', EOT ] )
			.join( EOT )
			.replace( new RegExp( `${ EOT }{3,}`, 'g' ), EOT ); // Combine two sequential empty spaces into one.

		if ( newKeywords === EOT ) {
			newKeywords = [ '' ];
		} else {
			newKeywords = newKeywords.split( EOT ).slice( 0, max );
		}

		setUserInputSetting( slug, newKeywords );
	}, [ slug ] );

	const onKeywordChange = useCallback( ( index, { target } ) => {
		if ( target.value[ target.value.length - 1 ] === ',' ) {
			return;
		}

		updateKeywords( [
			...values.slice( 0, index ),
			target.value,
			...values.slice( index + 1 ),
		] );
	}, dependencies );

	const onKeyDown = useCallback( ( index, { keyCode, target } ) => {
		const nonEmptyValues = values.filter( ( value ) => value.length > 0 );
		const nonEmptyValuesLength = nonEmptyValues.length;

		if ( ( keyCode === ENTER || keyCode === COMMA ) && nonEmptyValues.length < max ) {
			updateKeywords( [
				...values.slice( 0, index + 1 ),
				'',
				...values.slice( index + 1 ),
			] );

			setCanDeleteKeyword( true ); // New keyword has been added, so hitting backspace now will remove it
			setTimeout( () =>
				focusInput( `#${ slug }-keyword-${ index + 1 }` )
			, 50 );
		}

		if ( keyCode === BACKSPACE && canDeleteKeyword ) {
			deleteKeyword( nonEmptyValuesLength - 1 );
			setTimeout( () =>
				focusInput( `#${ slug }-keyword-${ nonEmptyValuesLength - 1 }` )
			, 50 );
		}

		if ( target.value.length <= 1 && keyCode === BACKSPACE ) {
			// user deleted the only character, or just landed in this input after
			// deleting a keyword so hitting backspace again should delete the previous keyword
			setCanDeleteKeyword( true );
		} else {
			// user is typing, so backspace should delete the last character
			setCanDeleteKeyword( false );
		}
	}, [ keywordsContainer.current, ...dependencies, canDeleteKeyword ] );

	const focusInput = ( querySelector ) => {
		const input = keywordsContainer.current.querySelector( querySelector );
		if ( input ) {
			input.focus();
		}
	};

	const onKeywordDelete = useCallback( ( index ) => {
		deleteKeyword( index );
	}, dependencies );

	const deleteKeyword = useCallback( ( index ) => {
		updateKeywords( [
			...values.slice( 0, index ),
			...values.slice( index + 1 ),
		] );
		// After deleting a keyword, hitting backspace will delete the next keyword
		setCanDeleteKeyword( true );
	}, dependencies, canDeleteKeyword );

	return (
		<Cell lgStart={ 6 } lgSize={ 6 } mdSize={ 8 } smSize={ 4 }>

				{ values.map( ( value, i ) => (

 i + 1 || value.length > 0,
						} ) }
					>
						<VisuallyHiden>
							<label htmlFor={ `${ slug }-keyword-${ i }` } >
								{ sprintf(
									/* translators: %s is the keyword number; 1, 2, or 3 */
									__( 'Keyword %s', 'google-site-kit' ),
									i + 1, // Keys are zero-indexed; this starts keyword at "1".
								) }

						</VisuallyHiden>
						<TextField
							label={ __( 'Enter minimum one (1), maximum three (3) terms', 'google-site-kit' ) }
							noLabel
						>
							<Input
								id={ `${ slug }-keyword-${ i }` }
								value={ value }
								size={ value.length > 0 ? value.length : undefined }
								onChange={ onKeywordChange.bind( null, i ) }
								onKeyDown={ onKeyDown.bind( null, i ) }
							/>
						</TextField>

						{ ( value.length > 0 || i + 1 < values.length ) && (
							<Button
								text
								icon={ <CloseIcon width="11" height="11" /> }
								onClick={ onKeywordDelete.bind( null, i ) }
							/>
						) }

				) ) }

				{ __( 'Separate with commas or the Enter key', 'google-site-kit' ) }

		</Cell>
	);
}

UserInputKeywords.propTypes = {
	slug: PropTypes.string.isRequired,
	max: PropTypes.number,
};

UserInputKeywords.defaultProps = {
	max: 1,
};
<commit_msg>Code review feedback.<commit_after>/**
 * User Input Keywords.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import classnames from 'classnames';

/**
 * WordPress dependencies
 */
import { useCallback, useRef, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { ENTER, BACKSPACE } from '@wordpress/keycodes';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_USER } from '../../googlesitekit/datastore/user/constants';
import { Cell, Input, TextField } from '../../material-components';
import Button from '../Button';
import CloseIcon from '../../../svg/close.svg';
import { COMMA } from '../../util/key-codes';
import VisuallyHiden from '../VisuallyHidden';
const { useSelect, useDispatch } = Data;

export default function UserInputKeywords( { slug, max } ) {
	const keywordsContainer = useRef();
	const [ canDeleteKeyword, setCanDeleteKeyword ] = useState( false );

	const values = useSelect( ( select ) => select( CORE_USER ).getUserInputSetting( slug ) || [] );
	const { setUserInputSetting } = useDispatch( CORE_USER );

	// Add an empty string if the values array is empty.
	if ( values.length === 0 ) {
		values.push( '' );
	}

	// Need to make sure that dependencies list always has the same number of elements.
	const dependencies = values.concat( Array( max ) ).slice( 0, max );

	const focusInput = ( querySelector ) => {
		const input = keywordsContainer.current.querySelector( querySelector );
		if ( input ) {
			input.focus();
		}
	};

	const deleteKeyword = useCallback( ( index ) => {
		updateKeywords( [
			...values.slice( 0, index ),
			...values.slice( index + 1 ),
		] );
		// After deleting a keyword, hitting backspace will delete the next keyword
		setCanDeleteKeyword( true );
	}, dependencies, canDeleteKeyword );

	const onKeywordDelete = useCallback( ( index ) => {
		deleteKeyword( index );
	}, dependencies );

	const updateKeywords = useCallback( ( keywords ) => {
		const EOT = String.fromCharCode( 4 );
		let newKeywords = keywords
			// Trim keywords to allow no empty spaces at the beginning and at max one space at the end.
			.map( ( keyword ) => keyword.replace( /(\S)\s+$/, '$1 ' ).replace( /^\s+/, '' ) )
			// EOT is added to the end to properly combine two sequential empty spaces at the end.
			.concat( [ '', EOT ] )
			.join( EOT )
			.replace( new RegExp( `${ EOT }{3,}`, 'g' ), EOT ); // Combine two sequential empty spaces into one.

		if ( newKeywords === EOT ) {
			newKeywords = [ '' ];
		} else {
			newKeywords = newKeywords.split( EOT ).slice( 0, max );
		}

		setUserInputSetting( slug, newKeywords );
	}, [ slug ] );

	const onKeywordChange = useCallback( ( index, { target } ) => {
		if ( target.value[ target.value.length - 1 ] === ',' ) {
			return;
		}

		updateKeywords( [
			...values.slice( 0, index ),
			target.value,
			...values.slice( index + 1 ),
		] );
	}, dependencies );

	const onKeyDown = useCallback( ( index, { keyCode, target } ) => {
		const nonEmptyValues = values.filter( ( value ) => value.length > 0 );
		const nonEmptyValuesLength = nonEmptyValues.length;

		if ( ( keyCode === ENTER || keyCode === COMMA ) && nonEmptyValues.length < max ) {
			updateKeywords( [
				...values.slice( 0, index + 1 ),
				'',
				...values.slice( index + 1 ),
			] );

			setCanDeleteKeyword( true ); // New keyword has been added, so hitting backspace now will remove it.
			setTimeout( () => {
				focusInput( `#${ slug }-keyword-${ index + 1 }` );
			}, 50 );
		}

		if ( target.value.length === 0 && keyCode === BACKSPACE ) {
			// User landed on the input and isn't in the middle of typing, so we can delete the last keyword.
			deleteKeyword( nonEmptyValuesLength - 1 );
			setTimeout( () => {
				focusInput( `#${ slug }-keyword-${ nonEmptyValuesLength - 1 }` );
			}, 50 );
			// After deleting a keyword, so hitting backspace again should continue to delete keywords.
			setCanDeleteKeyword( true );
		} else {
			// User is typing, so backspace should delete the last character rather than the keyword.
			setCanDeleteKeyword( false );
		}
	}, [ keywordsContainer.current, ...dependencies, canDeleteKeyword ] );

	return (
		<Cell lgStart={ 6 } lgSize={ 6 } mdSize={ 8 } smSize={ 4 }>

				{ values.map( ( value, i ) => (

 i + 1 || value.length > 0,
						} ) }
					>
						<VisuallyHiden>
							<label htmlFor={ `${ slug }-keyword-${ i }` } >
								{ sprintf(
									/* translators: %s is the keyword number; 1, 2, or 3 */
									__( 'Keyword %s', 'google-site-kit' ),
									i + 1, // Keys are zero-indexed; this starts keyword at "1".
								) }

						</VisuallyHiden>
						<TextField
							label={ __( 'Enter minimum one (1), maximum three (3) terms', 'google-site-kit' ) }
							noLabel
						>
							<Input
								id={ `${ slug }-keyword-${ i }` }
								value={ value }
								size={ value.length > 0 ? value.length : undefined }
								onChange={ onKeywordChange.bind( null, i ) }
								onKeyDown={ onKeyDown.bind( null, i ) }
							/>
						</TextField>

						{ ( value.length > 0 || i + 1 < values.length ) && (
							<Button
								text
								icon={ <CloseIcon width="11" height="11" /> }
								onClick={ onKeywordDelete.bind( null, i ) }
							/>
						) }

				) ) }

				{ __( 'Separate with commas or the Enter key', 'google-site-kit' ) }

		</Cell>
	);
}

UserInputKeywords.propTypes = {
	slug: PropTypes.string.isRequired,
	max: PropTypes.number,
};

UserInputKeywords.defaultProps = {
	max: 1,
};
<|endoftext|>


<commit_before>import 'vtk.js/Sources/favicon';

import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkRTAnalyticSource from 'vtk.js/Sources/Filters/Sources/RTAnalyticSource';
import vtkImageMapper from 'vtk.js/Sources/Rendering/Core/ImageMapper';
import vtkImageSlice from 'vtk.js/Sources/Rendering/Core/ImageSlice';
import vtkInteractorStyleImage from 'vtk.js/Sources/Interaction/Style/InteractorStyleImage';

// ----------------------------------------------------------------------------
// Standard rendering code setup
// ----------------------------------------------------------------------------

const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();

// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const rtSource = vtkRTAnalyticSource.newInstance();
rtSource.setWholeExtent(0, 200, 0, 200, 0, 200);
rtSource.setCenter(100, 100, 100);
rtSource.setStandardDeviation(0.3);

const mapper = vtkImageMapper.newInstance();
mapper.setInputConnection(rtSource.getOutputPort());
mapper.setSliceAtFocalPoint(true);
// mapper.setZSlice(5);

const actor = vtkImageSlice.newInstance();
actor.getProperty().setColorWindow(255);
actor.getProperty().setColorLevel(127);
actor.setMapper(mapper);

const iStyle = vtkInteractorStyleImage.newInstance();
iStyle.setInteractionMode('IMAGE_SLICING');
renderWindow.getInteractor().setInteractorStyle(iStyle);

renderer.addActor(actor);
renderer.resetCamera();
renderWindow.render();

// -----------------------------------------------------------
// Make some variables global so that you can inspect and
// modify objects in your browser's developer console:
// -----------------------------------------------------------

global.source = rtSource;
global.mapper = mapper;
global.actor = actor;
global.renderer = renderer;
global.renderWindow = renderWindow;
<commit_msg>fix(ImageMapper): use parallel projection in ImageMapper example<commit_after>import 'vtk.js/Sources/favicon';

import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkRTAnalyticSource from 'vtk.js/Sources/Filters/Sources/RTAnalyticSource';
import vtkImageMapper from 'vtk.js/Sources/Rendering/Core/ImageMapper';
import vtkImageSlice from 'vtk.js/Sources/Rendering/Core/ImageSlice';
import vtkInteractorStyleImage from 'vtk.js/Sources/Interaction/Style/InteractorStyleImage';

// ----------------------------------------------------------------------------
// Standard rendering code setup
// ----------------------------------------------------------------------------

const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();

// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const rtSource = vtkRTAnalyticSource.newInstance();
rtSource.setWholeExtent(0, 200, 0, 200, 0, 200);
rtSource.setCenter(100, 100, 100);
rtSource.setStandardDeviation(0.3);

const mapper = vtkImageMapper.newInstance();
mapper.setInputConnection(rtSource.getOutputPort());
mapper.setSliceAtFocalPoint(true);
// mapper.setZSlice(5);

const actor = vtkImageSlice.newInstance();
actor.getProperty().setColorWindow(255);
actor.getProperty().setColorLevel(127);
actor.setMapper(mapper);

const iStyle = vtkInteractorStyleImage.newInstance();
iStyle.setInteractionMode('IMAGE_SLICING');
renderWindow.getInteractor().setInteractorStyle(iStyle);

renderer.getActiveCamera().setParallelProjection(true);
renderer.addActor(actor);
renderer.resetCamera();
renderWindow.render();

// -----------------------------------------------------------
// Make some variables global so that you can inspect and
// modify objects in your browser's developer console:
// -----------------------------------------------------------

global.source = rtSource;
global.mapper = mapper;
global.actor = actor;
global.renderer = renderer;
global.renderWindow = renderWindow;
<|endoftext|>


<commit_before>import WebPackConfigBuilder from './WebPackConfigBuilder';
import HtmlWebpackPlugin from 'html-webpack-plugin';

export default function (entries = {}, outputPath = 'root') {
  const baseConfig = WebPackConfigBuilder.getBaseConfig(WebPackConfigBuilder.CONFIG_TYPES.COMPILE);
  const entryMap = {};
  const htmlPlugins = [];

  for (let k in entries) {
    if (entries.hasOwnProperty(k)) {
      const entry = entries[k];
      // TODO: Need chunks (full??? js paths per html file).
      // TODO: Need html files.
      // TODO: Need js files (full??? paths).
      htmlPlugins.push(new HtmlWebpackPlugin({
        template: 'app/index.html???',// TODO: How to configure this???
        hash: true,
        filename: '[name].html???',// TODO: How to configure this???
        minify: false,
        inject: 'body'// TODO: Is this right???
      }));
    }
  }

  return {
    entry: entryMap,
    output: {
      path: outputPath,
      filename: '[name].[hash].js',
      publicPath: '/'
    },
    resolve: {
      extensions: ['', '.js', '.jsx']
    },
    plugins: [...(baseConfig.plugins || []), ...(htmlPlugins || [])],
    loaders: baseConfig.loaders
  };
};
<commit_msg>chore(Config/WebPack/Compile) Add a TODO.<commit_after>import WebPackConfigBuilder from './WebPackConfigBuilder';
import HtmlWebpackPlugin from 'html-webpack-plugin';

export default function (entries = {}, outputPath = 'root') {
  const baseConfig = WebPackConfigBuilder.getBaseConfig(WebPackConfigBuilder.CONFIG_TYPES.COMPILE);
  const entryMap = {};
  const htmlPlugins = [];

  for (let k in entries) {
    if (entries.hasOwnProperty(k)) {
      const entry = entries[k];
      // TODO: Need chunks (full??? js paths per html file).
      // TODO: Need html files.
      // TODO: Need js files (full??? paths).
      // TODO: Use `templateContext`???
      htmlPlugins.push(new HtmlWebpackPlugin({
        template: 'app/index.html???',// TODO: How to configure this???
        hash: true,
        filename: '[name].html???',// TODO: How to configure this???
        minify: false,
        inject: 'body'// TODO: Is this right???
      }));
    }
  }

  return {
    entry: entryMap,
    output: {
      path: outputPath,
      filename: '[name].[hash].js',
      publicPath: '/'
    },
    resolve: {
      extensions: ['', '.js', '.jsx']
    },
    plugins: [...(baseConfig.plugins || []), ...(htmlPlugins || [])],
    loaders: baseConfig.loaders
  };
};
<|endoftext|>


<commit_before>var spawn = require('child_process').spawn;
var net = require('net');
var semaphore = require('semaphore')(1);

var conf = {
	bin: process.env.MELTED || "melted",
	root: process.env.MELTED_ROOT || process.env.PWD,
	host: process.env.MELTED_HOST || "localhost",
	port: process.env.MELTED_PORT || 5250,
	output: process.env.MELTED_OUTPUT || "sdl"
};

var melted_bin_path = process.env.PWD+ '/melted/BUILD/bin/melted';
var melted_lib_path = process.env.PWD+ '/melted/BUILD/lib';

_meltedbin = function(callback,errorCallback) {
    console.log("Melted.js: executing _meltedbin()");
	var pgrep = spawn( "which", ["melted"] );
    var pbin = melted_bin_path;

	pgrep.stdout.on('data', function (data) {
		pbin = data;
        console.log("Melted.js: data: " + data );
        conf.bin = pbin;
	});

	pgrep.on('exit', function (code) {
        if (code>1) {
            conf.bin = pbin;
            errorCallback(code);
        } else if (code==1) {
            conf.bin = pbin;
            return callback(pbin);
        } else {
            conf.bin = pbin;
            return callback(pbin);
        }
	});

};

/**
 * _do
 *
 * Private function to connect to melted.
 *
 * @callback: Callback function to do to melted.
 */
_do = function(callback) {
//	var pgrep = spawn('pgrep', ['-x', "melted"]);
    var pgrep = spawn('pgrep', ["melted"]);
	var pid;

	pgrep.stdout.on('data', function (data) {
		pid = data;
	});

	pgrep.on('exit', function (code) {
		return callback(parseInt(pid));
	});
};

/**
 * update_config
 *
 * Setup following melted attributes:
 *
 *   - bin: path to binary file.
 *   - root: path to videos files.
 *   - host: host where melted is running.
 *   - port: port where melted is running.
 *   - output: output device.
 *
 * @conf: Map with melted basic configuration.
 */
exports.update_config = function(new_config) {
	conf.bin   = new_config.bin || conf.bin;
	conf.root  = new_config.root || conf.root;
	conf.host  = new_config.host || conf.host;
	conf.port  = new_config.port || conf.port;
	conf.output= new_config.output || conf.output;
};

/**
 * get_config
 *
 * Return config object.
 */
exports.get_config = function() {
	return conf;
};

/**
 * is_running
 *
 * @callback: callback function when known if running or not.
 */
exports.is_running = function(callback) {
	_do(function(pid) {
		return callback(!isNaN(pid));
	})
}

/**
 * stop
 *
 * Stop melted.
 *
 * @callback : callback function when process is stopped.
 */
exports.stop = function(callback) {
	_do(function(pid) {
		if (pid) {
			//exports.connect(function(conn){ exports.push(conn, ['SHUTDOWN'], undefined, undefined); });
			var kill = spawn('kill',['-9',pid]);
			//kill.on('close', function(state) { return callback(pid) });
			kill.on('exit', function(code) {
                if (code) console.log("returned with code:"+code);
                return callback(pid)
            });
		} else
			callback(pid);
	})
};

/**
 * start
 *
 * Start melted deamon.
 *
 * @callback : callback function when process is ready.
 */
exports.start = function(callback) {
	_do(function(pid) {
		if (pid) {
			callback(pid);
		} else {
            _meltedbin( function(lbin) {
                console.log("Melted.js: [INFO] Melted.start > melted_bin is at: "+conf.bin);

                if (process.env.LD_LIBRARY_PATH!==undefined) process.env.LD_LIBRARY_PATH = process.env.LD_LIBRARY_PATH+":"+melted_lib_path;
                else process.env.LD_LIBRARY_PATH = melted_lib_path;

			    var melted_proc = spawn(conf.bin, [], {detached: true, stdio: [ 'ignore', 'ignore', 'ignore' ]});
			    var pid = melted_proc.pid;
                melted_proc.on('exit', function(code) {
                    setTimeout(function() { callback(pid); }, 1000 );
                } );
            }, function(error) {
                callback(0);
            } );
		}
	})
};

/**
 * connect
 *
 * Connect to melted daemon.
 *
 * @callback : callback function when process is ready.
 */
exports.connect = function(callback) {
	var conn = net.createConnection(conf.port, conf.host);
	conn.setEncoding('ascii');
	callback(conn);
};

/**
 * push
 *
 * Push commands to melted daemon.
 *
 * @commands : list of commands to send.
 * @callback : callback function when process is ready.
 */
exports.push = function(conn, commands, command_callback, close_callback) {
	var s = 0;
	conn.on('connect', function() {
		conn.on('data', function(data) {
			if (command_callback) command_callback(data);
			if (s < commands.length && data.indexOf("\n") > -1) {
				conn.write(commands[s]+"\n");
				s = s + 1;
			};
		});
	});
	if (close_callback) conn.on('close', function(had_err) { close_callback(had_err); });
};

/**
 * setup
 *
 * Setup melted deamon.
 *
 * @callback : callback function when process is ready.
 */
exports.setup = function(root, output, callback) {
	root = root || conf.root;
	output = output || conf.output;
	_do(function(pid) {
		if (pid) {
            console.log("Melted.js: [INFO] Melted.setup > setting up root:" + root + " ouput:" + output);
			var commands = [ 'NLS', 'SET root='+root, 'UADD '+output, 'BYE' ];
			exports.connect(function(conn){ exports.push(conn, commands, undefined, callback)});
		} else {
            callback(new Error("Melted.js: [ERROR] Can't connect to server. Server is not running!"));
		};
	})
};

/**
 * take
 *
 * Take melted and not leave execution to other melted taked.
 *
 * @callback: callback function to process while take melted.
 *
 */
exports.take = semaphore.take;

/**
 * leave
 *
 * Leave execution to other melted taked.
 *
 */
exports.leave = semaphore.leave;
<commit_msg>If which melted has data, use "melted" as bin.<commit_after>var spawn = require('child_process').spawn;
var net = require('net');
var semaphore = require('semaphore')(1);

var conf = {
	bin: process.env.MELTED || "melted",
	root: process.env.MELTED_ROOT || process.env.PWD,
	host: process.env.MELTED_HOST || "localhost",
	port: process.env.MELTED_PORT || 5250,
	output: process.env.MELTED_OUTPUT || "sdl"
};

var melted_bin_path = process.env.PWD+ '/melted/BUILD/bin/melted';
var melted_lib_path = process.env.PWD+ '/melted/BUILD/lib';

_meltedbin = function(callback,errorCallback) {
    console.log("Melted.js: executing _meltedbin()");
	var pgrep = spawn( "which", ["melted"] );
    var pbin = melted_bin_path;

	pgrep.stdout.on('data', function (data) {
		pbin = data;
        pbin = "melted";
        console.log("Melted.js: data: " + data );
        conf.bin = pbin;
	});

	pgrep.on('exit', function (code) {
        if (code>1) {
            conf.bin = pbin;
            errorCallback(code);
        } else if (code==1) {
            conf.bin = pbin;
            return callback(pbin);
        } else {
            conf.bin = pbin;
            return callback(pbin);
        }
	});

};

/**
 * _do
 *
 * Private function to connect to melted.
 *
 * @callback: Callback function to do to melted.
 */
_do = function(callback) {
//	var pgrep = spawn('pgrep', ['-x', "melted"]);
    var pgrep = spawn('pgrep', ["melted"]);
	var pid;

	pgrep.stdout.on('data', function (data) {
		pid = data;
        console.log("Melted.js: [INFO] _do pid : " + pid );
	});

	pgrep.on('exit', function (code) {
		return callback(parseInt(pid));
	});
};

/**
 * update_config
 *
 * Setup following melted attributes:
 *
 *   - bin: path to binary file.
 *   - root: path to videos files.
 *   - host: host where melted is running.
 *   - port: port where melted is running.
 *   - output: output device.
 *
 * @conf: Map with melted basic configuration.
 */
exports.update_config = function(new_config) {
	conf.bin   = new_config.bin || conf.bin;
	conf.root  = new_config.root || conf.root;
	conf.host  = new_config.host || conf.host;
	conf.port  = new_config.port || conf.port;
	conf.output= new_config.output || conf.output;
};

/**
 * get_config
 *
 * Return config object.
 */
exports.get_config = function() {
	return conf;
};

/**
 * is_running
 *
 * @callback: callback function when known if running or not.
 */
exports.is_running = function(callback) {
	_do(function(pid) {
		return callback(!isNaN(pid));
	})
}

/**
 * stop
 *
 * Stop melted.
 *
 * @callback : callback function when process is stopped.
 */
exports.stop = function(callback) {
	_do(function(pid) {
		if (pid) {
			//exports.connect(function(conn){ exports.push(conn, ['SHUTDOWN'], undefined, undefined); });
			var kill = spawn('kill',['-9',pid]);
			//kill.on('close', function(state) { return callback(pid) });
			kill.on('exit', function(code) {
                if (code) console.log("returned with code:"+code);
                return callback(pid)
            });
		} else
			callback(pid);
	})
};

/**
 * start
 *
 * Start melted deamon.
 *
 * @callback : callback function when process is ready.
 */
exports.start = function(callback) {
	_do(function(pid) {
		if (pid) {
			callback(pid);
		} else {
            _meltedbin( function(lbin) {
                console.log("Melted.js: [INFO] Melted.start > melted_bin is at: "+conf.bin);

                if (process.env.LD_LIBRARY_PATH!==undefined) process.env.LD_LIBRARY_PATH = process.env.LD_LIBRARY_PATH+":"+melted_lib_path;
                else process.env.LD_LIBRARY_PATH = melted_lib_path;

			    var melted_proc = spawn(conf.bin, [], {detached: true, stdio: [ 'ignore', 'ignore', 'ignore' ]});
			    var pid = melted_proc.pid;
                melted_proc.on('exit', function(code) {
                    setTimeout(function() { callback(pid); }, 1000 );
                } );
            }, function(error) {
                callback(0);
            } );
		}
	})
};

/**
 * connect
 *
 * Connect to melted daemon.
 *
 * @callback : callback function when process is ready.
 */
exports.connect = function(callback) {
	var conn = net.createConnection(conf.port, conf.host);
	conn.setEncoding('ascii');
	callback(conn);
};

/**
 * push
 *
 * Push commands to melted daemon.
 *
 * @commands : list of commands to send.
 * @callback : callback function when process is ready.
 */
exports.push = function(conn, commands, command_callback, close_callback) {
	var s = 0;
	conn.on('connect', function() {
		conn.on('data', function(data) {
			if (command_callback) command_callback(data);
			if (s < commands.length && data.indexOf("\n") > -1) {
				conn.write(commands[s]+"\n");
				s = s + 1;
			};
		});
	});
	if (close_callback) conn.on('close', function(had_err) { close_callback(had_err); });
};

/**
 * setup
 *
 * Setup melted deamon.
 *
 * @callback : callback function when process is ready.
 */
exports.setup = function(root, output, callback) {
	root = root || conf.root;
	output = output || conf.output;
	_do(function(pid) {
		if (pid) {
            console.log("Melted.js: [INFO] Melted.setup > setting up root:" + root + " ouput:" + output);
			var commands = [ 'NLS', 'SET root='+root, 'UADD '+output, 'BYE' ];
			exports.connect(function(conn){ exports.push(conn, commands, undefined, callback)});
		} else {
            callback(new Error("Melted.js: [ERROR] Can't connect to server. Server is not running!"));
		};
	})
};

/**
 * take
 *
 * Take melted and not leave execution to other melted taked.
 *
 * @callback: callback function to process while take melted.
 *
 */
exports.take = semaphore.take;

/**
 * leave
 *
 * Leave execution to other melted taked.
 *
 */
exports.leave = semaphore.leave;
<|endoftext|>


<commit_before>// whatever javascript files you place in this iFEF `folder will be concatenated to a single file in the js library

function test(arg){
	var output = arg || 'fire';
	console.log(output);
}

function delayReload(){
	setTimeout(function(){
		location.reload(true);
	},1000);
}

function json_post(url,data,callback,flag){
		var data = data || '';
		var callback = callback || '';
		var flag = flag || 'default';
		$.ajax({
			url: url,
			type: 'POST',
			data: JSON.stringify(data),
			contentType: 'application/json',
			success: callback,
			error: function(e){test(flag); test(e);}
		});
}

// Backbone.emulateJSON = true;

var AV = {};

AV.routes = Backbone.Router.extend({

	routes: {
		'': 'index',
	},

	initialize:function(){
		test('init');
		this.post = new AV.post();
		this.get = new AV.get();
		this.sources = new AV.sources();
		this.put = new AV.put();
		this.delete = new AV.delete();
		this.transform = new AV.transform();
		this.witness = new AV.witness();
		this.witnesses = new AV.witnesses();
		this.set = new AV.set();
		this.collate = new AV.collate();
		this.collection = new Backbone.Collection([
			this.post,
			this.get,
			this.sources,
			this.put,
			this.delete,
			this.transform,
			this.witness,
			this.witnesses,
			this.set,
			this.collate
			]);
		this.testerView = new AV.testerView({collection: this.collection});
	},

	index: function() {
		this.testerView.render();
	},

});

AV.testerView = Backbone.View.extend({

	el: '#verb-tests',
	initialize: function(){},
	events: {
		"click button#post" : 'post',
		"click button#get" : 'get',
		"click button#get-srcs" : 'getSRCS',
		"click button#put" : 'put',
		"click button#delete" : 'delete',
		"click button#transform" : 'transform',
		"click button#get-witness" : 'getWTNS',
		"click button#get-witnesses" : 'getWTNSlist',
		"click button#delete-witness" : 'deleteWitness',
		"click button#create-set" : 'createSet',
		"click button#collate-set" : 'collateSet',
		"click button#get-set" : 'getSet',
		"click button#delete-set" : 'deleteSet',
		"click button#get-viz" : 'getViz'
	},
	render:function(){
		this.$el.html(
			'
'
			+ '
<button class="btn btn-success" id="post">post</button>
'
			+ '
<button class="btn btn-primary" id="get">get source</button>
'
			+ '
<button class="btn btn-primary" id="get-srcs">get sources</button>
'
			+ '
<button class="btn btn-warning" id="put">put</button>
'
			+ '
<button class="btn btn-danger" id="delete">delete</button>
'
			+ '
<button class="btn btn-success" id="transform">transform</button>
'
			+ '
<button class="btn btn-default" id="get-witness">get witness</button>
'
			+ '
<button class="btn btn-default" id="get-witnesses">get witnesses</button>
'
			+ '
<button class="btn btn-default" id="delete-witness">delete witness</button>
'
			+ '
<button class="btn btn-default" id="create-set">create set</button>
'
			+ '
<button class="btn btn-default" id="collate-set">collate set</button>
'
			+ '
<button class="btn btn-default" id="get-set">get set</button>
'
			+ '
<button class="btn btn-default" id="delete-set">delete set</button>
'
			+ '
<button class="btn btn-default" id="get-viz">get viz</button>
'
			+ '
');
		this.$el.find('ul li').css( {'list-style' : 'none', 'margin-bottom' : '5px' });
	},
	post:function(){

		test('post');
		this.collection.models[0].url = '/juxta/source';
		this.collection.models[0].save({

		name: 'post issue debug',
			type: 'raw',
			contentType: 'txt',
			data: 'some test what what'
		},
	{ 	success: function(e){ test('success'); },
	}	);
//		delayReload();
	},

	get:function(){test('get');
		this.collection.models[1].set({id : this.collection.models[1].id + '.json' })
		this.collection.models[1].fetch({
			success:function() { test('success');},
			error:function() { test('not so much');}
		});
	//	delayReload();
	},

	getSRCS:function(){test('get-srcs');
		test('get-ws');
		this.collection.models[2].fetch({
			success: function(e){ test('success'); },
			error: function(e){ test('error'); }
		});
	//	delayReload();
	},

	put:function(){test('put');

		this.collection.models[3].save(
			{
			id: '152',
			name: 'successful put',
			data: 'putted it really I did'
			}
		);

		//delayReload();
	},

	delete:function(){test('delete');
		this.collection.models[4].set({id : 23});
		this.collection.models[4].destroy();

		// delayReload();
	},

	transform: function(){
		test('transform');
		this.collection.models[5].save({

			source: 295,
			finalName: 'aefae witness'

		});
	},

	getWTNS: function(){
		test('get witness');
		this.collection.models[6].set({ id : 11 });
		this.collection.models[6].fetch({
			success: function(a,b,c) {
				$('#log').append(JSON.stringify(b));
			}
		});
	},

	getWTNSlist: function(){
		test('get witnesses');
		this.collection.models[7].fetch();
	},

	deleteWitness: function(){

		test('delete witness')
		this.collection.models[6].set({ id : 11 });
		this.collection.models[6].destroy({

			success: function(a,b,c) {
			$('#log').append(JSON.stringify(b));
			}

		});
	},

	createSet: function(){
		test('create set');
		this.collection.models[8].save({
				name: 'akhmatova set',
				witnesses: [28,27,26,25,24,23]
			},
			{
			success: function(a,b,c) {
				$('#log').append(JSON.stringify(b));
			}
		});
	},

	collateSet: function(){
		test('collate set');
		this.collection.models[9].set({ id: 7 });
		this.collection.models[9].collateSetOpts();
	},

	getSet: function(){
		test('get set');
		this.collection.models[9].set({ id: 7 });
		this.collection.models[9].fetch();
	},

	deleteSet: function(){
		test('delete set');
		this.collection.models[9].delete();
	},

	getViz: function(){
		this.collection.models[9].set({ id: 7 });
		this.viz = this.collection.models[9].viewHeatMap();
		console.log(this.viz);
		$('#container').append('')
			.find('iframe')
			.attr('src', 'view_embed.html')
			.find('body')
			.html(this.viz);
	}

});
AV.post = Backbone.Model.extend({
	url: '/juxta/source',
	sync: function(a,b,c){
		b.attributes = [b.attributes];
		return Backbone.sync.apply(this, [a,b,c]);
	}
});

AV.get = Backbone.Model.extend({
	url: '/juxta/source/13.json'
});

AV.sources = Backbone.Model.extend({
	url: '/juxta/source.json'
});

AV.put = Backbone.Model.extend({
	urlRoot: '/juxta/source/152',
	defaults:{
		name: '',
		type: 'raw',
		contentType: 'txt',
		data: ''
	},
	sync: function(a,b,c){
		test(c);
		b.attributes = [b.attributes];
		c.emulateJSON = true;
		c.contentType = false;
		c.processData = false;
		return Backbone.sync.apply(this, [a,b,c]);
	}
});

AV.delete = Backbone.Model.extend({
	urlRoot: '/juxta/source',
	defaults:{ id: 8 }
	});

AV.transform = Backbone.Model.extend({

	url: '/juxta/transform',
	defaults: {
		source: '',
		finalName: ''
	}
});

AV.witness = Backbone.Model.extend({
	urlRoot: '/juxta/witness'
});

AV.witnesses = Backbone.Model.extend({
	url: '/juxta/witness.json'
});

AV.set = Backbone.Model.extend({
	url: '/juxta/set',
	defaults: {
		name: '',
		witnesses: []
	}
});

AV.collate = Backbone.Model.extend({
	url: '/juxta/set',
	defaults: {

		id: null,
		filterWhitespace: true,
		filterPunctuation: false,
		filterCase: true,
		hyphenationFilter: "INCLUDE_ALL"
	},
	collateSetOpts: function() {
		var data = this.attributes;
		var url = this.url + '/' + this.attributes.id + '/collator';
		json_post(url,data,this.collate(), 'setopts');
	},
	collate: function() {
		var url = this.url + '/' + this.attributes.id + '/collate';
		json_post(url);
	},
	viewHeatMap: function(){
		this.url = this.url + '/' + this.attributes.id + '/view';
		var params = {mode: 'heatmap', embed: true};

		var heatmap = $.ajax({
			type: 'GET',
			data: params,
			processData: true,
			dataType: 'html',
			success: function(a,b,c){ return a; }
		});

		return heatmap;
	}
});

var readysetgo = new AV.routes();

$(function(){
  Backbone.history.start();
});
<commit_msg>test collate funcs<commit_after>// whatever javascript files you place in this iFEF `folder will be concatenated to a single file in the js library

function test(arg){
	var output = arg || 'fire';
	console.log(output);
}

function delayReload(){
	setTimeout(function(){
		location.reload(true);
	},1000);
}

function json_post(url,data,callback,flag){
		var data = data || '';
		var callback = callback || '';
		var flag = flag || 'default';
		$.ajax({
			url: url,
			type: 'POST',
			data: JSON.stringify(data),
			contentType: 'application/json',
			success: callback,
			error: function(e){test(flag); test(e);}
		});
}

// Backbone.emulateJSON = true;

var AV = {};

AV.routes = Backbone.Router.extend({

	routes: {
		'': 'index',
	},

	initialize:function(){
		test('init');
		this.post = new AV.post();
		this.get = new AV.get();
		this.sources = new AV.sources();
		this.put = new AV.put();
		this.delete = new AV.delete();
		this.transform = new AV.transform();
		this.witness = new AV.witness();
		this.witnesses = new AV.witnesses();
		this.set = new AV.set();
		this.collate = new AV.collate();
		this.collection = new Backbone.Collection([
			this.post,
			this.get,
			this.sources,
			this.put,
			this.delete,
			this.transform,
			this.witness,
			this.witnesses,
			this.set,
			this.collate
			]);
		this.testerView = new AV.testerView({collection: this.collection});
	},

	index: function() {
		this.testerView.render();
	},

});

AV.testerView = Backbone.View.extend({

	el: '#verb-tests',
	initialize: function(){},
	events: {
		"click button#post" : 'post',
		"click button#get" : 'get',
		"click button#get-srcs" : 'getSRCS',
		"click button#put" : 'put',
		"click button#delete" : 'delete',
		"click button#transform" : 'transform',
		"click button#get-witness" : 'getWTNS',
		"click button#get-witnesses" : 'getWTNSlist',
		"click button#delete-witness" : 'deleteWitness',
		"click button#create-set" : 'createSet',
		"click button#collate-set" : 'collateSet',
		"click button#get-set" : 'getSet',
		"click button#delete-set" : 'deleteSet',
		"click button#get-viz" : 'getViz'
	},
	render:function(){
		this.$el.html(
			'
'
			+ '
<button class="btn btn-success" id="post">post</button>
'
			+ '
<button class="btn btn-primary" id="get">get source</button>
'
			+ '
<button class="btn btn-primary" id="get-srcs">get sources</button>
'
			+ '
<button class="btn btn-warning" id="put">put</button>
'
			+ '
<button class="btn btn-danger" id="delete">delete</button>
'
			+ '
<button class="btn btn-success" id="transform">transform</button>
'
			+ '
<button class="btn btn-default" id="get-witness">get witness</button>
'
			+ '
<button class="btn btn-default" id="get-witnesses">get witnesses</button>
'
			+ '
<button class="btn btn-default" id="delete-witness">delete witness</button>
'
			+ '
<button class="btn btn-default" id="create-set">create set</button>
'
			+ '
<button class="btn btn-default" id="collate-set">collate set</button>
'
			+ '
<button class="btn btn-default" id="get-set">get set</button>
'
			+ '
<button class="btn btn-default" id="delete-set">delete set</button>
'
			+ '
<button class="btn btn-default" id="get-viz">get viz</button>
'
			+ '
');
		this.$el.find('ul li').css( {'list-style' : 'none', 'margin-bottom' : '5px' });
	},
	post:function(){

		test('post');
		this.collection.models[0].url = '/juxta/source';
		this.collection.models[0].save({

		name: 'post issue debug',
			type: 'raw',
			contentType: 'txt',
			data: 'some test what what'
		},
	{ 	success: function(e){ test('success'); },
	}	);
//		delayReload();
	},

	get:function(){test('get');
		this.collection.models[1].set({id : this.collection.models[1].id + '.json' })
		this.collection.models[1].fetch({
			success:function() { test('success');},
			error:function() { test('not so much');}
		});
	//	delayReload();
	},

	getSRCS:function(){test('get-srcs');
		test('get-ws');
		this.collection.models[2].fetch({
			success: function(e){ test('success'); },
			error: function(e){ test('error'); }
		});
	//	delayReload();
	},

	put:function(){test('put');

		this.collection.models[3].save(
			{
			id: '152',
			name: 'successful put',
			data: 'putted it really I did'
			}
		);

		//delayReload();
	},

	delete:function(){test('delete');
		this.collection.models[4].set({id : 23});
		this.collection.models[4].destroy();

		// delayReload();
	},

	transform: function(){
		test('transform');
		this.collection.models[5].save({

			source: 295,
			finalName: 'aefae witness'

		});
	},

	getWTNS: function(){
		test('get witness');
		this.collection.models[6].set({ id : 11 });
		this.collection.models[6].fetch({
			success: function(a,b,c) {
				$('#log').append(JSON.stringify(b));
			}
		});
	},

	getWTNSlist: function(){
		test('get witnesses');
		this.collection.models[7].fetch();
	},

	deleteWitness: function(){

		test('delete witness')
		this.collection.models[6].set({ id : 11 });
		this.collection.models[6].destroy({

			success: function(a,b,c) {
			$('#log').append(JSON.stringify(b));
			}

		});
	},

	createSet: function(){
		test('create set');
		this.collection.models[8].save({
				name: 'akhmatova set',
				witnesses: [28,27,26,25,24,23]
			},
			{
			success: function(a,b,c) {
				$('#log').append(JSON.stringify(b));
			}
		});
	},

	collateSet: function(){
		test('collate set');
		this.collection.models[9].set({ id: 7 });
		this.collection.models[9].collateSetOpts();
	},

	getSet: function(){
		test('get set');
		this.collection.models[9].set({ id: 7 });
		this.collection.models[9].fetch();
	},

	deleteSet: function(){
		test('delete set');
		this.collection.models[9].delete();
	},

	getViz: function(){
		this.collection.models[9].set({ id: 7 });
		this.viz = this.collection.models[9].viewHeatMap();
		console.log(this.viz);
		$('#container').append('')
			.find('iframe')
			.attr('src', 'view_embed.html')
			.find('body')
			.html(this.viz);
	}

});
AV.post = Backbone.Model.extend({
	url: '/juxta/source',
	sync: function(a,b,c){
		b.attributes = [b.attributes];
		return Backbone.sync.apply(this, [a,b,c]);
	}
});

AV.get = Backbone.Model.extend({
	url: '/juxta/source/13.json'
});

AV.sources = Backbone.Model.extend({
	url: '/juxta/source.json'
});

AV.put = Backbone.Model.extend({
	urlRoot: '/juxta/source/152',
	defaults:{
		name: '',
		type: 'raw',
		contentType: 'txt',
		data: ''
	},
	sync: function(a,b,c){
		test(c);
		b.attributes = [b.attributes];
		c.emulateJSON = true;
		c.contentType = false;
		c.processData = false;
		return Backbone.sync.apply(this, [a,b,c]);
	}
});

AV.delete = Backbone.Model.extend({
	urlRoot: '/juxta/source',
	defaults:{ id: 8 }
	});

AV.transform = Backbone.Model.extend({

	url: '/juxta/transform',
	defaults: {
		source: '',
		finalName: ''
	}
});

AV.witness = Backbone.Model.extend({
	urlRoot: '/juxta/witness'
});

AV.witnesses = Backbone.Model.extend({
	url: '/juxta/witness.json'
});

AV.set = Backbone.Model.extend({
	url: '/juxta/set',
	defaults: {
		name: '',
		witnesses: []
	}
});

AV.collate = Backbone.Model.extend({
	url: '/juxta/set',
	defaults: {

		id: null,
		filterWhitespace: true,
		filterPunctuation: false,
		filterCase: true,
		hyphenationFilter: "INCLUDE_ALL"
	},
	collateSetOpts: function() {
		var data = this.attributes;
		var url = this.url + '/' + this.attributes.id + '/collator';
		json_post(url,data,this.collate(), 'setopts');
	},
	collate: function() {
		var url = this.url + '/' + this.attributes.id + '/collate';
		json_post(url);
	},
	viewHeatMap: function(){
		this.url = this.url + '/' + this.attributes.id + '/view';
		var params = {mode: 'heatmap', embed: true};

		var heatmap = $.ajax({
			type: 'GET',
			data: params,
			processData: true,
			dataType: 'html',
			success: function(a,b,c){ return a.responseText; }
		});

		return heatmap;
	}
});

var readysetgo = new AV.routes();

$(function(){
  Backbone.history.start();
});
<|endoftext|>