text:
/**
 * Finnish Translations
 * <tuomas.salo (at) iki.fi>
 * 'ä' should read as lowercase 'a' with two dots on top (ä)
 */
Ext.onReady(function() {

    if (Ext.Date) {
        Ext.Date.monthNames = ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"];

        Ext.Date.getShortMonthName = function(month) {
            return (month + 1) + ".";
        };

        Ext.Date.monthNumbers = {
            'tammikuu': 0,
            'helmikuu': 1,
            'maaliskuu': 2,
            'huhtikuu': 3,
            'toukokuu': 4,
            'kesäkuu': 5,
            'heinäkuu': 6,
            'elokuu': 7,
            'syyskuu': 8,
            'lokakuu': 9,
            'marraskuu': 10,
            'joulukuu': 11
        };

        Ext.Date.getMonthNumber = function(name) {
            if (name.match(/^(1?\d)\./)) {
                return -1 + RegExp.$1;
            } else {
                return Ext.Date.monthNumbers[name];
            }
        };

        Ext.Date.dayNames = ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"];

        Ext.Date.getShortDayName = function(day) {
            return Ext.Date.dayNames[day].substring(0, 2);
        };
    }

    if (Ext.util && Ext.util.Format) {
        Ext.apply(Ext.util.Format, {
            thousandSeparator: '.',
            decimalSeparator: ',',
            currencySign: '\u20ac',
            // Finnish Euro
            dateFormat: 'j.n.Y'
        });

        Ext.util.Format.date = function(v, format) {
            if (!v) return "";
            if (!(v instanceof Date)) v = new Date(Date.parse(v));
            return Ext.Date.format(v, format || "j.n.Y");
        };

    }
});

Ext.define("Ext.locale.fi.view.View", {
    override: "Ext.view.View",
    emptyText: ""
});

Ext.define("Ext.locale.fi.grid.plugin.DragDrop", {
    override: "Ext.grid.plugin.DragDrop",
    dragText: "{0} rivi(ä) valittu"
});

Ext.define("Ext.locale.fi.tab.Tab", {
    override: "Ext.tab.Tab",
    closeText: "Sulje tämä välilehti"
});

// changing the msg text below will affect the LoadMask
Ext.define("Ext.locale.fi.view.AbstractView", {
    override: "Ext.view.AbstractView",
    loadingText: "Ladataan..."
});

Ext.define("Ext.locale.fi.picker.Date", {
    override: "Ext.picker.Date",
    todayText: "Tänään",
    minText: "Tämä päivämäärä on aikaisempi kuin ensimmäinen sallittu",
    maxText: "Tämä päivämäärä on myöhäisempi kuin viimeinen sallittu",
    disabledDaysText: "",
    disabledDatesText: "",
    nextText: 'Seuraava kuukausi (Control+oikealle)',
    prevText: 'Edellinen kuukausi (Control+vasemmalle)',
    monthYearText: 'Valitse kuukausi (vaihda vuotta painamalla Control+ylös/alas)',
    todayTip: "{0} (välilyönti)",
    format: "j.n.Y",
    startDay: 1 // viikko alkaa maanantaista
});

Ext.define("Ext.locale.fi.picker.Month", {
    override: "Ext.picker.Month",
    okText: " OK ",
    cancelText: "Peruuta"
});

Ext.define("Ext.locale.fi.toolbar.Paging", {
    override: "Ext.PagingToolbar",
    beforePageText: "Sivu",
    afterPageText: "/ {0}",
    firstText: "Ensimmäinen sivu",
    prevText: "Edellinen sivu",
    nextText: "Seuraava sivu",
    lastText: "Viimeinen sivu",
    refreshText: "Päivitä",
    displayMsg: "Näytetään {0} - {1} / {2}",
    emptyMsg: 'Ei tietoja'
});

Ext.define("Ext.locale.fi.form.field.Base", {
    override: "Ext.form.field.Base",
    invalidText: "Tämän kentän arvo ei kelpaa"
});

Ext.define("Ext.locale.fi.form.field.Text", {
    override: "Ext.form.field.Text",
    minLengthText: "Tämän kentän minimipituus on {0}",
    maxLengthText: "Tämän kentän maksimipituus on {0}",
    blankText: "Tämä kenttä on pakollinen",
    regexText: "",
    emptyText: null
});

Ext.define("Ext.locale.fi.form.field.Number", {
    override: "Ext.form.field.Number",
    minText: "Tämän kentän pienin sallittu arvo on {0}",
    maxText: "Tämän kentän suurin sallittu arvo on {0}",
    nanText: "{0} ei ole numero"
});

Ext.define("Ext.locale.fi.form.field.Date", {
    override: "Ext.form.field.Date",
    disabledDaysText: "Ei käytössä",
    disabledDatesText: "Ei käytössä",
    minText: "Tämän kentän päivämäärän tulee olla {0} jälkeen",
    maxText: "Tämän kentän päivämäärän tulee olla ennen {0}",
    invalidText: "Päivämäärä {0} ei ole oikeassa muodossa - kirjoita päivämäärä muodossa {1}",
    format: "j.n.Y",
    altFormats: "j.n.|d.m.|mdy|mdY|d|Y-m-d|Y/m/d"
});

Ext.define("Ext.locale.fi.form.field.ComboBox", {
    override: "Ext.form.field.ComboBox",
    valueNotFoundText: undefined
}, function() {
    Ext.apply(Ext.form.field.ComboBox.prototype.defaultListConfig, {
        loadingText: "Ladataan..."
    });
});

Ext.define("Ext.locale.fi.form.field.VTypes", {
    override: "Ext.form.field.VTypes",
    emailText: 'Syötä tähän kenttään sähköpostiosoite, esim. "etunimi.sukunimi@osoite.fi"',
    urlText: 'Syötä tähän kenttään URL-osoite, esim. "http:/' + '/www.osoite.fi"',
    alphaText: 'Syötä tähän kenttään vain kirjaimia (a-z, A-Z) ja alaviivoja (_)',
    alphanumText: 'Syötä tähän kenttään vain kirjaimia (a-z, A-Z), numeroita (0-9) ja alaviivoja (_)'
});

Ext.define("Ext.locale.fi.form.field.HtmlEditor", {
    override: "Ext.form.field.HtmlEditor",
    createLinkText: 'Anna linkin URL-osoite:'
}, function() {
    Ext.apply(Ext.form.field.HtmlEditor.prototype, {
        buttonTips: {
            bold: {
                title: 'Lihavoi (Ctrl+B)',
                text: 'Lihavoi valittu teksti.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            italic: {
                title: 'Kursivoi (Ctrl+I)',
                text: 'Kursivoi valittu teksti.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            underline: {
                title: 'Alleviivaa (Ctrl+U)',
                text: 'Alleviivaa valittu teksti.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            increasefontsize: {
                title: 'Suurenna tekstiä',
                text: 'Kasvata tekstin kirjasinkokoa.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            decreasefontsize: {
                title: 'Pienennä tekstiä',
                text: 'Pienennä tekstin kirjasinkokoa.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            backcolor: {
                title: 'Tekstin korostusväri',
                text: 'Vaihda valitun tekstin taustaväriä.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            forecolor: {
                title: 'Tekstin väri',
                text: 'Vaihda valitun tekstin väriä.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            justifyleft: {
                title: 'Tasaa vasemmalle',
                text: 'Tasaa teksti vasempaan reunaan.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            justifycenter: {
                title: 'Keskitä',
                text: 'Keskitä teksti.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            justifyright: {
                title: 'Tasaa oikealle',
                text: 'Tasaa teksti oikeaan reunaan.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            insertunorderedlist: {
                title: 'Luettelo',
                text: 'Luo luettelo.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            insertorderedlist: {
                title: 'Numeroitu luettelo',
                text: 'Luo numeroitu luettelo.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            createlink: {
                title: 'Linkki',
                text: 'Tee valitusta tekstistä hyperlinkki.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            },
            sourceedit: {
                title: 'Lähdekoodin muokkaus',
                text: 'Vaihda lähdekoodin muokkausnäkymään.',
                cls: Ext.baseCSSPrefix + 'html-editor-tip'
            }
        }
    });
});

Ext.define("Ext.locale.fi.form.Basic", {
    override: "Ext.form.Basic",
    waitTitle: "Odota..."
});

Ext.define("Ext.locale.fi.grid.header.Container", {
    override: "Ext.grid.header.Container",
    sortAscText: "Järjestä A-Ö",
    sortDescText: "Järjestä Ö-A",
    lockText: "Lukitse sarake",
    unlockText: "Vapauta sarakkeen lukitus",
    columnsText: "Sarakkeet"
});

Ext.define("Ext.locale.fi.grid.GroupingFeature", {
    override: "Ext.grid.feature.Grouping",
    emptyGroupText: '(ei mitään)',
    groupByText: 'Ryhmittele tämän kentän mukaan',
    showGroupsText: 'Näytä ryhmissä'
});

Ext.define("Ext.locale.fi.grid.PropertyColumnModel", {
    override: "Ext.grid.PropertyColumnModel",
    nameText: "Nimi",
    valueText: "Arvo",
    dateFormat: "j.m.Y"
});

Ext.define("Ext.locale.fi.window.MessageBox", {
    override: "Ext.window.MessageBox",
    buttonText: {
        ok: "OK",
        cancel: "Peruuta",
        yes: "Kyllä",
        no: "Ei"
    }
});

// This is needed until we can refactor all of the locales into individual files
Ext.define("Ext.locale.fi.Component", {
    override: "Ext.Component"
});


text:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { prerender } = require('./prerender');
const { getTitle } = require('../../helpers/getTitle');

const templateDir = path.join(__dirname, '../../templates');

async function getHtmlWebpackPlugin({
  isProd,
  googleAnalyticsID,
  algolia,
  pathPrefix = '',
  url,
  title,
  isFullscreen
}) {
  return new HtmlWebpackPlugin({
    template: path.join(templateDir, 'html.ejs'),
    filename: `${url}/index.html`.replace(/^\/+/, ''),
    templateParameters: {
      title: getTitle(title),
      // Don't prerender fullscreen pages (expensive!)
      prerendering: (isProd && !isFullscreen && !url.includes('extensions')) ? await prerender(url, pathPrefix) : null,
      // Don't use GA in dev mode
      googleAnalyticsID: isProd ? googleAnalyticsID : false,
      algolia
    },
    scriptLoading: 'defer',
    inject: false,
    minify: false
  })
}

async function getHtmlWebpackPlugins(options) {
  const { isProd } = options;
  const { routes, fullscreenRoutes } = require('../../routes');
  const res = [
    // Sitemap
    new HtmlWebpackPlugin({
      template: path.join(templateDir, 'sitemap.ejs'),
      filename: 'sitemap.xml',
      templateParameters: {
        urls: Object.entries(routes)
          .map(([path, { sources }]) => [path, ...(sources || []).slice(1).map(source => source.slug)])
          .flat()
      },
      inject: false,
      minify: false,
    })
  ];

  if (!isProd) {
    // Only render the index page in dev mode and rely on historyApiFallback
    res.push(await getHtmlWebpackPlugin({ isProd, url: '', title: 'Dev', ...options }));
    return res;
  }

  const titledRoutes = Object.entries(routes)
    .concat(Object.entries(fullscreenRoutes))
    .map(([url, { sources = [], title, isFullscreen }]) => [
      [url, { title, isFullscreen }],
      // Add pages for sources
      ...sources.slice(1).map(source => [source.slug, source])
    ])
    .flat()
    .sort();

  for (const [url, { title, isFullscreen }] of titledRoutes) {
    res.push(await getHtmlWebpackPlugin({ url, title, isFullscreen, ...options }));
  }

  console.log('done prerendering');
  return res;
};

module.exports = {
  getHtmlWebpackPlugins
};

redpajama_set_name: RedPajamaGithub


text:
namespace ee {
namespace detail {
UiWidgetCallback* UiWidgetCallback::getInstance() {
    static Self sharedInstance;
    return &sharedInstance;
}

void UiWidgetCallback::setActiveClickCallback(const ClickCallback& callback) {
    clickCallback_ = callback;
    touchCallback_ = nullptr;
}

void UiWidgetCallback::setActiveTouchCallback(const TouchCallback& callback) {
    touchCallback_ = callback;
    clickCallback_ = nullptr;
}

auto UiWidgetCallback::getActiveTouchCallback() const -> const TouchCallback& {
    return touchCallback_;
}

auto UiWidgetCallback::getActiveClickCallback() const -> const ClickCallback& {
    return clickCallback_;
}
} // namespace detail
} // namespace ee

#endif // EE_X_COCOS_CPP


text:
Culinary recipes blog

## What you need to run the project:
- [NodeJS](nodejs.org);
- [NPM](https://www.npmjs.com);
- [Bower](https://bower.io);
- [Gulp](http://gulpjs.com);

## Tools and responsabilities:
- npm to manage development dependencies;
- Bower to manage website dependencies;
- Gulp as a task manager;
- [Sass](http://sass-lang.com) to improve CSS capabilities;
- [Autoprefixer](https://autoprefixer.github.io) to guarantee better support for old browser;

## Running the project for the first time
1. Go to project folder;
2. Install development dependencies: `npm install`;
3. Install website dependencies: `bower install`;
4. Run development environment: `gulp`;

Have fun :)

---

## Web fonts used
- [Amatic_SC](https://fonts.google.com/specimen/Amatic+SC);
- [Josefin_Sans](https://fonts.google.com/specimen/Josefin+Sans);
- [Sacramento](https://fonts.google.com/specimen/Sacramento);


text:
package org.jabref.gui.duplicationFinder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;

import org.jabref.gui.DialogService;
import org.jabref.gui.Globals;
import org.jabref.gui.JabRefExecutorService;
import org.jabref.gui.JabRefFrame;
import org.jabref.gui.LibraryTab;
import org.jabref.gui.StateManager;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.duplicationFinder.DuplicateResolverDialog.DuplicateResolverResult;
import org.jabref.gui.duplicationFinder.DuplicateResolverDialog.DuplicateResolverType;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableInsertEntries;
import org.jabref.gui.undo.UndoableRemoveEntries;
import org.jabref.gui.util.BackgroundTask;
import org.jabref.gui.util.DefaultTaskExecutor;
import org.jabref.logic.database.DuplicateCheck;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.BibDatabaseMode;
import org.jabref.model.entry.BibEntry;

import static org.jabref.gui.actions.ActionHelper.needsDatabase;

public class DuplicateSearch extends SimpleCommand {

    private final JabRefFrame frame;
    private final BlockingQueue<List<BibEntry>> duplicates = new LinkedBlockingQueue<>();

    private final AtomicBoolean libraryAnalyzed = new AtomicBoolean();
    private final AtomicBoolean autoRemoveExactDuplicates = new AtomicBoolean();
    private final AtomicInteger duplicateCount = new AtomicInteger();
    private final SimpleStringProperty duplicateCountObservable = new SimpleStringProperty();
    private final SimpleStringProperty duplicateTotal = new SimpleStringProperty();
    private final SimpleIntegerProperty duplicateProgress = new SimpleIntegerProperty(0);
    private final DialogService dialogService;
    private final StateManager stateManager;

    public DuplicateSearch(JabRefFrame frame, DialogService dialogService, StateManager stateManager) {
        this.frame = frame;
        this.dialogService = dialogService;
        this.stateManager = stateManager;

        this.executable.bind(needsDatabase(stateManager));
    }

    @Override
    public void execute() {
        BibDatabaseContext database = stateManager.getActiveDatabase().orElseThrow(() -> new NullPointerException("Database null"));
        dialogService.notify(Localization.lang("Searching for duplicates..."));

        List<BibEntry> entries = database.getEntries();
        duplicates.clear();
        libraryAnalyzed.set(false);
        autoRemoveExactDuplicates.set(false);
        duplicateCount.set(0);

        if (entries.size() < 2) {
            return;
        }

        duplicateCountObservable.addListener((obj, oldValue, newValue) -> DefaultTaskExecutor.runAndWaitInJavaFXThread(() -> duplicateTotal.set(newValue)));

        JabRefExecutorService.INSTANCE.executeInterruptableTask(() -> searchPossibleDuplicates(entries, database.getMode()), "DuplicateSearcher");
        BackgroundTask.wrap(this::verifyDuplicates)
                      .onSuccess(this::handleDuplicates)
                      .executeWith(Globals.TASK_EXECUTOR);
    }

    private void searchPossibleDuplicates(List<BibEntry> entries, BibDatabaseMode databaseMode) {
        for (int i = 0; (i < (entries.size() - 1)); i++) {
            for (int j = i + 1; (j < entries.size()); j++) {
                if (Thread.interrupted()) {
                    return;
                }

                BibEntry first = entries.get(i);
                BibEntry second = entries.get(j);

                if (new DuplicateCheck(Globals.entryTypesManager).isDuplicate(first, second, databaseMode)) {
                    duplicates.add(Arrays.asList(first, second));
                    duplicateCountObservable.set(String.valueOf(duplicateCount.incrementAndGet()));
                }
            }
        }
        libraryAnalyzed.set(true);
    }

    private DuplicateSearchResult verifyDuplicates() {
        DuplicateSearchResult result = new DuplicateSearchResult();

        while (!libraryAnalyzed.get() || !duplicates.isEmpty()) {
            duplicateProgress.set(duplicateProgress.getValue() + 1);

            List<BibEntry> dups;
            try {
                // poll with timeout in case the library is not analyzed completely, but contains no more duplicates
                dups = this.duplicates.poll(100, TimeUnit.MILLISECONDS);
                if (dups == null) {
                    continue;
                }
            } catch (InterruptedException e) {
                return null;
            }

            BibEntry first = dups.get(0);
            BibEntry second = dups.get(1);

            if (!result.isToRemove(first) && !result.isToRemove(second)) {
                // Check if they are exact duplicates:
                boolean askAboutExact = false;
                if (DuplicateCheck.compareEntriesStrictly(first, second) > 1) {
                    if (autoRemoveExactDuplicates.get()) {
                        result.remove(second);
                        continue;
                    }
                    askAboutExact = true;
                }

                DuplicateResolverType resolverType = askAboutExact ? DuplicateResolverType.DUPLICATE_SEARCH_WITH_EXACT : DuplicateResolverType.DUPLICATE_SEARCH;

                DefaultTaskExecutor.runAndWaitInJavaFXThread(() -> askResolveStrategy(result, first, second, resolverType));
            }
        }

        return result;
    }

    private void askResolveStrategy(DuplicateSearchResult result, BibEntry first, BibEntry second, DuplicateResolverType resolverType) {
        DuplicateResolverDialog dialog = new DuplicateResolverDialog(first, second, resolverType, frame.getCurrentLibraryTab().getBibDatabaseContext(), stateManager);

        dialog.titleProperty().bind(Bindings.concat(dialog.getTitle()).concat(" (").concat(duplicateProgress.getValue()).concat("/").concat(duplicateTotal).concat(")"));

        DuplicateResolverResult resolverResult = dialogService.showCustomDialogAndWait(dialog)
                                                              .orElse(DuplicateResolverResult.BREAK);

        if ((resolverResult == DuplicateResolverResult.KEEP_LEFT)
                || (resolverResult == DuplicateResolverResult.AUTOREMOVE_EXACT)) {
            result.remove(second);
            if (resolverResult == DuplicateResolverResult.AUTOREMOVE_EXACT) {
                autoRemoveExactDuplicates.set(true); // Remember choice
            }
        } else if (resolverResult == DuplicateResolverResult.KEEP_RIGHT) {
            result.remove(first);
        } else if (resolverResult == DuplicateResolverResult.BREAK) {
            libraryAnalyzed.set(true);
            duplicates.clear();
        } else if (resolverResult == DuplicateResolverResult.KEEP_MERGE) {
            result.replace(first, second, dialog.getMergedEntry());
        }
    }

    private void handleDuplicates(DuplicateSearchResult result) {
        if (result == null) {
            return;
        }

        LibraryTab libraryTab = frame.getCurrentLibraryTab();
        final NamedCompound compoundEdit = new NamedCompound(Localization.lang("duplicate removal"));
        // Now, do the actual removal:
        if (!result.getToRemove().isEmpty()) {
            compoundEdit.addEdit(new UndoableRemoveEntries(libraryTab.getDatabase(), result.getToRemove()));
            libraryTab.getDatabase().removeEntries(result.getToRemove());
            libraryTab.markBaseChanged();
        }
        // and adding merged entries:
        if (!result.getToAdd().isEmpty()) {
            compoundEdit.addEdit(new UndoableInsertEntries(libraryTab.getDatabase(), result.getToAdd()));
            libraryTab.getDatabase().insertEntries(result.getToAdd());
            libraryTab.markBaseChanged();
        }

        duplicateProgress.set(0);

        dialogService.notify(Localization.lang("Duplicates found") + ": " + duplicateCount.get() + ' '
                + Localization.lang("pairs processed") + ": " + result.getDuplicateCount());
        compoundEdit.end();
        libraryTab.getUndoManager().addEdit(compoundEdit);
    }

    /**
     * Result of a duplicate search.
     * Uses {@link System#identityHashCode(Object)} for identifying objects for removal, as completely identical
     * {@link BibEntry BibEntries} are equal to each other.
     */
    static class DuplicateSearchResult {

        private final Map<Integer, BibEntry> toRemove = new HashMap<>();
        private final List<BibEntry> toAdd = new ArrayList<>();

        private int duplicates = 0;

        public synchronized List<BibEntry> getToRemove() {
            return new ArrayList<>(toRemove.values());
        }

        public synchronized List<BibEntry> getToAdd() {
            return toAdd;
        }

        public synchronized void remove(BibEntry entry) {
            toRemove.put(System.identityHashCode(entry), entry);
            duplicates++;
        }

        public synchronized void replace(BibEntry first, BibEntry second, BibEntry replacement) {
            remove(first);
            remove(second);
            toAdd.add(replacement);
            duplicates++;
        }

        public synchronized boolean isToRemove(BibEntry entry) {
            return toRemove.containsKey(System.identityHashCode(entry));
        }

        public synchronized int getDuplicateCount() {
            return duplicates;
        }
    }
}


text:
@interface MaximumSpacingFlowLayout : UICollectionViewFlowLayout

@end


text:
layout: topic
title:  "Special topics in DC analysis"
author: Willy McAllister
comments: true
---

Special topics in DC circuit analysis. How circuits become equations.
Linearity and superposition. Transforming sources. Thévenin and Norton equivalents.

----

[![]({% link i/article.svg %}) How circuits become equations]({% link _articles/how-circuits-become-equations.md %})

[![]({% link i/article.svg %}) Linearity]({% link _articles/linearity.md %})

[![]({% link i/article.svg %}) Linearity of electronic components]({% link _articles/linearity-RLC.md %})

[![]({% link i/article.svg %}) Superposition]({% link _articles/superposition.md %})

[![]({% link i/article.svg %}) Source transformation]({% link _articles/source-transformation.md %})

[![]({% link i/article.svg %}) Source transformation — example]({% link _articles/source-transformation-example.md %})

[![]({% link i/article.svg %}) Thévenin's theorem — proof]({% link _articles/thevenin-proof.md %})

[![]({% link i/article.svg %}) Thévenin's theorem — how to]({% link _articles/thevenin-howto.md %})

---

 [DC analysis]({% link _topics/topic-dc-analysis.md %}) $\qquad$ [Natural and forced response]({% link _topics/topic-natural-and-forced-response.md %})

---


text:
use input::{Input, InputAt, CharInput};
use program::{Inst, InstIdx, Program};
use re::CaptureIdxs;

type Bits = u32;
const BIT_SIZE: usize = 32;
const MAX_PROG_SIZE: usize = 100;
const MAX_INPUT_SIZE: usize = 256 * (1 << 10);

// Total memory usage in bytes is determined by:
//
//   ((len(insts) * (len(input) + 1) + bits - 1) / bits) / (bits / 8)
//
// With the above settings, this comes out to ~3.2MB. Mostly these numbers
// were picked empirically with suspicious benchmarks.

/// A backtracking matching engine.
#[derive(Debug)]
pub struct Backtrack<'r, 't, 'c> {
    prog: &'r Program,
    input: CharInput<'t>,
    caps: &'c mut CaptureIdxs,
    m: BackMachine,
}

/// Shared cached state between multiple invocations of a backtracking engine
/// in the same thread.
///
/// It is exported so that it can be cached by `program::Program`.
#[derive(Debug)]
pub struct BackMachine {
    jobs: Vec<Job>,
    visited: Vec<Bits>,
}

impl BackMachine {
    /// Create new empty state for the backtracking engine.
    pub fn new() -> BackMachine {
        BackMachine {
            jobs: vec![],
            visited: vec![],
        }
    }
}

/// A job is an explicit unit of stack space in the backtracking engine.
///
/// The "normal" representation is a single state transition, which corresponds
/// to an NFA state and a character in the input. However, the backtracking
/// engine must keep track of old capture group values. We use the explicit
/// stack to do it.
#[derive(Clone, Copy, Debug)]
enum Job {
    Inst { pc: InstIdx, at: InputAt },
    SaveRestore { slot: usize, old_pos: Option<usize> },
}

impl<'r, 't, 'c> Backtrack<'r, 't, 'c> {
    /// Execute the backtracking matching engine.
    ///
    /// If there's a match, `exec` returns `true` and populates the given
    /// captures accordingly.
    pub fn exec(
        prog: &'r Program,
        mut caps: &mut CaptureIdxs,
        text: &'t str,
        start: usize,
    ) -> bool {
        let input = CharInput::new(text);
        let start = input.at(start);
        let m = prog.backtrack.get();
        let mut b = Backtrack {
            prog: prog,
            input: input,
            caps: caps,
            m: m,
        };
        let matched = b.exec_(start);
        prog.backtrack.put(b.m);
        matched
    }

    /// Returns true iff the given regex and input can be executed by this
    /// engine with reasonable memory usage.
    pub fn should_exec(prog: &'r Program, input: &str) -> bool {
        prog.insts.len() <= MAX_PROG_SIZE && input.len() <= MAX_INPUT_SIZE
    }

    fn clear(&mut self) {
        // Reset the job memory so that we start fresh.
        self.m.jobs.truncate(0);

        // Now we need to clear the bit state set.
        // We do this by figuring out how much space we need to keep track
        // of the states we've visited.
        // Then we reset all existing allocated space to 0.
        // Finally, we request more space if we need it.
        //
        // This is all a little circuitous, but doing this unsafely
        // doesn't seem to have a measurable impact on performance.
        // (Probably because backtracking is limited to such small
        // inputs/regexes in the first place.)
        let visited_len =
            (self.prog.insts.len() * (self.input.len() + 1) + BIT_SIZE - 1)
            /
            BIT_SIZE;
        for v in &mut self.m.visited {
            *v = 0;
        }
        let cur_visited_cap = self.m.visited.capacity();
        if visited_len > cur_visited_cap {
            self.m.visited.reserve_exact(visited_len - cur_visited_cap);
            for _ in 0..(visited_len - cur_visited_cap) {
                self.m.visited.push(0);
            }
        }
    }

    fn exec_(&mut self, mut at: InputAt) -> bool {
        self.clear();
        if self.prog.anchored_begin {
            return if !at.is_beginning() {
                false
            } else {
                match self.input.prefix_at(&self.prog.prefixes, at) {
                    None => false,
                    Some(at) => self.backtrack(at),
                }
            };
        }
        loop {
            if !self.prog.prefixes.is_empty() {
                at = match self.input.prefix_at(&self.prog.prefixes, at) {
                    None => return false,
                    Some(at) => at,
                };
            }
            if self.backtrack(at) {
                return true;
            }
            if at.char().is_none() {
                return false;
            }
            at = self.input.at(at.next_pos());
        }
    }

    // This `inline(always)` seems to result in about a 10-15% increase in
    // throughput on the `hard` benchmarks (over a standard `inline`). ---AG
    #[inline(always)]
    fn backtrack(&mut self, start: InputAt) -> bool {
        self.push(0, start);
        while let Some(job) = self.m.jobs.pop() {
            match job {
                Job::Inst { pc, at } => {
                    if self.step(pc, at) {
                        return true;
                    }
                }
                Job::SaveRestore { slot, old_pos } => {
                    self.caps[slot] = old_pos;
                }
            }
        }
        false
    }

    fn step(&mut self, mut pc: InstIdx, mut at: InputAt) -> bool {
        use program::Inst::*;
        loop {
            // This loop is an optimization to avoid constantly pushing/popping
            // from the stack. Namely, if we're pushing a job only to run it
            // next, avoid the push and just mutate `pc` (and possibly `at`)
            // in place.
            match self.prog.insts[pc] {
                Match => return true,
                Save(slot) => {
                    if slot < self.caps.len() {
                        // If this path doesn't work out, then we save the old
                        // capture index (if one exists) in an alternate
                        // job. If the next path fails, then the alternate
                        // job is popped and the old capture index is restored.
                        let old_pos = self.caps[slot];
                        self.push_save_restore(slot, old_pos);
                        self.caps[slot] = Some(at.pos());
                    }
                    pc += 1;
                }
                Jump(pc2) => pc = pc2,
                Split(x, y) => {
                    self.push(y, at);
                    pc = x;
                }
                EmptyLook(ref inst) => {
                    let prev = self.input.previous_at(at.pos());
                    if inst.matches(prev.char(), at.char()) {
                        pc += 1;
                    } else {
                        return false;
                    }
                }
                Char(c) => {
                    if c == at.char() {
                        pc += 1;
                        at = self.input.at(at.next_pos());
                    } else {
                        return false;
                    }
                }
                Ranges(ref inst) => {
                    if inst.matches(at.char()) {
                        pc += 1;
                        at = self.input.at(at.next_pos());
                    } else {
                        return false;
                    }
                }
            }
            if self.has_visited(pc, at) {
                return false;
            }
        }
    }

    fn push(&mut self, pc: InstIdx, at: InputAt) {
        self.m.jobs.push(Job::Inst { pc: pc, at: at });
    }

    fn push_save_restore(&mut self, slot: usize, old_pos: Option<usize>) {
        self.m.jobs.push(Job::SaveRestore { slot: slot, old_pos: old_pos });
    }

    fn has_visited(&mut self, pc: InstIdx, at: InputAt) -> bool {
        let k = pc * (self.input.len() + 1) + at.pos();
        let k1 = k / BIT_SIZE;
        let k2 = (1 << (k & (BIT_SIZE - 1))) as Bits;
        if self.m.visited[k1] & k2 == 0 {
            self.m.visited[k1] |= k2;
            false
        } else {
            true
        }
    }
}


text:
from sure import this
from steadymark.core import SteadyMark

def test_find_python_code_with_titles():
    ("SteadyMark should find python code and use the " "previous header as title")

    md = """# test 1
a paragraph

```python
assert False, 'boom!'
```

# not a test

foobar

```ruby
ruby no!
```

# another part

## test 2

a paragraph

```python
assert False, 'uh yeah'
```
    """

    sm = SteadyMark.inspect(md)

    sm.tests.should.have.length_of(2)

    test1, test2 = sm.tests

    test1.title.should.equal("test 1")
    test1.raw_code.should.equal("assert False, 'boom!'")
    eval.when.called_with(test1.code).should.throw(AssertionError, "boom!")

    test2.title.should.equal("test 2")
    test2.raw_code.should.equal("assert False, 'uh yeah'")
    eval.when.called_with(test2.code).should.throw(AssertionError, "uh yeah")

def test_find_inline_doctests_with_titles():
    ("SteadyMark should find docstrings and use the " "previous header as title")

    md = """# test 1
a paragraph

```python
>>> x = 'doc'
>>> y = 'test'
>>> assert (x + y) == 'doctest'
```

# not a test

foobar

```ruby
ruby no!
```

# another part

## test 2

a paragraph

```python
assert False, 'uh yeah'
```
    """

    sm = SteadyMark.inspect(md)

    sm.tests.should.have.length_of(2)

    test1, test2 = sm.tests

    test1.title.should.equal("test 1")
    test1.raw_code.should.equal(
        ">>> x = 'doc'\n" ">>> y = 'test'\n" ">>> assert (x + y) == 'doctest'"
    )

    this(test1.code).should.be.a("doctest.DocTest")
    test1.run()
    test2.title.should.equal("test 2")
    test2.raw_code.should.equal("assert False, 'uh yeah'")
    eval.when.called_with(test2.code).should.throw(AssertionError, "uh yeah")

def test_use_same_title_for_all_tests():
    ("SteadyMark should find all the tests under the same header (title)")

    md = """# Test Foo
a paragraph

```python
assert False, 'FIRST'
```

```python
assert False, 'SECOND'
```

```python
assert False, 'THIRD'
```

    """

    sm = SteadyMark.inspect(md)

    sm.tests.should.have.length_of(3)

    test1, test2, test3 = sm.tests

    test1.title.should.equal("Test Foo #1")
    eval.when.called_with(test1.code).should.throw(AssertionError, "FIRST")

    test2.title.should.equal("Test Foo #2")
    eval.when.called_with(test2.code).should.throw(AssertionError, "SECOND")

    test3.title.should.equal("Test Foo #3")
    eval.when.called_with(test3.code).should.throw(AssertionError, "THIRD")

def test_skip_tests_marked_with_ignore():
    ("SteadyMark should skip tests with the 'ignore' modeline")

    md = """# My test
```python
# steadymark: ignore
This should break, but it won't because steady mark will ignore this
```

# Another test
```python
>>> 1 + 1
2
```
"""
    sm = SteadyMark.inspect(md)
    sm.tests.should.have.length_of(1)
    sm.tests[0].title.should.be.equal("Another test")


text:
var overpass = require('query-overpass'),
    fs = require('fs'),
    csv = require('ya-csv');

var countries = [], c = 18, r = 0, buffer = {lat:0.03, lng:0.09}, rfolder = ["highway","building"];

var reader = csv.createCsvFileReader('../data/countries.csv', { columnsFromHeader: true });
reader.addListener('data', function(data) {
	countries.push(data);
});

reader.addListener('end', function() {
	buildQuery();
});

function buildQuery(){

	countries[c].longitude = parseFloat(countries[c].longitude);
	countries[c].latitude = parseFloat(countries[c].latitude);

	var bbox = '('+
		(countries[c].latitude -buffer.lat/2)+','+
		(countries[c].longitude-buffer.lng/2)+','+
		(countries[c].latitude +buffer.lat/2)+','+
		(countries[c].longitude+buffer.lng/2)+')';

	var query = '[out:json];(';
	if(r === 0){
		query += 'way["highway"]'+bbox+';>;';
	}else{
		query += 'way["building"]'+bbox+';>;';
	}
	query += ');out;';

	overpass(query, function(err, data){
		if(err){
			console.log(query);
			console.log(err);
			if(err.statusCode === 429){
				buildQuery();
			}
		}else{
			var outputFilename = "../data/"+rfolder[r]+"/"+countries[c].cca3+".min.geojson";
			fs.writeFile(outputFilename, JSON.stringify(data), function(err) {
				console.log("done:",countries[c].name,r);
				nextQuery();
			});
		}
	});
}

function nextQuery(){
	r++;
	if(r>1){
		r = 0;
		c++;
		if(c>=countries.length){
			process.exit();
		}else{
			buildQuery();
		}
	}else{
		buildQuery();
	}
}


text:
'''
Created by auto_sdk on 2014-12-17 17:22:51
'''
from top.api.base import RestApi
class WlbItemCombinationDeleteRequest(RestApi):
	def __init__(self,domain='gw.api.taobao.com',port=80):
		RestApi.__init__(self,domain, port)
		self.dest_item_list = None
		self.item_id = None

	def getapiname(self):
		return 'taobao.wlb.item.combination.delete'


text:
package com.alibaba.csp.sentinel.cluster.client.codec;

import com.alibaba.csp.sentinel.spi.SpiLoader;
import com.alibaba.csp.sentinel.cluster.codec.request.RequestEntityWriter;
import com.alibaba.csp.sentinel.cluster.codec.response.ResponseEntityDecoder;
import com.alibaba.csp.sentinel.log.RecordLog;

/**
 * @author Eric Zhao
 * @since 1.4.0
 */
public final class ClientEntityCodecProvider {

    private static RequestEntityWriter requestEntityWriter = null;
    private static ResponseEntityDecoder responseEntityDecoder = null;

    static {
        resolveInstance();
    }

    private static void resolveInstance() {
        RequestEntityWriter writer = SpiLoader.of(RequestEntityWriter.class).loadFirstInstance();
        if (writer == null) {
            RecordLog.warn("[ClientEntityCodecProvider] No existing request entity writer, resolve failed");
        } else {
            requestEntityWriter = writer;
            RecordLog.info("[ClientEntityCodecProvider] Request entity writer resolved: {}",
                requestEntityWriter.getClass().getCanonicalName());
        }
        ResponseEntityDecoder decoder = SpiLoader.of(ResponseEntityDecoder.class).loadFirstInstance();
        if (decoder == null) {
            RecordLog.warn("[ClientEntityCodecProvider] No existing response entity decoder, resolve failed");
        } else {
            responseEntityDecoder = decoder;
            RecordLog.info("[ClientEntityCodecProvider] Response entity decoder resolved: {}",
                responseEntityDecoder.getClass().getCanonicalName());
        }
    }

    public static RequestEntityWriter getRequestEntityWriter() {
        return requestEntityWriter;
    }

    public static ResponseEntityDecoder getResponseEntityDecoder() {
        return responseEntityDecoder;
    }

    private ClientEntityCodecProvider() {}
}


text:
package org.ovirt.engine.core.bll.scheduling.policyunits;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl;
import org.ovirt.engine.core.bll.scheduling.pending.PendingResourceManager;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.scheduling.PolicyUnit;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.compat.Guid;

public class NoneBalancePolicyUnit extends PolicyUnitImpl {

    public NoneBalancePolicyUnit(PolicyUnit policyUnit,
            PendingResourceManager pendingResourceManager) {
        super(policyUnit, pendingResourceManager);
    }

    @Override
    public Pair<List<Guid>, Guid> balance(VDSGroup cluster,
            List<VDS> hosts,
            Map<String, String> parameters,
            ArrayList<String> messages) {
        return null;
    }
}


text:
package model.battlefield.army.components;

import java.util.ArrayList;
import java.util.logging.Logger;

/**
 * Set of weapons and turrets of a unit.
 *
 * the role of this class is mainly to manage all weapons as one.
 *
 */
public class Arming {
	private static final Logger logger = Logger.getLogger(Mover.class.getName());
	Unit holder;
	ArrayList<Weapon> weapons = new ArrayList<>();
	ArrayList<Turret> turrets = new ArrayList<>();

	boolean aiming;
	boolean onScan;
	boolean atRange;

	public Arming(Unit holder){
		this.holder = holder;
	}

	protected void updateWeapons(){
		onScan = false;
		atRange = false;
		for(Weapon w : weapons){
			w.update(holder.faction.getEnemies().get(0).getUnits());
			if(w.isAtRange()) {
				atRange = true;
			}
			if(w.scanning()) {
				onScan = true;
			}
		}
		aiming = false;
	}

	protected void updateTurrets(double elapsedTime, boolean holderIsMoving){
		for(Turret t : turrets) {
			t.update(elapsedTime, holderIsMoving);
		}
	}

	public boolean isAiming(){
		return aiming;
	}

	protected boolean hasTurret(){
		return !turrets.isEmpty();
	}

	public boolean scanning(){
		return onScan;
	}

	public boolean acquiring(){
		return atRange;
	}

	public boolean acquiring(Unit unit){
		for(Weapon w : weapons) {
			if(w.hasTargetAtRange(unit)) {
				return true;
			}
		}
		return false;
	}

	public void attack(){
		if(!atRange) {
			throw new RuntimeException("Asking to attack but no target at range.");
		}
		aiming = true;
		for(Weapon w : weapons) {
			if(w.isAtRange()) {
				w.attack();
			}
		}
	}

	public void attack(Unit unit){
		aiming = true;
		boolean found = false;
		for(Weapon w : weapons) {
			if(w.hasTargetAtRange(unit)){
				w.attack(unit);
				found = true;
			}
		}
		if(!found) {
			throw new IllegalArgumentException("Specific unit to attack is not at range.");
		}
	}

	public Unit getNearestScanned(){
		Unit res = null;
		for(Weapon w : weapons) {
			if(w.getTarget() != null) {
				res = res == null? w.getTarget():holder.getNearest(res, w.getTarget());
			}
		}
		if(res == null) {
			throw new RuntimeException("Asking the nearest scanned but nothing on scan.");
		}
		return res;
	}

}