text:
// "Therefore those skilled at the unorthodox
// are infinite as heaven and earth,
// inexhaustible as the great rivers.
// When they come to an end,
// they begin again,
// like the days and months;
// they die and are reborn,
// like the four seasons."
//
// - Sun Tsu,
// "The Art of War"

using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System;
using TheArtOfDev.HtmlRenderer.Core;
using TheArtOfDev.HtmlRenderer.Core.Entities;
using TheArtOfDev.HtmlRenderer.Core.Utils;
using TheArtOfDev.HtmlRenderer.PdfSharp.Adapters;

namespace TheArtOfDev.HtmlRenderer.PdfSharp
{
    ///
    /// TODO:a add doc
    ///
    public static class PdfGenerator
    {
        ///
        /// Adds a font mapping from <paramref name="fromFamily"/> to <paramref name="toFamily"/> iff the <paramref name="fromFamily"/> is not found.

        /// When the <paramref name="fromFamily"/> font is used in rendered html and is not found in existing
        /// fonts (installed or added) it will be replaced by <paramref name="toFamily"/>.

        ///
        /// <remarks>
        /// This fonts mapping can be used as a fallback in case the requested font is not installed in the client system.
        /// </remarks>
        /// <param name="fromFamily">the font family to replace</param>
        /// <param name="toFamily">the font family to replace with</param>
        public static void AddFontFamilyMapping(string fromFamily, string toFamily)
        {
            ArgChecker.AssertArgNotNullOrEmpty(fromFamily, "fromFamily");
            ArgChecker.AssertArgNotNullOrEmpty(toFamily, "toFamily");

            PdfSharpAdapter.Instance.AddFontFamilyMapping(fromFamily, toFamily);
        }

        ///
        /// Parse the given stylesheet to <see cref="CssData"/> object.

        /// If <paramref name="combineWithDefault"/> is true the parsed css blocks are added to the
        /// default css data (as defined by W3), merged if class name already exists. If false only the data in the given stylesheet is returned.
        ///
        /// <seealso cref="http://www.w3.org/TR/CSS21/sample.html"/>
        /// <param name="stylesheet">the stylesheet source to parse</param>
        /// <param name="combineWithDefault">true - combine the parsed css data with default css data, false - return only the parsed css data</param>
        /// <returns>the parsed css data</returns>
        public static CssData ParseStyleSheet(string stylesheet, bool combineWithDefault = true)
        {
            return CssData.Parse(PdfSharpAdapter.Instance, stylesheet, combineWithDefault);
        }

        ///
        /// Create PDF document from given HTML.

        ///
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="pageSize">the page size to use for each page in the generated pdf </param>
        /// <param name="margin">the margin to use between the HTML and the edges of each page</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static PdfDocument GeneratePdf(string html, PageSize pageSize, int margin = 20, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            var config = new PdfGenerateConfig();
            config.PageSize = pageSize;
            config.SetMargins(margin);
            return GeneratePdf(html, config, cssData, stylesheetLoad, imageLoad);
        }

        ///
        /// Create PDF document from given HTML.

        ///
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static PdfDocument GeneratePdf(string html, PdfGenerateConfig config, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            // create PDF document to render the HTML into
            var document = new PdfDocument();

            // add rendered PDF pages to document
            AddPdfPages(document, html, config, cssData, stylesheetLoad, imageLoad);

            return document;
        }

        ///
        /// Create PDF pages from given HTML and appends them to the provided PDF document.

        ///
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="pageSize">the page size to use for each page in the generated pdf </param>
        /// <param name="margin">the margin to use between the HTML and the edges of each page</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static void AddPdfPages(PdfDocument document, string html, PageSize pageSize, int margin = 20, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            var config = new PdfGenerateConfig();
            config.PageSize = pageSize;
            config.SetMargins(margin);
            AddPdfPages(document, html, config, cssData, stylesheetLoad, imageLoad);
        }

        ///
        /// Create PDF pages from given HTML and appends them to the provided PDF document.

        ///
        /// <param name="document">PDF document to append pages to</param>
        /// <param name="html">HTML source to create PDF from</param>
        /// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
        /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
        /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
        /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
        /// <returns>the generated image of the html</returns>
        public static void AddPdfPages(PdfDocument document, string html, PdfGenerateConfig config, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
        {
            XSize orgPageSize;
            // get the size of each page to layout the HTML in
            if (config.PageSize != PageSize.Undefined)
                orgPageSize = PageSizeConverter.ToSize(config.PageSize);
            else
                orgPageSize = config.ManualPageSize;

            if (config.PageOrientation == PageOrientation.Landscape)
            {
                // invert pagesize for landscape
                orgPageSize = new XSize(orgPageSize.Height, orgPageSize.Width);
            }

            var pageSize = new XSize(orgPageSize.Width - config.MarginLeft - config.MarginRight, orgPageSize.Height - config.MarginTop - config.MarginBottom);

            if (!string.IsNullOrEmpty(html))
            {
                using (var container = new HtmlContainer())
                {
                    if (stylesheetLoad != null)
                        container.StylesheetLoad += stylesheetLoad;
                    if (imageLoad != null)
                        container.ImageLoad += imageLoad;

                    container.Location = new XPoint(config.MarginLeft, config.MarginTop);
                    container.MaxSize = new XSize(pageSize.Width, 0);
                    container.SetHtml(html, cssData);
                    container.PageSize = pageSize;
                    container.MarginBottom = config.MarginBottom;
                    container.MarginLeft = config.MarginLeft;
                    container.MarginRight = config.MarginRight;
                    container.MarginTop = config.MarginTop;

                    // layout the HTML with the page width restriction to know how many pages are required
                    using (var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards))
                    {
                        container.PerformLayout(measure);
                    }

                    // while there is un-rendered HTML, create another PDF page and render with proper offset for the next page
                    double scrollOffset = 0;
                    while (scrollOffset > -container.ActualSize.Height)
                    {
                        var page = document.AddPage();
                        page.Height = orgPageSize.Height;
                        page.Width = orgPageSize.Width;

                        using (var g = XGraphics.FromPdfPage(page))
                        {
                            //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height));
                            g.IntersectClip(new XRect(0, 0, page.Width, page.Height));

                            container.ScrollOffset = new XPoint(0, scrollOffset);
                            container.PerformPaint(g);
                        }
                        scrollOffset -= pageSize.Height;
                    }

                    // add web links and anchors
                    HandleLinks(document, container, orgPageSize, pageSize);
                }
            }
        }

        #region Private/Protected methods

        ///
        /// Handle HTML links by create PDF Documents link either to external URL or to another page in the document.
        ///
        private static void HandleLinks(PdfDocument document, HtmlContainer container, XSize orgPageSize, XSize pageSize)
        {
            foreach (var link in container.GetLinks())
            {
                int i = (int)(link.Rectangle.Top / pageSize.Height);
                for (; i < document.Pages.Count && pageSize.Height * i < link.Rectangle.Bottom; i++)
                {
                    var offset = pageSize.Height * i;

                    // fucking position is from the bottom of the page
                    var xRect = new XRect(link.Rectangle.Left, orgPageSize.Height - (link.Rectangle.Height + link.Rectangle.Top - offset), link.Rectangle.Width, link.Rectangle.Height);

                    if (link.IsAnchor)
                    {
                        // create link to another page in the document
                        var anchorRect = container.GetElementRectangle(link.AnchorId);
                        if (anchorRect.HasValue)
                        {
                            // document links to the same page as the link is not allowed
                            int anchorPageIdx = (int)(anchorRect.Value.Top / pageSize.Height);
                            if (i != anchorPageIdx)
                                document.Pages[i].AddDocumentLink(new PdfRectangle(xRect), anchorPageIdx);
                        }
                    }
                    else
                    {
                        // create link to URL
                        document.Pages[i].AddWebLink(new PdfRectangle(xRect), link.Href);
                    }
                }
            }
        }

        #endregion
    }
}


text:
import sys
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, QAction, QMessageBox
from PyQt5.QtWidgets import QCalendarWidget, QFontDialog, QColorDialog, QTextEdit, QFileDialog
from PyQt5.QtWidgets import QCheckBox, QProgressBar, QComboBox, QLabel, QStyleFactory, QLineEdit, QInputDialog

class window(QMainWindow):

    def __init__(self):
        super(window, self).__init__()
        self.setGeometry(50, 50, 800, 500)
        self.setWindowTitle('pyqt5 Tut')
        self.setWindowIcon(QIcon('pic.png'))

        extractAction = QAction('&Get to the choppah', self)
        extractAction.setShortcut('Ctrl+Q')
        extractAction.setStatusTip('leave the app')
        extractAction.triggered.connect(self.close_application)

        openEditor = QAction('&Editor', self)
        openEditor.setShortcut('Ctrl+E')
        openEditor.setStatusTip('Open Editor')
        openEditor.triggered.connect(self.editor)

        openFile = QAction('&Open File', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open File')
        openFile.triggered.connect(self.file_open)

        saveFile = QAction('&Save File', self)
        saveFile.setShortcut('Ctrl+S')
        saveFile.setStatusTip('Save File')
        saveFile.triggered.connect(self.file_save)

        self.statusBar()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&File')
        fileMenu.addAction(extractAction)

        fileMenu.addAction(openFile)
        fileMenu.addAction(saveFile)

        editorMenu = mainMenu.addMenu('&Editor')
        editorMenu.addAction(openEditor)

        extractAction = QAction(QIcon('pic.png'), 'flee the scene', self)
        extractAction.triggered.connect(self.close_application)
        self.toolBar = self.addToolBar('extraction')
        self.toolBar.addAction(extractAction)

        fontChoice = QAction('Font', self)
        fontChoice.triggered.connect(self.font_choice)
        # self.toolBar = self.addToolBar('Font')
        self.toolBar.addAction(fontChoice)

        cal = QCalendarWidget(self)
        cal.move(500, 200)
        cal.resize(200, 200)

        self.home()

    def editor(self):
        self.textEdit = QTextEdit()
        self.setCentralWidget(self.textEdit)

    def file_open(self):
        # need to make name an tupple otherwise i had an error and app crashed
        name, _ = QFileDialog.getOpenFileName(self, 'Open File', options=QFileDialog.DontUseNativeDialog)
        print('tot na dialog gelukt')  # for debugging
        file = open(name, 'r')
        print('na het inlezen gelukt') # for debugging
        self.editor()

        with file:
            text = file.read()
            self.textEdit.setText(text)

    def file_save(self):
        name, _ = QFileDialog.getSaveFileName(self,'Save File', options=QFileDialog.DontUseNativeDialog)
        file = open(name, 'w')
        text = self.textEdit.toPlainText()
        file.write(text)
        file.close()

    def color_picker(self):
        color = QColorDialog.getColor()
        self.styleChoice.setStyleSheet('QWidget{background-color: %s}' % color.name())

    def font_choice(self):
        font, valid = QFontDialog.getFont()
        if valid:
            self.styleChoice.setFont(font)

    def home(self):
        btn = QPushButton('quit', self)
        btn.clicked.connect(self.close_application)
        btn.resize(btn.sizeHint())
        btn.move(0, 100)

        checkBox = QCheckBox('Enlarge window', self)
        # checkBox.toggle()  # if you want to be checked in in the begin
        checkBox.move(0, 50)
        checkBox.stateChanged.connect(self.enlarge_window)

        self.progress = QProgressBar(self)
        self.progress.setGeometry(200, 80, 250, 20)

        self.btn = QPushButton('download', self)
        self.btn.move(200, 120)
        self.btn.clicked.connect(self.download)

        self.styleChoice = QLabel('Windows', self)
        comboBox = QComboBox(self)
        comboBox.addItem('motif')
        comboBox.addItem('Windows')
        comboBox.addItem('cde')
        comboBox.addItem('Plastique')
        comboBox.addItem('Cleanlooks')
        comboBox.addItem('windowsvista')

        comboBox.move(25, 250)
        self.styleChoice.move(25, 150)
        comboBox.activated[str].connect(self.style_choice)

        color = QColor(0,0,0)
        fontColer = QAction('font bg color', self)
        fontColer.triggered.connect(self.color_picker)
        self.toolBar.addAction(fontColer)

        self.show()

    def style_choice(self, text):
        self.styleChoice.setText(text)
        QApplication.setStyle(QStyleFactory.create(text))

    def download(self):
        self.completed = 0

        while self.completed < 100:
            self.completed += 0.0001
            self.progress.setValue(self.completed)

    def enlarge_window(self, state):
        if state == Qt.Checked:
            self.setGeometry(50, 50, 1000, 600)
        else:
            self.setGeometry(50, 50 , 500, 300)

    def close_application(self):

        choice = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)

        if choice == QMessageBox.Yes:
            print('quit application')
            sys.exit()
        else:
            pass

if __name__ == "__main__":  # had to add this otherwise app crashed

    def run():
        app = QApplication(sys.argv)
        Gui = window()
        sys.exit(app.exec_())

run()

redpajama_set_name: RedPajamaGithub


text:
using System.Text.Json;
using Azure.Core;

namespace Azure.ResourceManager.EventHubs.Models
{
    public partial class CheckNameAvailabilityResult
    {
        internal static CheckNameAvailabilityResult DeserializeCheckNameAvailabilityResult(JsonElement element)
        {
            string message = default;
            bool? nameAvailable = default;
            UnavailableReason? reason = default;
            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("message"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    message = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("nameAvailable"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    nameAvailable = property.Value.GetBoolean();
                    continue;
                }
                if (property.NameEquals("reason"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        continue;
                    }
                    reason = property.Value.GetString().ToUnavailableReason();
                    continue;
                }
            }
            return new CheckNameAvailabilityResult(message, nameAvailable, reason);
        }
    }
}


text:
'use strict';

const OptimizeCmd = require('../../lib/cmds/optimize.js');
const AmpOptimizer = require('@ampproject/toolbox-optimizer');
const MockLogger = require('../helpers/MockLogger');

describe('optimize', () => {
  let input;
  let inputUrl;
  let mockLogger;
  let mockLoader;

  beforeEach(async () => {
    mockLogger = new MockLogger();
    mockLoader = (url) => {
      inputUrl = url;
      return input;
    };
    const optimizeCmd = new OptimizeCmd(AmpOptimizer.create(), mockLoader);
    input = '<html amp></html>';
    await optimizeCmd.run({_: ['', 'https://example.com']}, mockLogger);
  });

  it('runs optimizer', () => {
    expect(mockLogger.getLogs().startsWith('<!doctype html><html amp i-amphtml-layout')).toBe(true);
  });
  it('loads url / path', () => {
    expect(inputUrl).toBe('https://example.com');
  });
});


text:
package org.jbox2d.dynamics.contacts;

import org.jbox2d.collision.Manifold;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.ShapeType;
import org.jbox2d.common.Transform;
import org.jbox2d.dynamics.Fixture;
import org.jbox2d.pooling.IWorldPool;

public class CircleContact extends Contact {

  public CircleContact(IWorldPool argPool) {
    super(argPool);
  }

  public void init(Fixture fixtureA, Fixture fixtureB) {
    super.init(fixtureA, 0, fixtureB, 0);
    assert (m_fixtureA.getType() == ShapeType.CIRCLE);
    assert (m_fixtureB.getType() == ShapeType.CIRCLE);
  }

  @Override
  public void evaluate(Manifold manifold, Transform xfA, Transform xfB) {
    pool.getCollision().collideCircles(manifold, (CircleShape) m_fixtureA.getShape(), xfA,
        (CircleShape) m_fixtureB.getShape(), xfB);
  }
}


text:
using JetBrains.Annotations;
using VkNet.Abstractions;
using VkNet.Model;
using VkNet.Utils;

namespace VkNet.Categories;

/// <inheritdoc />
public partial class StatusCategory : IStatusCategory
{
	private readonly IVkApiInvoke _vk;

	/// <summary>
	/// api vk.com
	/// </summary>
	/// <param name="vk"> </param>
	public StatusCategory(IVkApiInvoke vk) => _vk = vk;

	/// <inheritdoc />
	[Pure]
	public Status Get(long userId, long? groupId = null)
	{
		var parameters = new VkParameters
		{
			{
				"user_id", userId
			},
			{
				"group_id", groupId
			}
		};

		return _vk.Call("status.get", parameters);
	}

	/// <inheritdoc />
	public bool Set(string text, long? groupId = null)
	{
		var parameters = new VkParameters
		{
			{
				"text", text
			},
			{
				"group_id", groupId
			}
		};

		return _vk.Call("status.set", parameters);
	}
}


text:
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports Aspose.Cells.GridDesktop

Namespace WorkingWithRowsandColumns
	Public Partial Class AddInsertColumn
		Inherits Form
		Public Sub New()
			InitializeComponent()
		End Sub

		Private Sub button1_Click(sender As Object, e As EventArgs)
			' ExStart:AddColumn
			' Accessing first worksheet of the Grid
			Dim sheet As Worksheet = gridDesktop1.Worksheets(0)

			' Adding column to the worksheet
			sheet.AddColumn()
			' ExEnd:AddColumn
			MessageBox.Show("Column added.")
		End Sub

		Private Sub button2_Click(sender As Object, e As EventArgs)
			' ExStart:InsertColumn
			' Accessing first worksheet of the Grid
			Dim sheet As Worksheet = gridDesktop1.Worksheets(0)

			' Inserting column to the worksheet to the first position.
			gridDesktop1.Worksheets(0).InsertColumn(0)
			' ExEnd:InsertColumn
			MessageBox.Show("Column Inserted.")
		End Sub
	End Class
End Namespace


text:
title: Random Character Generation
---

Now use the rand function to make your own function for generating random
letters of the alphabet.  It should only generate lower case letters a-z.

We supply a function in MCPrelude called toLetter.  Use the toLetter function
to write this random letter function:

    randLetter :: Seed -> (Char, Seed)

Now use this function to write another function randString3 that generates a
random string of three letters using an initial seed of 1.

    randString3 :: String

When you use [this site](http://www.xorbin.com/tools/sha256-hash-calculator) to
calculate the SHA-256 hash of the output of randString3, you get
9d475eb78d3e38085220ed6ebde9d8f7d26540bb1c8f9382479c3acd4c8c94a3.


text:
package ibis.smartsockets.hub;

import ibis.smartsockets.direct.DirectSocketAddress;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class HubOutputStream extends DataOutputStream {

    public HubOutputStream(OutputStream out) {
        super(out);
    }

    public void writeSocketAddressSet(DirectSocketAddress a) throws IOException {

        byte [] codedForm = a.getAddress();

        writeInt(codedForm.length);
        write(codedForm);
    }

}


text:
<?php
	// Alteração da descrição da equipa
	print("
Alterar Descrição

".$data["description"]."
");

	// Membros da equipa de combate
	print("
Equipa de Combate

".$data["description"]."
");

	// Membros de Equipa
	print("
Membros de Equipa

Númear novo chefe

* Esta opção não poderá ser cancelada, esta fará com que outro jogador da Equipa passe a ter os teus poderes, e só essa pessoa te poderá os devolver utilizando o mesmo processo
");
	if (count($aux["members"]) > 1)
	{
		if (!isset($_POST["003-save"]))
		{
			echo "<form method=\"post\">

Seleccione novo Chefe:

				<select name=\"char\">
					<option value=\"null\">Selecciona um jogador</option>";
					for ($i = 0; $i < count($aux["members"]);$i++)
					{
						if ($aux["members"][$i] != $conta["game"]["id"])
						{echo "<option value=\"".$aux["members"][$i]."\">(".($i + 1).") ".return_charname($aux["members"][$i])."</option>";}
					}
				echo "</select>
				<button type=\"submit\" name=\"003-save\">Guardar</button>
				</form>";
		}
		else
		{
			if ($_POST["char"] == null) {echo "Para esta opção tens de escolher um jogador.";}
			else{
				$query = "UPDATE g_team SET owner_id_ass = '".$_POST["char"]."' WHERE id = '".$data["id"]."'";
				if (mysql_query($query) && $data["owner_id_ass"] == $conta["game"]["id"])
				{echo "
Operação efectuada com Sucesso!
";}
				else {echo "
Operação não efectuada!
";}
			}
		}
	}
	else{print("
Necessita de ter mais um jogador na equipa, para que esta opção seja desbloqueada.
");}

	print("");
?>


text:
=========
Customers
=========

This section describes the management interfaces of the ``Customers`` menu.

.. toctree::
   :maxdepth: 2

   customers.rst
   orders.rst
   carts.rst
   reviews.rst


text:
#ifndef __PAST_H__
#define __PAST_H__

#include <stdint.h>
#include <stdbool.h>

typedef enum {
	past_wifi_ssid = 10,
	past_wifi_pw,

	past_mqtt_server = 20,
	past_mqtt_port,
	past_mqtt_user,
	past_mqtt_pw,

	// Any id above 256 is free for the taking
	past_user_defined = 256
} past_t;

// Check if past if valid and return true if so
bool past_valid(void);

// Format past and return true if successful
bool past_format(void);

// Return size of past
uint32_t past_size(void);

// Read unit from past
// id - unit id
// data - pointer where unit data goes
// length - length of data buffer
// Returns true if unit was found and could be read
bool past_read_unit(past_t id, void *data, uint32_t length);

// Write unit to past
// id - unit id
// data - pointer where unit data goes
// length - length of data buffer
// Returns true if unit was found and could be read
bool past_write_unit(past_t id, void *data, uint32_t length);

// Erase unit from past
// id - unit id
// Returns true if unit was found and could be erased
bool past_erase_unit(past_t id);

// Debug: dump contents of past
void past_dump(void);

#endif // __PAST_H__


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<title>PF: Tradução do Endereço de Rede (NAT)</title>
<link rev="made" href="mailto:www@openbsd.org">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="resource-type" content="document">
<meta name="description"   content="the OpenBSD FAQ page">
<meta name="keywords"      content="openbsd,faq,pf">
<meta name="distribution"  content="global">

[Anterior: Filtragem de Pacotes]
[Conteúdo]
[Próximo: Redirecionamento de Tráfego
("Port Forwarding")]

PF: Tradução do Endereço de Rede (NAT)

Conteúdo

Introdução

Como Funciona a NAT

IP Forwarding

Configuração da NAT

Mapeamento Bidirecional (mapeamento 1:1)

Exceções em Regras de Tradução

Verificação do Status da NAT

Introdução

A Tradução do Endereço de Rede (NAT - "Network Address Translation") é
uma forma de mapear toda uma rede (ou redes) para apenas um endereço IP.
NAT é necessária quando o número de endereços IP atribuídos a você pelo
seu Provedor de Serviços de Internet é menor que o número total de
computadores para os quais você quer prover acesso à Internet.
NAT está descrita na
RFC 1631,
"The IP Network Address Translator (NAT)".

NAT permite que você faça uso dos blocos de endereços reservados
descritos na
RFC 1918,
"Address Allocation for Private Internets".
Tipicamente, sua rede interna é configurada com endereços IP de
um ou mais desses blocos de redes. São eles:

	10.0.0.0/8       (10.0.0.0 - 10.255.255.255)
	172.16.0.0/12    (172.16.0.0 - 172.31.255.255)
	192.168.0.0/16   (192.168.0.0 - 192.168.255.255)

Um sistema OpenBSD fazendo NAT deve ter ao menos duas interfaces de
rede, um para a Internet e outro para a rede interna. A NAT
traduz as requisições da rede interna de forma que elas pareçam
se originar do sistema OpenBSD fazendo NAT.

Como Funciona a NAT

Quando um cliente na rede interna procura uma máquina na Internet,
ele envia pacotes IP destinados a essa máquina. Esses pacotes contêm
toda a informação de endereçamento necessária para chegar a seu
destino. Informação pertinente à NAT:

Endereço IP de origem (por exemplo, 192.168.1.35)

Porta TCP ou UDP de origem (por exemplo, 2132)

Quando o pacote passa pelo gateway NAT, ele é alterado para que pareça
ter sido originado no próprio gateway. O gateway NAT registra então as
alterações feitas por ele em sua tabela de estados para que ele
possa a) reverter as alterações nos pacotes que retornam e b)
certificar-se de que os pacotes que retornam cruzem o firewall sem
serem bloqueados. Por exemplo, as seguintes alterações devem ser feitas:

Endereço IP de origem: substituído pelo endereço externo do gateway
(por exemplo, 24.5.0.5)

Porta de origem: substituída por uma porta disponível no gateway,
escolhida dinamicamente (por exemplo, 53136)

Nem a máquina interna nem a máquina na Internet percebem esse trabalho
de tradução. Para a máquina interna, o sistema de NAT é simplesmente um
gateway de Internet. Para a máquina na Internet, os pacotes parecem vir
diretamente do sistema NAT; ele nem mesmo suspeita da existência da
estação de trabalho interna.

Quando a máquina na Internet responde aos pacotes da máquina interna,
eles são endereçados ao IP externo do gateway NAT (24.5.0.5) na porta
da tradução (53136). O gateway NAT então pesquisa na sua tabela de
estados para determinar se os pacotes de resposta correspondem a uma
conexão já estabelecida. Uma ocorrência única será encontrada
baseando-se na combinação endereço IP/porta, que diz ao PF que os
pacotes pertencem à conexão iniciada pela máquina interna 192.168.1.35.
O PF então faz as alterações reversas feitas nos pacotes que
estabeleceram a conexão e transfere os pacotes de resposta para a
máquina interna.

A tradução de pacotes ICMP ocorre de maneira similar, mas sem alteração
da porta de origem.

IP Forwarding

Como a NAT é quase sempre usada em roteadores e gateways de rede,
provavelmente será necessário habilitar o IP forwarding para que
pacotes possam trafegar entre as interfaces de rede na máquina OpenBSD.
IP forwarding é habilitado usando o mecanismo
sysctl(3):

<tt>
# sysctl net.inet.ip.forwarding=1

# sysctl net.inet6.ip6.forwarding=1 (se estiver usando IPv6)
</tt>

Para que essa alteração seja permanente, as linhas a seguir devem ser
acrescentadas ao arquivo
<tt>/etc/sysctl.conf</tt>:

<tt>
net.inet.ip.forwarding=1

net.inet6.ip6.forwarding=1
</tt>

Essas linhas estão presentes, mas comentadas
(prefixadas por <tt>#</tt>). Remova o <tt>#</tt> e salve o arquivo.
O IP forwarding será habilitado quando a máquina for reinicializada.

Configuração da NAT

NOTA: Estas informações são relevantes apenas ao OpenBSD 4.7.
As configurações de NAT são significativamente diferentes nas versões mais atuais.

O uso de NAT é especificado através do uso do parâmetro opcional
<tt>nat-to</tt> atrelado a uma regra <tt>pass</tt> de saída.
Geralmente, em vez de ser definida diretamente numa regra
<tt>pass</tt>, uma regra de <tt>match</tt> é utilizada.

Quando um pacote é selecionado/marcado por uma regra <tt>match</tt>,
parâmetros (como o <tt>nat-to</tt>)presentes naquela regra são
armazenados e são aplicados ao pacote quando este pacote bate
com a regra de <tt>pass</tt>.

Isso permite que uma grande quantidade de pacotes seja gerenciada
por uma única regra <tt>match</tt> e então decisões específicas
podem ser aplicadas através de regras <tt>block</tt> ou <tt>pass</tt>.

Regras contidas no arquivo <tt>pf.conf</tt> teriam as seguintes sintaxes:

<tt>
match out on interface [af] \

   from src_addr to dst_addr \

   nat-to ext_addr [pool_type] [static-port]

...

pass out [log] on interface [af] [proto protocol] \

   from ext_addr [port src_port] \

   to dst_addr [port dst_port]</tt>

<tt>match</tt>

Quando um pacote atravessa o conjunto de regras e corresponde a uma
regra <tt>match</tt>, os parâmetros opcionais especificados nesta
referida serão lembrados para uso futuro (é adicionada uma espécie
de etiqueta).

<tt>pass</tt>

Esta regra permite que o pacote seja transmitido.
Se o pacote foi previamente marcado por uma regra <tt>match</tt> de acordo com
os parâmetros especificados, eles serão aplicados a este pacote.
Regras <tt>pass</tt> podem ter seus próprios parâmetros; estes parâmetros tomam
prioridade sobre os parâmetros especificados em uma regra <tt>match</tt>.

<tt>log</tt>

Pacotes que corresponderam são registrados via
pflogd(8).
Normalmente, apenas o primeiro pacote que corresponde é registrado.
Para registrar todos os pacotes que corresponderam, use
<tt>log (all)</tt>.

<tt>interface</tt>

O nome ou grupo da interface de rede onde os pacotes devem ser
transmitidos.

<tt>af</tt>

A família de endereços, <tt>inet</tt> para IPv4 ou
<tt>inet6</tt> para IPv6. Normalmente o PF pode determinar essa
informação com base no(s) endereço(s) de origem/destino.

<tt>protocol</tt>

O protocolo (ex.: tcp, udp ou icmp) utilizado pelo pacote.
Caso src_port ou dst_port sejam especificados, o protocolo
DEVE ser informado.

<tt>src_addr</tt>

O endereço de origem (interno) dos pacotes que serão
traduzidos. O endereço de origem pode ser especificado como:

Um endereço IPv4 ou IPv6 simples.

Um bloco de rede
    CIDR.

Um nome de domínio totalmente qualificado que será resolvido pelo
    DNS quando o conjunto de regras for carregado. Todos os endereços IP
    resultantes da pesquisa serão substituídos na regra.

O nome ou grupo de uma interface de rede. Quaisquer endereços IP
    na interface serão substituídos quando a regra for carregada.

O nome de uma interface de rede seguido de uma
    <tt>/máscara</tt> (por exemplo, <tt>/24</tt>). Cada endereço
    IP na interface é combinado com a máscara para formar um bloco de
    rede CIDR que será substituído na regra.

O nome ou grupo de uma interface de rede seguido de qualquer um
    destes modificadores:

<tt>:network</tt> - substitui o bloco de rede CIDR (por exemplo,
        192.168.0.0/24)

<tt>:broadcast</tt> - substitui o endereço de broadcast
        (por exemplo, 192.168.0.255)

<tt>:peer</tt> - substitui o endereço da outra ponta em um
        link ponto a ponto

Além disso, o modificador <tt>:0</tt> pode ser acrescentado a um
    nome/grupo de interface ou a qualquer um dos modificadores acima
    para dizer ao PF para não incluir apelidos de endereços IP na
    substituição.
    Esses modificadores também podem ser usados quando a interface está
    entre parêntesis.
    Exemplo: <tt>fxp0:network:0</tt>

Uma tabela.

Qualquer um dos apresentados acima, mas negado usando o modificador
    <tt>!</tt> ("não").

Um grupo de endereços usando-se uma
    lista.

A palavra-chave <tt>any</tt>, indicando todos os endereços

<tt>src_port</tt>

A porta de origem no cabeçalho da Camada 4 do pacote. Portas
são especificadas como:

Um número entre 1 e 65535

Um nome de serviço válido de
    <tt>/etc/services</tt>

Um grupo de portas usando-se uma
    lista

Uma faixa:

<tt>!=</tt> (diferente de)

<tt><</tt> (menor que)

<tt>></tt> (maior que)

<tt><=</tt> (menor ou igual a)

<tt>>=</tt> (maior ou igual a)

<tt>><</tt> (faixa)

<tt><></tt> (faixa inversa)

Os dois últimos são operadores binários (recebem dois
	argumentos) e não incluem os argumentos na faixa.

<tt>:</tt> (faixa inclusiva)

O operador de faixa inclusiva também é um operador binário
        e inclui os argumentos na faixa.

A opção <tt>port</tt> geralmente não é usada em regras <tt>nat</tt>
porque o objetivo geralmente é fazer NAT de todo o tráfego,
independente da(s) porta(s) sendo utilizada(s).

<tt>dst_addr</tt>

O endereço de destino dos pacotes a serem traduzidos.
Ele é especificado da mesma forma que o endereço de origem.

<tt>dst_port</tt>

A porta de destino no cabeçalho da Camada 4 do pacote. Essa porta
é especificada da mesma forma que a porta de origem.

<tt>ext_addr</tt>

O endereço externo (de tradução) do gateway NAT em que os pacotes
serão traduzidos. O endereço externo pode ser especificado como:

Um endereço IPv4 ou IPv6 simples.

Um bloco de rede
    CIDR.

Um nome de domínio totalmente qualificado que será resolvido pelo
    servidor DNS quando a regra for carregada.

O nome de uma interface ou de um grupo de interfaces da rede externa.
    Quaisquer endereços IP atribuídos à interface serão substituídos
    na regra quando for carregada.

O nome de uma interface ou de um grupo de interfaces da rede externa entre parêntesis
    <tt>( )</tt>. Isso informa ao PF para atualizar a regra caso o(s)
    endereço(s) da interface sofra(m) alterações. É muito útil quando a
    interface externa tem seu endereço IP atribuído via DHCP ou discada,
    pois o conjunto de regras não precisa ser recarregado toda vez que
    o endereço mudar.

O nome de uma interface ou de um grupo de interfaces de rede,
    seguidos de um destes modificadores:

<tt>:network</tt> - substitui o bloco de rede CIDR (por exemplo,
      192.168.0.0/24)

<tt>:peer</tt> - substitui o endereço IP da outra ponta em um
      link ponto a ponto

Além disso, o modificador <tt>:0</tt> pode ser acrescentado a um
  nome/grupo de interfaces ou a qualquer um dos modificadores acima para
  indicar que o PF não deve incluir apelidos de endereços IP na
  substituição.
  Esses modificadores também podem ser usados quando a interface está
  entre parêntesis.
  Exemplo: <tt>fxp0:network:0</tt>

Um grupo de endereços usando-se uma
    lista.

<tt>pool_type</tt>

Especifica o tipo de grupo de endereços a
usar para tradução.

<tt>static-port</tt>

Informa ao PF para não traduzir a porta de origem em pacotes TCP e
UDP.

Isso nos levaria à criação de regras básicas similares como estas:

<tt>
match out on tl0 from 192.168.1.0/24 to any nat-to 24.5.0.5

pass on tl0 from 192.168.1.0/24 to any
</tt>

ou você poderia simplesmente usar algo como:

<tt>
pass out on tl0 from 192.168.1.0/24 to any nat-to 24.5.0.5
</tt>

Essa regra diz para fazer NAT na interface <tt>tl0</tt> para quaisquer
pacotes vindos de 192.168.1.0/24 e substituir o endereço IP de origem
por 24.5.0.5.

Embora a regra acima esteja correta, essa forma de uso não é
recomendada.
A manutenção pode se tornar difícil, porque caso algum endereço na
interface externa ou interna seja alterado, a linha também precisará
ser alterada.
Faça a comparação com uma linha que facilita um pouco a
manutenção (<tt>tl0</tt> é externa, <tt>dc0</tt> interna):

<tt>
pass out on tl0 from dc0:network to any nat-to tl0
</tt>

A vantagem deve ser clara: podemos alterar o endereço IP de qualquer
interface sem haver necessidade de se alterar a regra.

Ao especificar um nome de interface para a tradução de endereços como
mostrado acima, o endereço IP é determinado no carregamento do
pf.conf, e não em tempo real. Caso esteja usando DHCP para configurar
sua interface externa, isso pode se tornar um problema. Se o endereço
atribuído for alterado, a NAT continua traduzindo pacotes saindo do
firewall usando o endereço IP antigo. Isso faz com que as conexões
parem de funcionar.
Para evitar esse problema, você pode dizer ao PF para atualizar o
endereço de tradução automaticamente, colocando o nome da interface
entre parêntesis:

<tt>
pass out on tl0 from dc0:network to any nat-to (tl0)
</tt>

Esse método funciona para tradução tanto de endereços IPv4 quanto IPv6.

Mapeamento Bidirecional (mapeamento 1:1)

Um mapeamento bidirecional pode ser estabelecido através do uso do parâmetro
<tt>binat-to</tt>.
Uma regra com <tt>binat-to</tt> estabelece um mapeamento de um para um (1:1)
entre um endereço IP interno e um endereço IP externo.
Isso pode ser útil, por exemplo, para fornecer acesso a um servidor web
interno de modo que ele tenha seu próprio endereço IP externo.
Conexões vindas da Internet, destinadas aquele endereço, serão
transmitidas ao IP interno do servidor web e as conexões originadas
internamente pelo servidor web (tais como consultas de DNS) serão
repassadas com o endereço IP externo.
Portas de protocolos TCP e UDP nunca serão alteradas com o uso de
<tt>binat-to</tt>, da forma como são alteradas se você usar regras de
<tt>nat</tt>.

Exemplo:

<tt>
web_serv_int = "192.168.1.100"

web_serv_ext = "24.5.0.6"

pass on tl0 from $web_serv_int to any binat-to $web_serv_ext

</tt>

Exceções em Regras de Tradução

Se você necessita fazer tradução de grande parte do tráfego, mas prover
exceções à alguns casos, assegure-se de que as exceções sejam gerenciadas
por uma regra de filtro que não contenha o parâmetro <tt>nat-to</tt>.
Por exemplo, se o exemplo de NAT repassado anteriormente for
modificado para se parecer com isto:

<tt>
pass out on tl0 from 192.168.1.0/24 to any nat-to 24.2.74.79

pass out on tl0 from 192.168.1.208 to any

</tt>

Então toda a rede 192.168.1.0/24 teria seus pacotes traduzidos para
o endereço externo 24.2.74.79, exceto a máquina 192.168.1.208.

Verificação do Status da NAT

O
pfctl(8)
com a opção <tt>-s state</tt> é usado para verificar as traduções
NAT ativas.
Essa opção lista todas as sessões NAT ativas:

   # pfctl -s state
   fxp0 tcp 192.168.1.35:2132 (24.5.0.5:53136) -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
   fxp0 udp 192.168.1.35:2491 (24.5.0.5:60527) -> 24.2.68.33:53   MULTIPLE:SINGLE

Explicações (apenas da primeira linha):

fxp0

Indica a interface a qual o estado está vinculado. A palavra
<tt>self</tt> aparecerá caso o estado seja
<tt>floating</tt>.

TCP

O protocolo usado pela conexão.

192.168.1.35:2132

O endereço IP (192.168.1.35) da máquina na rede interna.
A porta de origem (2132) é mostrada após o endereço. Esse também é
o endereço substituído no cabeçalho IP.

24.5.0.5:53136

O endereço IP (24.5.0.5) e a porta (53136) no gateway onde os
pacotes estão sendo traduzidos.

65.42.33.245:22

O endereço IP (65.42.33.245) e a porta (22) onde a máquina interna
está se conectando.

TIME_WAIT:TIME_WAIT

Indica em qual estado o PF acredita que a conexão TCP esteja.

[Anterior: Filtragem de Pacotes]
[Conteúdo]
[Próximo: Redirecionamento de Tráfego
("Port Forwarding")]

www@openbsd.org

$OpenBSD$


text:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Microsoft.Xbox.Services.UserStatistics
{
    public class StatisticChangeEventArgs : EventArgs
    {

        public Statistic LatestStatistic
        {
            get;
            private set;
        }

        public string ServiceConfigurationId
        {
            get;
            private set;
        }

        public string XboxUserId
        {
            get;
            private set;
        }

    }
}


text:
import log from "../log";
import createSharedReference, {
  IReadOnlySharedReference,
} from "../utils/reference";
import { CancellationSignal } from "../utils/task_canceller";
import isNode from "./is_node";

export interface IResolution { width : number;
                               height : number; }

interface IResizeObserverConstructor {
  /* eslint-disable @typescript-eslint/prefer-function-type */
  new(callback: IResizeObserverCallback) : IResizeObserver;
  /* eslint-enable @typescript-eslint/prefer-function-type */
}

interface IResizeObserver { observe(target : Element) : void;
                            unobserve(target : Element) : void;
                            disconnect() : void; }

type IResizeObserverCallback  = (entries: IResizeObserverEntry[],
                                 observer: IResizeObserver) => void;

interface IResizeObserverEntry { readonly target : Element;
                                 readonly contentRect : IDOMRectReadOnly; }

interface IDOMRectReadOnly { readonly x: number;
                             readonly y: number;
                             readonly width: number;
                             readonly height: number;
                             readonly top: number;
                             readonly right: number;
                             readonly bottom: number;
                             readonly left: number; }

/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
const _ResizeObserver : IResizeObserverConstructor |
                        undefined = isNode ? undefined :
                                             window.ResizeObserver;
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
/* eslint-enable @typescript-eslint/no-unsafe-assignment */

/**
 * Emit the current height and width of the given `element` each time it
 * changes.
 *
 * On some browsers, we might not be able to rely on a native API to know when
 * it changes, the `interval` argument allow us to provide us an inverval in
 * milliseconds at which we should query that element's size.
 * @param {HTMLElement} element
 * @param {number} interval
 * @returns {Observable}
 */
export default function onHeightWidthChange(
  element : HTMLElement,
  interval : number,
  cancellationSignal : CancellationSignal
) : IReadOnlySharedReference<IResolution> {
  const { height: initHeight, width: initWidth } = element.getBoundingClientRect();
  const ref = createSharedReference<IResolution>({
    height: initHeight,
    width: initWidth,
  });
  let lastHeight : number = initHeight;
  let lastWidth : number = initWidth;

  if (_ResizeObserver !== undefined) {
    const resizeObserver = new _ResizeObserver(entries => {
      if (entries.length === 0) {
        log.error("Compat: Resized but no observed element.");
        return;
      }

      const entry = entries[0];
      const { height, width } = entry.contentRect;

      if (height !== lastHeight || width !== lastWidth) {
        lastHeight = height;
        lastWidth = width;
        ref.setValue({ height, width });
      }
    });

    resizeObserver.observe(element);
    cancellationSignal.register(() => {
      resizeObserver.disconnect();
    });
  } else {
    const intervalId = setInterval(() => {
      const { height, width } = element.getBoundingClientRect();
      if (height !== lastHeight || width !== lastWidth) {
        lastHeight = height;
        lastWidth = width;
        ref.setValue({ height, width });
      }
    }, interval);
    cancellationSignal.register(() => {
      clearInterval(intervalId);
    });
  }
  return ref;
}


text:
package restore

import (
	"testing"

	"github.com/pingcap/tidb/br/pkg/lightning/config"
	"github.com/pingcap/tidb/br/pkg/lightning/restore/mock"
	"github.com/stretchr/testify/require"
)

func TestPrecheckBuilderBasic(t *testing.T) {
	var err error
	mockSrc, err := mock.NewMockImportSource(nil)
	require.NoError(t, err)
	mockTarget := mock.NewMockTargetInfo()
	cfg := config.NewConfig()
	cfg.TikvImporter.Backend = config.BackendLocal

	preInfoGetter, err := NewPreRestoreInfoGetter(cfg, mockSrc.GetAllDBFileMetas(), mockSrc.GetStorage(), mockTarget, nil, nil)
	require.NoError(t, err)
	theCheckBuilder := NewPrecheckItemBuilder(cfg, mockSrc.GetAllDBFileMetas(), preInfoGetter, nil)
	for _, checkItemID := range []CheckItemID{
		CheckLargeDataFile,
		CheckSourcePermission,
		CheckTargetTableEmpty,
		CheckSourceSchemaValid,
		CheckCheckpoints,
		CheckCSVHeader,
		CheckTargetClusterSize,
		CheckTargetClusterEmptyRegion,
		CheckTargetClusterRegionDist,
		CheckTargetClusterVersion,
		CheckLocalDiskPlacement,
		CheckLocalTempKVDir,
	} {
		theChecker, err := theCheckBuilder.BuildPrecheckItem(checkItemID)
		require.NoError(t, err)
		require.Equal(t, checkItemID, theChecker.GetCheckItemID())
	}
}


text:
1. General information
2. Definitions and explanation of Columns
3. Sources and methods

# 1. General Information
This table contains categorical information about stakeholders and subsidiaries that are active within the IETF and 3GPP.

In general, the 3GPP contains more fine-grained stakeholder compositions -- listing many more subsidiaries -- than the IETF. Therefore, if one is to use this data for the analysis of IETF mailing archives, we advise to merge all branches (subsidiaries, e.g., Ericsson España S.A.) into the highest node (stakeholder, e.g., Ericsson) of the tree. The highest node of the tree is identifiable through the subsidiary column, as the corresponding cell should be empty in that case.

# 2. Definitions and explanation of Columns
## Column A: name
The name of the company who has a member registered at a standard body organisation.
## Column B: Category
- Association
- Advertising Company
- Chipmaker
- Content Distribution Network
- Content Providers
- Consulting
- Cloud Provider
- Cybersecurity
- Financial Institution
- Hardware vendor
- Internet Registry
- Infrastructure Company
- Networking Equipment Vendor
- Network Service Provider
- Regional Standards Body
- Regulatory Body
- Research and Development Institution
- Software Provider
- Testing and Certification
- Telecommunications Provider
- Satellite Operator

As some stakeholders or subsidiaries are active in multiple market sectors, they have been associated with multiple categories, separating them with a comma.

As assigning such categories to stakeholders and subsidiaries is an inherently difficult endeavour we clearly state our objective here. The categories were assigned according to stakeholders and subsidiaries country registration and market sector activities as of November 2021. The correctness of those associations can't be guaranteed to have been or will be the same in the past or future.

[Something that we are thinking to follow up on in the future is to indicating whether the stakeholder or subsidiary has an ASN (Autonomous System Number; used for routing in the Internet), as it is not subject to debate and can be used to check for categories in other databases (eg, PeeringDB)]. A challenge with this is that corporations have different ASNs and there is change over time.
## Column C: subsidiary
This column describes when a company is the subsidiary of another company in the list. If the cell in this column is empty, this company can be understood as the parent company.
## Column D: stakeholdergroup
Stakeholdergroups are used as they have been defined in the WSIS process and the Tunis-agenda.

- Academia
- Civil Society
- Private Sector (including industry consortia and associations; state-owned and government-funded businesses)
- Government
- Technical Community (IETF, ICANN, ETSI, 3GPP, oneM2M, etc)
- Intergovernmental organization

## Column E: nationality
The country name in which the stakeholder or subsidiary is registered.

## Column F: email domain names
The Email domains associated with each stakeholder and subsidiary is derived from the Email addresses used by members that contribute to the public mailing archives of standard organisations IETF and 3GPP. The association has been made by hand to ensure that no, e.g., personal or free available domain names (such as @gmail.com) are used. Sometimes multiple email domain names match the same stakeholder, in which case both are listed separated by a comma.

## Column G: Membership Organization
Membership of regional SDOs, derived from 3GPP data.
- ARIB
- ATIS
- CCSA
- ETSI
- TSDSI
- TTA
- TTC

# 3. Sources and methods
The sources for relevant stakeholders and subsidiaries and their Email domain names are the mailing archives of the standard organisations and the membership data from the 3GPP. Their associated categories and nationalities are derived from Wikipedia data, the companies' websites, as well as data from the standards organizations.


text:
""" Tests for the storpool.spconfig.SPConfig class. """

import collections
import errno
import itertools
import os

import mock
import pytest

from storpool import spconfig

ConfigData = collections.namedtuple('ConfigData', [
    'filename',
    'exists',
    'data',
])

CONFIG_DATA = (
    ConfigData(
        filename='/etc/storpool.conf',
        exists=True,
        data={'beleriand': {
            'SP_CACHE_SIZE': '8192',
            'SP_API_HTTP_PORT': '80',
        }},
    ),
    ConfigData(
        filename='/etc/storpool.conf.d/local.conf',
        exists=True,
        data={'': {'c': '3'}, 'beleriand': {'a': '4'}},
    ),
    ConfigData(
        filename='/etc/storpool.conf.d/storpool.conf',
        exists=False,
        data={},
    ),
)

CONFIG_FILES = {
    item.filename: item for item in CONFIG_DATA
}

TEST_CONFIG_FILES = {
    "/etc/storpool.conf": True,
    "/etc/storpool-defaults.conf": False,
    "/etc/storpool.conf.d/.hidden.conf": False,
    "/etc/storpool.conf.d/local.conf": True,
    "/etc/storpool.conf.d/local.confx": False,
    "/etc/storpool.conf.d/server.conf.bak": False,
    "/etc/storpool.conf.d/storpool.conf": True,
    "/etc/storpool.conf.d/storpool.conf~": False,
    "/usr/lib/storpool/storpool.conf": False,
}

TEST_CONFIG_FILES_LISTDIR = dict(
    (
        dirname,
        ["subdir", "another-subdir.conf"]
        + sorted(filename for _, filename in files)
    )
    for dirname, files in itertools.groupby(
        sorted(os.path.split(fname) for fname in TEST_CONFIG_FILES),
        lambda item: item[0],
    )
)

def fake_get_config_files(_cls, missing_ok=False):
    """ Simulate looking for the StorPool configuration files. """
    assert missing_ok is not None  # Make this do something...
    return [item.filename for item in CONFIG_DATA]

class FakeConfig(object):
    # pylint: disable=too-few-public-methods
    """ Simulate a confget.Config settings holder. """

    def __init__(self, varnames, filename='(invalid)'):
        """ Initialize a fake Config object: store the filename. """
        assert varnames == []
        assert filename in CONFIG_FILES
        self.filename = filename

class FakeINI(object):
    # pylint: disable=too-few-public-methods
    """ Simulate a confget.backend.ini.INIBackend reader. """

    def __init__(self, config):
        """ Initialize a fake INI reader: store the fake config object. """
        assert isinstance(config, FakeConfig)
        self.config = config

    def read_file(self):
        """ Simulate reading from the INI file. """
        return CONFIG_FILES[self.config.filename].data

class FakeINICheck(object):
    # pylint: disable=too-few-public-methods
    """ Simulate a confget.backend.ini.INIBackend reader. """

    def __init__(self, config):
        """ Initialize a fake INI reader: store the fake config object. """
        assert isinstance(config, FakeConfig)
        self.config = config

    def read_file(self):
        """ Simulate reading from the INI file. """
        res = CONFIG_FILES[self.config.filename]
        if not res.exists:
            raise IOError(
                errno.ENOENT,
                "No such file or directory",
                self.config.filename,
            )

        return res.data

@mock.patch('storpool.spconfig.SPConfig.get_config_files',
            new=fake_get_config_files)
@mock.patch('confget.Config', new=FakeConfig)
@mock.patch('confget.BACKENDS', new={'ini': FakeINI})
def test_success():
    """ Test that a SPConfig object behaves almost like a dictionary. """
    cfg = spconfig.SPConfig(
        section='beleriand',
        missing_ok=True,
        use_env=False,
    )

    assert cfg['SP_CACHE_SIZE'] == '8192'
    with pytest.raises(KeyError):
        assert cfg['d'] == 'we should never get here, right?'

    assert cfg.get('a', 42) == '4'
    assert cfg.get('d', 42) == 42

    assert dict(cfg.items()) == dict(
        set(
            item
            for item in spconfig.DEFAULTS.items()
            if item[0] not in ('SP_CACHE_SIZE', 'SP_API_HTTP_PORT')
        )
        | set({
            'SP_CACHE_SIZE': '8192',
            'SP_API_HTTP_PORT': '80',
            'a': '4',
            'c': '3',
        }.items())
    )

    assert (
        sorted(set(cfg.keys()) - set(spconfig.DEFAULTS.keys()))
    ) == ['a', 'c']

    assert sorted(
        set(cfg.iteritems()) - set(spconfig.DEFAULTS.items())
    ) == [
        ('SP_API_HTTP_PORT', '80'),
        ('SP_CACHE_SIZE', '8192'),
        ('a', '4'),
        ('c', '3'),
    ]

    assert sorted(
        set(cfg.iterkeys()) - set(spconfig.DEFAULTS.keys())
    ) == ['a', 'c']

    cfg = spconfig.SPConfig(section='beleriand', use_env=False)

    assert cfg['SP_CACHE_SIZE'] == '8192'
    with pytest.raises(KeyError):
        assert cfg['d'] == 'we should never get here, right?'

    assert cfg.get('a', 42) == '4'
    assert cfg.get('d', 42) == 42

    assert dict(cfg.items()) == dict(
        set(
            item
            for item in spconfig.DEFAULTS.items()
            if item[0] not in ('SP_CACHE_SIZE', 'SP_API_HTTP_PORT')
        )
        | set({
            'SP_CACHE_SIZE': '8192',
            'SP_API_HTTP_PORT': '80',
            'a': '4',
            'c': '3',
        }.items())
    )

    assert (
        sorted(set(cfg.keys()) - set(spconfig.DEFAULTS.keys()))
    ) == ['a', 'c']

    assert sorted(
        set(cfg.iteritems()) - set(spconfig.DEFAULTS.items())
    ) == [
        ('SP_API_HTTP_PORT', '80'),
        ('SP_CACHE_SIZE', '8192'),
        ('a', '4'),
        ('c', '3'),
    ]

    assert sorted(
        set(cfg.iterkeys()) - set(spconfig.DEFAULTS.keys())
    ) == ['a', 'c']

@mock.patch('storpool.spconfig.SPConfig.get_config_files',
            new=fake_get_config_files)
@mock.patch('confget.Config', new=FakeConfig)
@mock.patch('confget.BACKENDS', new={'ini': FakeINI})
def test_environment():
    """ Test that environment variables may override the config. """
    cfg = spconfig.SPConfig(
        section='beleriand',
        missing_ok=True,
        use_env=False,
    )

    assert cfg['SP_CACHE_SIZE'] == '8192'
    assert cfg['SP_API_HTTP_HOST'] == '127.0.0.1'
    assert cfg['SP_API_HTTP_PORT'] == '80'
    with pytest.raises(KeyError):
        assert cfg['SP_AUTH_TOKEN'] == 'we should never get here, right?'

    default_dict = dict(cfg.items())
    del default_dict['SP_API_HTTP_HOST']
    del default_dict['SP_API_HTTP_PORT']

    env = {'SP_AUTH_TOKEN': 'secret', 'SP_CACHE_SIZE': '4096'}
    with mock.patch.object(os.environ, 'get', new=env.get):
        cfg = spconfig.SPConfig(section='beleriand', missing_ok=True)

    assert cfg['SP_API_HTTP_HOST'] == '127.0.0.1'
    assert cfg['SP_API_HTTP_PORT'] == '80'
    assert cfg['SP_AUTH_TOKEN'] == 'secret'

    cfg_dict = dict(cfg.items())
    del cfg_dict['SP_API_HTTP_HOST']
    del cfg_dict['SP_API_HTTP_PORT']
    del cfg_dict['SP_AUTH_TOKEN']
    assert cfg_dict == default_dict

    env = {'SP_API_HTTP_HOST': 'nowhere', 'SP_API_HTTP_PORT': 'none'}
    with mock.patch.object(os.environ, 'get', new=env.get):
        cfg = spconfig.SPConfig(section='beleriand', missing_ok=True)

    assert cfg['SP_API_HTTP_HOST'] == 'nowhere'
    assert cfg['SP_API_HTTP_PORT'] == 'none'
    with pytest.raises(KeyError):
        assert cfg['SP_AUTH_TOKEN'] == 'we should never get here, right?'

    cfg_dict = dict(cfg.items())
    del cfg_dict['SP_API_HTTP_HOST']
    del cfg_dict['SP_API_HTTP_PORT']
    assert cfg_dict == default_dict

@mock.patch('storpool.spconfig.SPConfig.get_config_files',
            new=fake_get_config_files)
@mock.patch('confget.Config', new=FakeConfig)
@mock.patch('confget.BACKENDS', new={'ini': FakeINICheck})
def test_file_not_found():
    """ Test that a SPConfig object behaves almost like a dictionary. """
    with pytest.raises(spconfig.SPConfigException) as err:
        spconfig.SPConfig(section='beleriand', missing_ok=True, use_env=False)

    assert "/etc/storpool.conf.d/storpool.conf" in str(err.value)

def test_get_config_files():
    """Test that SPConfig.get_config_files() works properly."""

    dirs_checked = set()
    files_checked = set()

    def mock_listdir(dirname):
        """Mock os.listdir(), return our synthetic filesystem's contents."""
        return TEST_CONFIG_FILES_LISTDIR[dirname]

    def mock_is_dir(path):
        """Mock os.path.isdir(), check and record."""
        dirs_checked.add(path)
        return path in TEST_CONFIG_FILES_LISTDIR

    def mock_is_file(path):
        """Mock os.path.isfile(), check and record."""
        files_checked.add(path)
        return path in TEST_CONFIG_FILES

    with mock.patch("os.listdir", new=mock_listdir), mock.patch(
        "os.path.isdir", new=mock_is_dir
    ), mock.patch(
        "os.path.isfile", new=mock_is_file
    ):
        res = set(spconfig.SPConfig.get_config_files(missing_ok=True))

    assert dirs_checked == set(["/etc/storpool.conf.d"])
    assert files_checked == set(
        [
            "/etc/storpool.conf",
            "/etc/storpool.conf.d/local.conf",
            "/etc/storpool.conf.d/storpool.conf",
            "/etc/storpool.conf.d/another-subdir.conf",
        ]
    )
    assert res == set(
        filename
        for filename, wanted in TEST_CONFIG_FILES.items()
        if wanted
    )

    dirs_checked.clear()
    files_checked.clear()

    with mock.patch("os.listdir", new=mock_listdir), mock.patch(
        "os.path.isdir", new=mock_is_dir
    ), mock.patch(
        "os.path.isfile", new=mock_is_file
    ):
        res = set(spconfig.SPConfig.get_config_files())

    assert dirs_checked == set(["/etc/storpool.conf.d"])
    assert not files_checked
    assert res == set(
        filename
        for filename, wanted in TEST_CONFIG_FILES.items()
        if wanted
    ) | set(["/etc/storpool.conf.d/another-subdir.conf"])