text:
<!doctype html>

		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

		<title>Stocking a Front-end Toolshed</title>

		<meta name="description" content="A presentation on modern front-end tooling">
		<meta name="author" content="Jared Siirila">

		<meta name="apple-mobile-web-app-capable" content="yes">
		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

		<link rel="stylesheet" href="css/reveal.css">
		<link rel="stylesheet" href="css/theme/black.css">

		<link rel="stylesheet" href="lib/css/zenburn.css">

		<link rel="stylesheet" href="css/custom.css">

Stocking a Front-end Toolshed

						Created by Jared Siirila / @jtsiirila

						- Decision Fatique
						- Decision Avoidance
						- Impaired self-regulation
						- Spend your time adding value, not making minor tooling decisions

Roll Your Own

						webpack
						, the

production

unbiased

flexible

extensible

open source

module bundler.


text:
package org.jbpm.process.builder;

import static org.junit.Assert.assertEquals;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.drools.compiler.builder.impl.KnowledgeBuilderImpl;
import org.drools.compiler.compiler.DialectCompiletimeRegistry;
import org.drools.compiler.lang.descr.ActionDescr;
import org.drools.compiler.lang.descr.ProcessDescr;
import org.drools.compiler.rule.builder.dialect.java.JavaDialect;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.definitions.InternalKnowledgePackage;
import org.drools.core.definitions.impl.KnowledgePackageImpl;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.impl.KnowledgeBaseFactory;
import org.drools.core.spi.ProcessContext;
import org.jbpm.process.builder.dialect.ProcessDialect;
import org.jbpm.process.builder.dialect.ProcessDialectRegistry;
import org.jbpm.process.instance.impl.Action;
import org.jbpm.test.util.AbstractBaseTest;
import org.jbpm.workflow.core.DroolsAction;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.impl.WorkflowProcessImpl;
import org.jbpm.workflow.core.node.ActionNode;
import org.junit.Test;
import org.kie.api.runtime.KieSession;

public class JavaActionBuilderTest extends AbstractBaseTest {

    @Test
    public void testSimpleAction() throws Exception {
        final InternalKnowledgePackage pkg = new KnowledgePackageImpl( "pkg1" );

        ActionDescr actionDescr = new ActionDescr();
        actionDescr.setText( "list.add( \"hello world\" );" );

        KnowledgeBuilderImpl pkgBuilder = new KnowledgeBuilderImpl( pkg );
        DialectCompiletimeRegistry dialectRegistry = pkgBuilder.getPackageRegistry( pkg.getName() ).getDialectCompiletimeRegistry();
        JavaDialect javaDialect = ( JavaDialect ) dialectRegistry.getDialect( "java" );

        ProcessDescr processDescr = new ProcessDescr();
        processDescr.setClassName( "Process1" );
        processDescr.setName( "Process1" );

        WorkflowProcessImpl process = new WorkflowProcessImpl();
        process.setName( "Process1" );
        process.setPackageName( "pkg1" );

        ProcessBuildContext context = new ProcessBuildContext(pkgBuilder, pkgBuilder.getPackage(), null, processDescr, dialectRegistry, javaDialect);

        context.init( pkgBuilder, pkg, null, dialectRegistry, javaDialect, null);

        pkgBuilder.addPackageFromDrl( new StringReader("package pkg1;\nglobal java.util.List list;\n") );

        ActionNode actionNode = new ActionNode();
        DroolsAction action = new DroolsConsequenceAction("java", null);
        actionNode.setAction(action);

        ProcessDialect dialect = ProcessDialectRegistry.getDialect( "java" );
        dialect.getActionBuilder().build( context, action, actionDescr, actionNode );
        dialect.addProcess( context );
        javaDialect.compileAll();
        assertEquals( 0, javaDialect.getResults().size() );

        final InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
        kbase.addPackages( Arrays.asList(pkgBuilder.getPackage()) );
        final KieSession wm = kbase.newKieSession();

        List<String> list = new ArrayList<String>();
        wm.setGlobal( "list", list );

        ProcessContext processContext = new ProcessContext( ((InternalWorkingMemory) wm).getKnowledgeRuntime() );
        ((Action) actionNode.getAction().getMetaData("Action")).execute( processContext );

        assertEquals("hello world", list.get(0) );
    }

}

redpajama_set_name: RedPajamaGithub


text:
'''
@author:     Juncheng Chen

@copyright:  1999-2015 Alibaba.com. All rights reserved.

@license:    Apache Software License 2.0

@contact:    juncheng.cjc@outlook.com
'''
import os
from datetime import datetime
import copy

import logging
logger = logging.getLogger(__name__)

class Command(object):
    def __init__(self, name, command=None, clean_command=None):
        self.name = name
        self.command = command
        self.clean_command = clean_command
        self.process = None

    def new(self, device, args):
        self.device = device
        self.args = args
        return copy.deepcopy(self)

    def kill(self):
        if self.process:
            self.process.kill()
            self.process.wait()
            self.process = None
            logger.debug('kill %s %s' % (self.name, self.command))

    def is_done(self):
        if self.process:
            return self.process.poll() is not None
        return True

    def execute(self):
        raise Exception('%s not implement execute' % self.__class__)

    def clean(self):
        pass

class LastCommand(Command):
    def execute(self):
        if self.command:
            logger.debug('execute single command %s' % self.command)
            with open(os.path.join(self.device.log_dir, '%s.txt' % self.name), 'a') as f:
                self.process = self.device.shell(self.command)
                f.write(self.device.get_process_stdout(self.process))

class LoopCommand(Command):
    def execute(self):
        if self.command:
            logger.debug('execute loop command %s' % self.command)
            with open(os.path.join(self.device.log_dir, '%s.txt' % self.name), 'a') as f:
                self.process = self.device.shell(self.command)
                f.write(">>%s>>\n%s\n" % (datetime.now().strftime('%m/%d %H:%M:%S'), self.device.get_process_stdout(self.process)))

class AnrLoopCommand(LoopCommand):
    def execute(self):
        logger.debug('execute loop command %s' % self.command)
        if not hasattr(self, 'timestamp'):
            self.process = self.device.shell(self.command)
            self.timestamp = self.device.get_process_stdout(self.process)
        self.process = self.device.shell(self.command)
        timestamp = self.device.get_process_stdout(self.process)
        if timestamp != self.timestamp:
            self.timestamp = timestamp
            with open(os.path.join(self.device.log_dir, '%s_%s.txt' % (self.name, datetime.now().strftime('%Y%m%d%H%M%S'))), 'w') as f:
                self.process = self.device.shell('cat /data/anr/traces.txt')
                f.write(self.device.get_process_stdout(self.process))

class MemdetailLoopCommand(LoopCommand):
    def new(self, device, args):
        if args.process_names:
            self.command = 'dumpsys meminfo -a %s' % args.process_names[0]
        else:
            self.command = None
        return LoopCommand.new(self, device, args)

class ShowMapLoopCommand(LoopCommand):
    def new(self, device, args):
        if args.process_names:
            self.command = "ps | grep %s | awk '{print $2}' | xargs showmap" % args.process_names[0]
        else:
            self.command = None
        return LoopCommand.new(self, device, args)

class DumpheapLoopCommand(LoopCommand):
    def new(self, device, args):
        self.delay = 3600 / args.interval
        self.hprof = '/sdcard/dumpheap.hprof'
        self.clean_command = 'rm -f %s' % self.hprof
        if args.process_names:
            self.command = "am dumpheap %s %s" % (args.process_names[0], self.hprof)
        else:
            self.command = None
        self.i = 0
        return LoopCommand.new(self, device, args)

    def execute(self):
        if self.command:
            if self.i == (self.delay - 2):
                logger.debug('execute loop command %s' % self.command)
                self.clean()
                self.device.get_process_stdout(self.device.shell(self.command))
            elif self.i == self.delay:
                self.i = 0
                self.device.adb('pull %s %s' % (self.hprof, os.path.join(self.device.log_dir, '%s_%s.hprof' % (self.name, datetime.now().strftime('%Y%m%d_%H%M%S')))))
            self.i += 1

    def clean(self):
        if self.clean_command:
            logger.debug('execute loop clean command %s' % self.clean_command)
            self.device.get_process_stdout(self.device.shell(self.clean_command))

class DurableCommand(Command):

    def execute(self):
        if self.command and self.is_done():
            logger.debug('execute durable command %s' % self.command)
            self.clean()
            self.process = self.device.shell(self.command, os.path.join(self.device.log_dir, '%s_%s.txt' % (self.name, datetime.now().strftime('%Y%m%d_%H%M%S'))))

    def clean(self):
        if self.clean_command:
            logger.debug('execute durable clean command %s' % self.command)
            self.device.get_process_stdout(self.device.shell(self.clean_command))
            if self.process:
                self.process.wait()

MONKEYBLACKLIST = '/mnt/sdcard/tvb_monkey_blacklist.txt'
MONKEYSCRIPT = '/mnt/sdcard/tvb_monkey_script.txt'
MONKEYSCRIPTTITLE = ['type = tvb_user', 'count = 1', 'speed = 1.0', 'start data >>']
MONKEYCMD = 'monkey -v -v -v --ignore-crashes --ignore-timeouts --ignore-security-exceptions --kill-process-after-error --monitor-native-crashes'
MONKEYCOUNT = 1200000000

MONKEYPCT = {'pct-touch': 0, 'pct-motion': 0, 'pct-trackball': 5, 'pct-nav': 55, 'pct-majornav': 15, 'pct-syskeys': 15, 'pct-appswitch': 9, 'pct-anyevent': 1}

class MonkeyDurableCommand(DurableCommand):
    def new(self, device, args):
        self.clean_command = 'busybox killall com.android.commands.monkey'
        return DurableCommand.new(self, device, args)

    def get_monkey_percent(self, args):
        percent = []
        for pct in MONKEYPCT:
            if hasattr(args, pct):
                value = getattr(args, pct)
                if value:
                    percent.append('--%s %s' % (pct, value))
        if percent:
            return ' '.join(percent)
        return ' '.join(['--%s %s' % (k, v) for k, v in MONKEYPCT.iteritems() if v])

class AppMonkeyDurableCommand(MonkeyDurableCommand):
    def new(self, device, args):
        extra = ''
        if args.monkey:
            extra = '-p ' + ' -p '.join(args.monkey)
        self.command = '%s %s %s --throttle %s %s' % (MONKEYCMD, self.get_monkey_percent(args), extra, args.throttle, MONKEYCOUNT)
        return MonkeyDurableCommand.new(self, device, args)

class BlacklistMonkeyDurableCommand(MonkeyDurableCommand):
    def new(self, device, args):
        if args.blacklist:
            cmd = "echo '%s' > %s" % ('\\n'.join(args.blacklist), MONKEYBLACKLIST)
            device.shell(cmd)
            extra = '--pkg-blacklist-file %s' % MONKEYBLACKLIST
            self.command = '%s %s %s --throttle %s %s' % (MONKEYCMD, self.get_monkey_percent(args), extra, args.throttle, MONKEYCOUNT)
        else:
            self.command = None
        return MonkeyDurableCommand.new(self, device, args)

class ScriptMonkeyDurableCommand(MonkeyDurableCommand):
    def new(self, device, args):
        if args.script:
            with open(args.script, 'r') as f:
                cmd = "echo '%s' > %s" % ('\\n'.join(MONKEYSCRIPTTITLE + f.read().splitlines()), MONKEYSCRIPT)
                device.shell(cmd)
                extra = '-f %s ' % MONKEYSCRIPT
                self.command = '%s %s --throttle %s %s' % (MONKEYCMD, extra, args.throttle, MONKEYCOUNT)
        else:
            self.command = None
        return MonkeyDurableCommand.new(self, device, args)

COMMAND_CONFIG = {
    'top': LoopCommand('top', 'top -n 1'),
    'meminfo': LoopCommand('meminfo', 'dumpsys meminfo'),
    'cpuinfo': LoopCommand('cpuinfo', 'dumpsys cpuinfo'),
    'mali': LoopCommand('mali', 'librank -P /dev/mali'),
    'activity': LoopCommand('activity', 'dumpsys activity'),
    'oom': LoopCommand('activity_oom', 'dumpsys activity oom'),
    'processes': LoopCommand('activity_processes', 'dumpsys activity processes'),
    'procstats': LoopCommand('activity_procstats', 'dumpsys activity procstats'),
    'temp0': LoopCommand('temperature_zone0', 'cat /sys/class/thermal/thermal_zone0/temp'),
    'temp1': LoopCommand('temperature_zone1', 'cat /sys/class/thermal/thermal_zone1/temp'),
    'anr': AnrLoopCommand('anr', 'ls -l /data/anr/traces.txt'),
    'memdetail': MemdetailLoopCommand('memdetail'),
    'showmap': ShowMapLoopCommand('showmap'),
    'dumpheap': DumpheapLoopCommand('dumpheap'),

    'logcat': DurableCommand('logcat', 'logcat -v threadtime', 'busybox killall logcat'),
    'event': DurableCommand('logcat_event', 'logcat -v threadtime -b events'),

    'monkey': AppMonkeyDurableCommand('monkey'),
    'blacklist': BlacklistMonkeyDurableCommand('monkey'),
    'script': ScriptMonkeyDurableCommand('monkey'),
}

LAST_COMMAND_CONFIG = {
    'bugreport': LastCommand('bugreport', 'bugreport'),
    'usagestats': LastCommand('usagestats', 'dumpsys usagestats')
}

excluded = ['monkey', 'blacklist', 'script']
support_commands = sorted([key for key in COMMAND_CONFIG.keys() if key not in excluded] + LAST_COMMAND_CONFIG.keys())
default_commands = sorted(['top', 'cpuinfo', 'meminfo', 'logcat', 'anr', 'bugreport'])


text:
plugin_sqlite_backup
====================

A web2py plugin providing a utility function to backup a sqlite app database


text:
/**
 * @author: dnyffenegger
 * @since 06.12.13
 */

var fs = require('fs')
    , childProcess = require('child_process')
    , moment = require('moment')
    , Q = require('q')
    , ejs = require('ejs')
    , shellescape = require('shell-escape')
    ;

module.exports = function(settings) {

    var pdfDirectory = settings.pdfDirectory || 'pdfs';
    var receiptTemplate = ejs.compile(fs.readFileSync(settings.receiptTemplate || 'print/receipt.tex').toString());
    var orderTemplate = ejs.compile(fs.readFileSync(settings.orderTemplate || 'print/order.tex').toString());
    var getPrinterName = settings.getPrinterName;
    var receiptPrinterSettingName = settings.receiptPrinterSettingName || 'receiptPrinter';
    var orderPrinterSettingName = settings.orderPrinterSettingName || 'orderPrinter';

    if (!fs.existsSync(pdfDirectory)) {
        fs.mkdirSync(pdfDirectory);
    }

    var printFile = function(printer, jobname, file, options) {
        var deferred = Q.defer();
        var args = [];
        args.push('lp');
        args.push('-d');
        args.push(printer);
        args.push('-t'); // job name
        args.push(jobname);
        if (options) {
            args.push(options);
        }
        args.push(file);
        childProcess.exec(shellescape(args), function(error, stdout, stderr){
            if (error != null) {
                var errorMsg = 'Fehler beim Drucken auf ' + printer + ': ' + stderr;
                console.log(errorMsg);
                deferred.reject(errorMsg);
            } else {
                deferred.resolve(stdout);
            }
        });
        return deferred.promise;

    };

    var printOnReceiptPrinter = function(file, jobname) {
        var deferred = Q.defer();
        getPrinterName(receiptPrinterSettingName, 'Kein Beleg-Drucker definiert').then(function(printerName){
                return printFile(printerName, jobname, file);
        }, function(error){
            deferred.reject(error);
        });
        return deferred.promise;
    };

    var printOnOrderPrinter = function(file, jobname) {
        var deferred = Q.defer();
        getPrinterName(orderPrinterSettingName, 'Kein Bestell-Drucker definiert').then(function(printerName) {
            return printFile(printerName, jobname, file, '-o media=a5 -o fit-to-page');
        }, function(error){
            deferred.reject(error);
        });
        return deferred.promise;
    };

    function createJobname(order, suffix) {
        var orderId = moment(order._id.getTimestamp()).format('YYYYMMDD-HHmmss');
        if (order.no)
            orderId += '-' + order.no;
        var jobname = orderId + '-' + suffix;
        return jobname;
    }

    function createLatexFile(order, jobname, template) {
        var filenameTex = pdfDirectory + '/' + jobname + '.tex';
        fs.writeFileSync(filenameTex, template({
            order: order,
            formatCurrency: function (amount) {
                return (amount / 100).toFixed(2);
            },
            moment: moment
        }));
        return filenameTex;
    }

    var createPdf = function(latexFile, jobname) {
        var deferred = Q.defer();
        var args = [];
        args.push('/usr/texbin/pdflatex')
        args.push('-output-directory');
        args.push(pdfDirectory);
        args.push('-jobname');
        args.push(jobname);
        args.push(latexFile);

        childProcess.exec(shellescape(args), function(error, stdout, stderr){
            if (error != null) {
                deferred.reject(error);
            } else {
                deferred.resolve(pdfDirectory + '/' + jobname + '.pdf');
            }
        });
        return deferred.promise;
    };

    var createPdfAndPrint = function(printJob) {
        var deferred = Q.defer();
        createPdf(printJob.latexFile, printJob.jobname).then(
            function (pdf) {
                return printJob.printFunc(pdf, printJob.jobname);
            },
            function (error) {
                console.log('Error while creating PDF from ' + printJob.latexFile + ': ' + error);
                deferred.reject(printJob.errorName + ' konnte nicht erstellt werden: ' + JSON.stringify(error));
            }
        );

        return deferred.promise;
    }

    var print = function(printJob) {
        var jobname = createJobname(printJob.order, printJob.name);
        var latexFile = createLatexFile(printJob.order, jobname, printJob.template);
        return createPdfAndPrint({
            jobname: jobname,
            latexFile: latexFile,
            printFunc: printJob.printFunc,
            errorName: printJob.errorName
        });
    };

    var getQueue = function() {
        var deferred = Q.defer();
        childProcess.exec('lpq -a', function(error, stdout, stderr){
            if (error != null) {
                deferred.reject(error);
            } else {
                var queue = stdout.split('\n');
                queue.shift(); // removes the first element (header)
                queue.pop(); // remove the last (empty) element
                deferred.resolve(queue);
            }
        });
        return deferred.promise;
    };

    var getPrinters = function() {
        var deferred = Q.defer();
        childProcess.exec('lpstat -a | cut -d " " -f 1', function(error, stdout, stderr) {
            if (error != null) {
                deferred.reject(error);
            } else {
                var printers = stdout.split(/\n/);
                printers.pop(); // remove the last (empty) item
                deferred.resolve(printers);
            }
        });
        return deferred.promise;
    };

    return {
        printOrder: function(order){
            return print({
                order: order,
                name: 'order',
                template: orderTemplate,
                printFunc: printOnOrderPrinter,
                errorName: 'Bestellung'
            });
        },
        printReceipt: function(order) {
            return print({
                order: order,
                name: 'receipt',
                template: receiptTemplate,
                printFunc: printOnReceiptPrinter,
                errorName: 'Beleg'
            });

        },
        getQueue: getQueue,
        getPrinters: getPrinters
    };

};


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>
      {% if page.title %}
        {{ page.title }} -
      {% endif %}
      {{ site.title }}
    </title>
    {% if page.description %}<meta name="description" content="{{ page.description }}">{% endif %}
    <meta name="author" content="{{ site.author.name }}">
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <link rel="stylesheet" href="{{ ASSET_PATH }}/css/reveal.min.css">
    <link rel="stylesheet" href="{{ ASSET_PATH }}/css/theme/default.css" id="theme">

    <!-- For syntax highlighting -->
    <link rel="stylesheet" href="{{ ASSET_PATH }}/lib/css/zenburn.css">

    <!-- If the query includes 'print-pdf', use the PDF print sheet -->
    <script>
      document.write( '<link rel="stylesheet" href="{{ ASSET_PATH }}/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
    </script>

    <!-- fav and touch icons -->
  <!-- Update these with your own images
    <link rel="shortcut icon" href="images/favicon.ico">
    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">
    <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
  -->
    <!-- HTML5 shim, for IE6-8 support of HTML elements -->
    <!--[if lt IE 9]>
    <script src="lib/js/html5shiv.js"></script>
    <![endif]-->
  </head>

  <body>
    <div class="reveal">

      {{ content }}

    </div>

    <script src="{{ ASSET_PATH }}/lib/js/head.min.js"></script>
    <script src="{{ ASSET_PATH }}/js/reveal.min.js"></script>

    <script>

        // Full list of configuration options available here:
        // https://github.com/hakimel/reveal.js#configuration
        Reveal.initialize({
            controls: true,
            progress: true,
            history: true,
            center: true,

            theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
            transition: Reveal.getQueryHash().transition || 'page', // default/cube/page/concave/zoom/linear/fade/none

            // Optional libraries used to extend on reveal.js
            dependencies: [
                { src: '{{ ASSET_PATH }}/lib/js/classList.js', condition: function() { return !document.body.classList; } },
                { src: '{{ ASSET_PATH }}/plugin/markdown/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
                { src: '{{ ASSET_PATH }}/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
                { src: '{{ ASSET_PATH }}/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
                { src: '{{ ASSET_PATH }}/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
                { src: '{{ ASSET_PATH }}/plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
                // { src: '{{ ASSET_PATH }}/plugin/search/search.js', async: true, condition: function() { return !!document.body.classList; } }
                // { src: '{{ ASSET_PATH }}/plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
            ]
        });

    </script>
    {% include JB/analytics %}
  </body>
</html>


text:
namespace HealthServer.Models
{
    using System.Threading.Tasks;

    using Microsoft.AspNetCore.Http;

    public interface IHealthStatusHandler
    {
        string Route { get; }

        Task Execute(HttpContext context);
    }
}


text:
'use strict';

const {Main} = require('./Main');
const component = new Main({});
document.getElementById('main').appendChild(component.element);


text:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
        <shape android:shape="rectangle" >
            <solid android:color="#F0BABABA" />
        </shape>
    </item>
    <item android:top="1dp">
        <shape android:shape="rectangle" >
            <solid android:color="#D2D2D2" />
        </shape>
    </item>
    <item android:top="2dp">
        <shape android:shape="rectangle" >
            <solid android:color="@color/overlay_light" />
        </shape>
    </item>

</layer-list>


text:
/* SPDX-License-Identifier: BSD-3-Clause */
#include <stdlib.h>

#include "files.h"
#include "log.h"
#include "tpm2.h"
#include "tpm2_tool.h"
#include "tpm2_nv_util.h"
#include "tpm2_options.h"

#define MAX_SESSIONS 3
#define MAX_AUX_SESSIONS 2
typedef struct tpm_nvsetbits_ctx tpm_nvsetbits_ctx;
struct tpm_nvsetbits_ctx {
    /*
     * Inputs
     */
    struct {
        const char *ctx_path;
        const char *auth_str;
        tpm2_loaded_object object;
    } auth_hierarchy;

    const char *bit_string;
    UINT64 bits;
    TPM2_HANDLE nv_index;
    TPM2B_NAME precalc_nvname;

    /*
     * Outputs
     */

    /*
     * Parameter hashes
     */
    const char *cp_hash_path;
    TPM2B_DIGEST cp_hash;
    const char *rp_hash_path;
    TPM2B_DIGEST rp_hash;
    bool is_command_dispatch;
    bool is_tcti_none;
    TPMI_ALG_HASH parameter_hash_algorithm;

    /*
     * Aux sessions
     */
    uint8_t aux_session_cnt;
    tpm2_session *aux_session[MAX_AUX_SESSIONS];
    const char *aux_session_path[MAX_AUX_SESSIONS];
    ESYS_TR aux_session_handle[MAX_AUX_SESSIONS];
};

static tpm_nvsetbits_ctx ctx = {
    .parameter_hash_algorithm = TPM2_ALG_ERROR,
    .aux_session_handle[0] = ESYS_TR_NONE,
    .aux_session_handle[1] = ESYS_TR_NONE,
};

static tool_rc nvsetbits(ESYS_CONTEXT *ectx) {

    /*
     * 1. TPM2_CC_<command> OR Retrieve cpHash
     */
    return tpm2_nvsetbits(ectx, &ctx.auth_hierarchy.object, ctx.nv_index,
        ctx.bits, &ctx.cp_hash, &ctx.rp_hash, ctx.parameter_hash_algorithm,
        &ctx.precalc_nvname, ctx.aux_session_handle[0],
        ctx.aux_session_handle[1]);

}

static tool_rc process_output(ESYS_CONTEXT *ectx) {

    UNUSED(ectx);
    /*
     * 1. Outputs that do not require TPM2_CC_<command> dispatch
     */
    bool is_file_op_success = true;
    if (ctx.cp_hash_path) {
        is_file_op_success = files_save_digest(&ctx.cp_hash, ctx.cp_hash_path);

        if (!is_file_op_success) {
            return tool_rc_general_error;
        }
    }

    if (!ctx.is_command_dispatch) {
        return tool_rc_success;
    }

    /*
     * 2. Outputs generated after TPM2_CC_<command> dispatch
     */

    if (ctx.rp_hash_path) {
        is_file_op_success = files_save_digest(&ctx.rp_hash, ctx.rp_hash_path);
    }

    return is_file_op_success ? tool_rc_success : tool_rc_general_error;
}

static tool_rc process_inputs(ESYS_CONTEXT *ectx) {

    /*
     * 1. Object and auth initializations
     */

    /*
     * 1.a Add the new-auth values to be set for the object.
     */

    /*
     * 1.b Add object names and their auth sessions
     */

    /* Object #1 */
    tool_rc rc = tool_rc_success;
    if (ctx.is_tcti_none) {
        /*
         * Cannot use tpm2_util_object_load like in nvdefine as it makes a call
         * to tpm2_util_sys_handle_to_esys_handle which then tries to read the
         * ESYS_TR object off of the TPM expecting it to be there.
         * Note: this if it is a permanent handle ESYS_TR is fixed and so the
         * TPM is not probed even with tpm2_util_sys_handle_to_esys_handle.
         */
        rc = tpm2_util_handle_from_optarg(ctx.auth_hierarchy.ctx_path,
            &ctx.auth_hierarchy.object.handle,
            TPM2_HANDLE_FLAGS_NV | TPM2_HANDLE_FLAGS_O | TPM2_HANDLE_FLAGS_P) ?
            tool_rc_success : tool_rc_option_error;

        ctx.auth_hierarchy.object.tr_handle = (rc == tool_rc_success) ?
           tpm2_tpmi_hierarchy_to_esys_tr(ctx.auth_hierarchy.object.handle) : 0;
    } else {
        rc = tpm2_util_object_load_auth(ectx, ctx.auth_hierarchy.ctx_path,
            ctx.auth_hierarchy.auth_str, &ctx.auth_hierarchy.object, false,
            TPM2_HANDLE_FLAGS_NV | TPM2_HANDLE_FLAGS_O | TPM2_HANDLE_FLAGS_P);
    }

    if (rc != tool_rc_success) {
        LOG_ERR("Invalid handle authorization");
        return rc;
    }

    /*
     * 2. Restore auxiliary sessions
     */
    rc = tpm2_util_aux_sessions_setup(ectx, ctx.aux_session_cnt,
        ctx.aux_session_path, ctx.aux_session_handle, ctx.aux_session);
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 3. Command specific initializations
     */
    bool result = tpm2_util_string_to_uint64(ctx.bit_string, &ctx.bits);
    if (!result) {
        LOG_ERR("Could not convert option argument to number, got: \"%s\"",
                ctx.bit_string);
        return tool_rc_general_error;
    }

    /*
     * 4. Configuration for calculating the pHash
     */

    /*
     * 4.a Determine pHash length and alg
     */
    tpm2_session *all_sessions[MAX_SESSIONS] = {
        ctx.auth_hierarchy.object.session,
        ctx.aux_session[0],
        ctx.aux_session[1]
    };

    const char **cphash_path = ctx.cp_hash_path ? &ctx.cp_hash_path : 0;
    const char **rphash_path = ctx.rp_hash_path ? &ctx.rp_hash_path : 0;

    ctx.parameter_hash_algorithm = tpm2_util_calculate_phash_algorithm(ectx,
        cphash_path, &ctx.cp_hash, rphash_path, &ctx.rp_hash, all_sessions);

    /*
     * 4.b Determine if TPM2_CC_<command> is to be dispatched
     * is_tcti_none       [N]
     * !rphash && !cphash [Y]
     * !rphash && cphash  [N]
     * rphash && !cphash  [Y]
     * rphash && cphash   [Y]
     */
    ctx.is_command_dispatch = (ctx.is_tcti_none ||
        (ctx.cp_hash_path && !ctx.rp_hash_path)) ? false : true;

    return rc;
}

static tool_rc check_options(tpm2_option_flags flags) {

    ctx.is_tcti_none = flags.tcti_none ? true : false;
    if (ctx.is_tcti_none && !ctx.cp_hash_path) {
        LOG_ERR("If tcti is none, then cpHash path must be specified");
        return tool_rc_option_error;
    }

    bool is_nv_name_specified = ctx.precalc_nvname.size;
    if (ctx.is_tcti_none && !is_nv_name_specified) {
        LOG_ERR("Must specify the NVIndex name.");
        return tool_rc_option_error;
    }

    if (!ctx.is_tcti_none && is_nv_name_specified) {
        LOG_ERR("Do not specify NVIndex name, it is directly read from NV");
        return tool_rc_option_error;
    }

    if (!ctx.bit_string) {
        LOG_ERR("Expected option --bits for specifying the bits to set");
        return tool_rc_option_error;
    }

    return tool_rc_success;
}

static bool on_arg(int argc, char **argv) {

    if (!ctx.auth_hierarchy.ctx_path) {
        ctx.auth_hierarchy.ctx_path = argv[0];
    }

    return on_arg_nv_index(argc, argv, &ctx.nv_index);
}

static bool on_option(char key, char *value) {

    switch (key) {

    case 'C':
        ctx.auth_hierarchy.ctx_path = value;
        break;
    case 'P':
        ctx.auth_hierarchy.auth_str = value;
        break;
    case 'i':
        ctx.bit_string = value;
        break;
    case 0:
        ctx.cp_hash_path = value;
        break;
    case 1:
        ctx.rp_hash_path = value;
        break;
    case 'S':
        ctx.aux_session_path[ctx.aux_session_cnt] = value;
        if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) {
            ctx.aux_session_cnt++;
        } else {
            LOG_ERR("Specify a max of 3 sessions");
            return false;
        }
        break;
    case 'n':
        ctx.precalc_nvname.size = BUFFER_SIZE(TPM2B_NAME, name);
        int q = tpm2_util_hex_to_byte_structure(value, &ctx.precalc_nvname.size,
        ctx.precalc_nvname.name);
        if (q) {
            LOG_ERR("FAILED: %d", q);
            return false;
        }
        break;
    }

    return true;
}

static bool tpm2_tool_onstart(tpm2_options **opts) {

    const struct option topts[] = {
        { "hierarchy", required_argument, NULL, 'C' },
        { "auth",      required_argument, NULL, 'P' },
        { "bits",      required_argument, NULL, 'i' },
        { "cphash",    required_argument, NULL,  0  },
        { "rphash",    required_argument, NULL,  1  },
        { "session",   required_argument, NULL, 'S' },
        { "name",      required_argument, NULL, 'n' },
    };

    *opts = tpm2_options_new("C:P:i:S:n:", ARRAY_LEN(topts), topts, on_option,
            on_arg, TPM2_OPTIONS_OPTIONAL_SAPI_AND_FAKE_TCTI);

    return *opts != NULL;
}

static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {

    UNUSED(flags);

    /*
     * 1. Process options
     */
    tool_rc rc = check_options(flags);
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 2. Process inputs
     */
    rc = process_inputs(ectx);
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 3. TPM2_CC_<command> call
     */
    rc = nvsetbits(ectx);
    if (rc != tool_rc_success) {
        return rc;
    }

    /*
     * 4. Process outputs
     */
    return process_output(ectx);
}

static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) {

    UNUSED(ectx);
    /*
     * 1. Free objects
     */

    /*
     * 2. Close authorization sessions
     */
    tool_rc rc = tool_rc_success;
    tool_rc tmp_rc = tpm2_session_close(&ctx.auth_hierarchy.object.session);
    if (tmp_rc != tool_rc_success) {
        rc = tmp_rc;
    }

    /*
     * 3. Close auxiliary sessions
     */
    size_t i = 0;
    for(i = 0; i < ctx.aux_session_cnt; i++) {
        if (ctx.aux_session_path[i]) {
            tmp_rc = tpm2_session_close(&ctx.aux_session[i]);
            if (tmp_rc != tool_rc_success) {
                rc = tmp_rc;
            }
        }
    }

    return rc;
}

// Register this tool with tpm2_tool.c
TPM2_TOOL_REGISTER("nvsetbits", tpm2_tool_onstart, tpm2_tool_onrun,
    tpm2_tool_onstop, NULL)


text:
title: Настройка генератора скриптов для БД
sidebar: guide-practical-guides_sidebar
keywords: guide
toc: true
permalink: ru/gpg_configuring-script-generator-db.html
lang: ru
---

1.	Перейти на стадию: выберать в дереве слева пункт `Стадия` левой кнопкой мыши.

![](/images/pages/guides/flexberry-aspnet/stage.png)

2.Далее нажать на стадии правой кнопкой мыши. В появившемся меню выберать пункт `ASP.NET` -> `SQL` -> `Microsoft SQL Server` -> `Настройка БД`. Появится окно `Стадия (редактирование)`.

3.В появившемся окне изменить поле `Строка соединения`:

 * вместо `server` надо указать имя конкретного сервера; для локального сервера могут использоваться следующие варианты:
    * .\<имя экземпляра SQL SERVER> или <имя компьютера>\<имя экземпляра SQL SERVER>, например, .\SQLEXPRESS
    * <имя компьютера>
    * (local)
* вместо `database` необходимо указать имя конкретной базы данных, с которой будет работать приложение – желательно указать имя несуществующей базы данных, так как при первой генерации она будет создана автоматически.

Пример строки соединения: `SERVER=.\SQLEXPRESS;Trusted_connection=yes;DATABASE=sklad;`
__Примечание:__ если один из вариантов окажется нерабочим, попробуйте другие.

4.Установить в поле `Дополнительные настройки` «галочку» `БД полномочий в БД приложения`.

![](/images/pages/guides/flexberry-aspnet/stage-edit.jpg)

5.Нажать кнопку `Сохранить и закрыть` ![](/images/pages/guides/flexberry-aspnet/save-and-close.png).

6.Далее нажать на стадии правой кнопкой мыши. В появившемся меню выберите пункт `ASP.NET` -> `SQL` -> `Microsoft SQL Server` -> `Привести БД в соответствие с моделью`. Появится окно `Сообщения…`.

![](/images/pages/guides/flexberry-aspnet/messages.png)

Если база данных, указанная в строке соединения не существует, то она будет создана. Также будет сгенерирован скрипт, который представляет собой набор SQL-DDL-команд. В результате их применения будет получена структура базы данных, соответствующая модели.

7.Если база данных успешно создана и генерация скрипта завершена, всплывет окно `Результат` с вопросом о применении этого скрипта. Следует нажать `Применить`.

![](/images/pages/guides/flexberry-aspnet/script.jpg)

8.В окне `Требуется подтверждение` необходимо подтвердить применение скрипта - нажмите `Да`.

![](/images/pages/guides/flexberry-aspnet/script-application.png)

9.В результате скрипт будет применен:

![](/images/pages/guides/flexberry-aspnet/script-applied.png)

10.Закрыть все окна с сообщениями.

## Перейти

*   [Подготовительный этап разработки веб-приложений](gpg_preparatory-stage.html)
* [Создание прототипа](gpg_prototype-creating.html)


text:
(function() {
  var backgroundPage = chrome.extension.getBackgroundPage();
  var search_pane = 2;

  // click to open tweet window (new tweet)
  $('#open_tweetarea').click(function() {
    TWITT.tweet_intents();
  });

  $('p.source a').attr("target","_blank");
  $('.word_menu').click(function() {
    return false;
  });
  $('.head_word_listdown_button').click(function() {
    return false;
  });
  $('.add_word_button').click(function() {
    return false;
  });
  var logo_html = '
';
  logo_html += '
';

  $('#logout').click(function() {
    TWITT.jsoauth.endSession(function(data) {
      var json = JSON.parse(data.text);
      //console.log(json);
      //console.log(backgroundPage.TWITT.conf.tabid);
      //console.log(TWITT.conf.tabid);
      TWITT.removeTab(backgroundPage.TWITT.conf.tabid);
    });
  });

  /*
   * open reply
   */
  $('#home_timeline').delegate('.reply','click',function() {
    var tweet_id = $(this).attr('tweet_id');
    var obj = $('#tw'+tweet_id);
    TWITT.onClickReply(obj);
  });

  /*
   * open reply with edit
   */
  $('#home_timeline').delegate('.share_rt','click',function() {
    var tweet_id = $(this).attr('tweet_id');
    var obj = $('#tw'+tweet_id);
    TWITT.onClickShareReply(obj);
  });

  /*
   * open retweet
   */
  $('#home_timeline').delegate('.retweet','click',function() {
    var tweet_id = $(this).attr('tweet_id');
    var obj = $('#tw'+tweet_id);
    TWITT.onClickRetweet(obj); // home_timeline上のretweetボタン押した時
  });

  /*
   * delete tweet
   */
  $('#home_timeline').delegate('.destroy_tweet','click',function() {
    var tweet_id = $(this).attr('tweet_id');
    var obj = $('#tw'+tweet_id);
    TWITT.onClickDestroy(obj);
  });

  /*
   * pick up list name (pane 1)
   */
  $('#head_tweets1').delegate('li.lists_list', 'click', function() {
    var pane_id = 1;
    var name = $(this).find('a').attr('list_name');

    /*
     * stop current search
     */
    if (TWITT.conf.search_data["1"] !== undefined) {
      clearTimeout(TWITT.conf.search_data["1"].timer);
    }
    if (TWITT.conf.lists_data["1"] !== undefined) {
      clearTimeout(TWITT.conf.lists_data["1"].timer);
    }

    $('#tweets'+pane_id+' .tweet').remove();

    var params = {
      "name": name,
      "max_id_str": 0
    };

    if (TWITT.conf.lists_data["1"] != undefined) {
      TWITT.conf.lists_data["1"].max_id_str = undefined;
    }

    TWITT.list_timeline(params, pane_id);
    TWITT.change_list_words(pane_id, params.name);
  });

  /*
   * pick up list name (pane 2)
   */
  $('#head_tweets2').delegate('li.lists_list', 'click', function() {
    var pane_id = 2;
    var name = $(this).find('a').attr('list_name');

    /*
     * stop current search
     */
    if (TWITT.conf.search_data["2"] !== undefined) {
      clearTimeout(TWITT.conf.search_data["2"].timer);
    }
    if (TWITT.conf.lists_data["2"] !== undefined) {
      clearTimeout(TWITT.conf.lists_data["2"].timer);
    }

    $('#tweets'+pane_id+' .tweet').remove();

    var params = {
      "name": name,
      "max_id_str": 0
    };

    if (TWITT.conf.lists_data["2"] != undefined) {
      //console.log(TWITT.conf.lists_data["2"].max_id_str);
      TWITT.conf.lists_data["2"].max_id_str = undefined;
    }

    console.log(params);
    TWITT.list_timeline(params, pane_id);
    TWITT.change_list_words(pane_id, params.name);
  });

  // Undo retweet (off since cannot get ID)
  /*
  $('#home_timeline').delegate('.undo_retweet', 'click', function() {
    console.log(this);
    var tweet_id = $(this).attr('tweet_id');
    var obj = $('#tw'+tweet_id);
    console.log(obj);
    TWITT.onClickUndoRetweet(obj);
  });
  */

  TWITT.jsoauth = backgroundPage.TWITT.jsoauth;
  var jsoauth = backgroundPage.TWITT.jsoauth;

  if (localStorage.oauth_token && localStorage.oauth_token_secret) {
    var oauth_token = localStorage.oauth_token;
    var oauth_token_secret = localStorage.oauth_token_secret;
    TWITT.jsoauth.oauth.setAccessToken([oauth_token, oauth_token_secret]);
  }

  /*
   * main
   */
  jsoauth.verifyCredentials(function(data) {
    var json = JSON.parse(data.text);
    var send_data = {
      'screen_name': json.screen_name,
      'profile_image_url': json.profile_image_url,
      'id_str' : json.id_str
    };

    // send screen_name to background listener
    chrome.extension.sendRequest({msg:"set_screen_name", body: send_data}, function(response) {});

    TWITT.get_saved_searches(function(){
      var ary_words = TWITT.get_words();
      var n = 0;
      /*
       * start searching
       */
      $('div.pane').delay(5000).each(function (e) {
        TWITT.search_pane(n+1, ary_words); // 検索のdropdown menuをセット
        var pane_id = $(this).attr('pane_id');
        //console.log(ary_words[n]);
        var m = ary_words[n].match(/^\((.*?)\)$/);
        if (m) {
          // list name case
          //console.log(m);
          var params = {
            'name': m[1],
            'max_id_str': 0
          };
          //console.log(JSON.stringify(params));
          TWITT.list_timeline(params, pane_id);
        } else {
          TWITT.search_tweets(pane_id, ary_words[n]);
        }
        n += 1;
        TWITT.add_search(pane_id); // set search form event
      });

      TWITT.init_timeline();
      TWITT.jsoauth.rateLimitStatus(function(data) {
        var json = JSON.parse(data.text);
        //console.log(json);
        $('#my_title').text(send_data.screen_name +
         ' (home_timeline api limit ' +
        json.resources.statuses['/statuses/home_timeline'].remaining + '/' +
        json.resources.statuses['/statuses/home_timeline'].limit + ')');
      });
    });

    /*
     * add lists to dropdown menu
     */
    TWITT.get_lists_all(function(json) {
      TWITT.set_lists(json);
      var s = TWITT.lists_list(json);
      TWITT.dropdown_append_lists(1, s);
      TWITT.dropdown_append_lists(2, s);
    });

  });

  $("#home_timeline").bottom(); // add event on scroll to bottom
  $("#home_timeline").bind("bottom", function() {
    TWITT.timeline_maxid(); // get old home_timeline
  });

}());


text:
#import <Foundation/Foundation.h>

#import <Parse/PFConstants.h>

#import "PFEncoder.h"

@class PFFileManager;
@class PFKeychainStore;
@class PFNetworkCommand;

@interface PFInternalUtils : NSObject

+ (NSString *)parseServerURLString;
+ (void)setParseServer:(NSString *)server;

+ (NSNumber *)fileSizeOfFileAtPath:(NSString *)filePath error:(NSError **)error;

/**
 Clears system time zone cache, gets the name of the time zone
 and caches it. This method is completely thread-safe.
 */
+ (NSString *)currentSystemTimeZoneName;

/**
 * Performs selector on the target, only if the target and selector are non-nil,
 * as well as target responds to selector
 */
+ (void)safePerformSelector:(SEL)selector withTarget:(id)target object:(id)object object:(id)anotherObject;

+ (NSNumber *)addNumber:(NSNumber *)first withNumber:(NSNumber *)second;

//
// Given an NSDictionary/NSArray/NSNumber/NSString even nested ones
// Generates a cache key that can be used to identify this object
+ (NSString *)cacheKeyForObject:(id)object;

/**!
 * Does a deep traversal of every item in object, calling block on every one.
 * @param object The object or array to traverse deeply.
 * @param block The block to call for every item. It will be passed the item
 * as an argument. If it returns a truthy value, that value will replace the
 * item in its parent container.
 * @return The result of calling block on the top-level object itself.
 **/
+ (id)traverseObject:(id)object usingBlock:(id (^)(id object))block;

/*!
 This method will split an array into multiple arrays, each with up to maximum components count.

 @param array      Array to split.
 @param components Number of components that should be used as a max per each subarray.

 @return Array of arrays constructed by splitting the array.
 */
+ (NSArray *)arrayBySplittingArray:(NSArray *)array withMaximumComponentsPerSegment:(NSUInteger)components;

+ (id)_stringWithFormat:(NSString *)format arguments:(NSArray *)arguments;

@end


text:
<?php

namespace Symfony\Component\Finder\Tests\Iterator;

use Symfony\Component\Finder\Iterator\FilenameFilterIterator;

class FilenameFilterIteratorTest extends IteratorTestCase
{
    /**
     * @dataProvider getAcceptData
     */
    public function testAccept($matchPatterns, $noMatchPatterns, $expected)
    {
        $inner = new InnerNameIterator(array('test.php', 'test.py', 'foo.php'));

        $iterator = new FilenameFilterIterator($inner, $matchPatterns, $noMatchPatterns);

        $this->assertIterator($expected, $iterator);
    }

    public function getAcceptData()
    {
        return array(
            array(array('test.*'), array(), array('test.php', 'test.py')),
            array(array(), array('test.*'), array('foo.php')),
            array(array('*.php'), array('test.*'), array('foo.php')),
            array(array('*.php', '*.py'), array('foo.*'), array('test.php', 'test.py')),
            array(array('/\.php$/'), array(), array('test.php', 'foo.php')),
            array(array(), array('/\.php$/'), array('test.py')),
        );
    }
}

class InnerNameIterator extends \ArrayIterator
{
    public function current()
    {
        return new \SplFileInfo(parent::current());
    }

    public function getFilename()
    {
        return parent::current();
    }
}


text:
"""TF metrics for Bandits algorithms."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from typing import Callable, Optional, Text

import gin
import tensorflow as tf  # pylint: disable=g-explicit-tensorflow-version-import

from tf_agents.bandits.policies import constraints
from tf_agents.bandits.specs import utils as bandit_spec_utils
from tf_agents.metrics import tf_metric
from tf_agents.typing import types
from tf_agents.utils import common

@gin.configurable
class RegretMetric(tf_metric.TFStepMetric):
  """Computes the regret with respect to a baseline."""

  def __init__(self,
               baseline_reward_fn: Callable[[types.Tensor], types.Tensor],
               name: Optional[Text] = 'RegretMetric',
               dtype: float = tf.float32):
    """Computes the regret with respect to a baseline.

    The regret is computed by computing the difference of the current reward
    from the baseline action reward. The latter is computed by calling the input
    `baseline_reward_fn` function that given a (batched) observation computes
    the baseline action reward.

    Args:
      baseline_reward_fn: function that computes the reward used as a baseline
        for computing the regret.
      name: (str) name of the metric
      dtype: dtype of the metric value.
    """
    self._baseline_reward_fn = baseline_reward_fn
    self.dtype = dtype
    self.regret = common.create_variable(
        initial_value=0, dtype=self.dtype, shape=(), name='regret')
    super(RegretMetric, self).__init__(name=name)

  def call(self, trajectory):
    """Update the regret value.

    Args:
      trajectory: A tf_agents.trajectory.Trajectory

    Returns:
      The arguments, for easy chaining.
    """
    baseline_reward = self._baseline_reward_fn(trajectory.observation)
    trajectory_reward = trajectory.reward
    if isinstance(trajectory.reward, dict):
      trajectory_reward = trajectory.reward[bandit_spec_utils.REWARD_SPEC_KEY]
    trajectory_regret = baseline_reward - trajectory_reward
    self.regret.assign(tf.reduce_mean(trajectory_regret))
    return trajectory

  def result(self):
    return tf.identity(
        self.regret, name=self.name)

@gin.configurable
class SuboptimalArmsMetric(tf_metric.TFStepMetric):
  """Computes the number of suboptimal arms with respect to a baseline."""

  def __init__(self,
               baseline_action_fn: Callable[[types.Tensor], types.Tensor],
               name: Optional[Text] = 'SuboptimalArmsMetric',
               dtype: float = tf.float32):
    """Computes the number of suboptimal arms with respect to a baseline.

    Args:
      baseline_action_fn: function that computes the action used as a baseline
        for computing the metric.
      name: (str) name of the metric
      dtype: dtype of the metric value.
    """
    self._baseline_action_fn = baseline_action_fn
    self.dtype = dtype
    self.suboptimal_arms = common.create_variable(
        initial_value=0, dtype=self.dtype, shape=(), name='suboptimal_arms')
    super(SuboptimalArmsMetric, self).__init__(name=name)

  def call(self, trajectory):
    """Update the metric value.

    Args:
      trajectory: A tf_agents.trajectory.Trajectory

    Returns:
      The arguments, for easy chaining.
    """
    baseline_action = self._baseline_action_fn(trajectory.observation)
    disagreement = tf.cast(
        tf.not_equal(baseline_action, trajectory.action), tf.float32)
    self.suboptimal_arms.assign(tf.reduce_mean(disagreement))
    return trajectory

  def result(self):
    return tf.identity(
        self.suboptimal_arms, name=self.name)

@gin.configurable
class ConstraintViolationsMetric(tf_metric.TFStepMetric):
  """Computes the violations of a certain constraint."""

  def __init__(self,
               constraint: constraints.BaseConstraint,
               name: Optional[Text] = 'ConstraintViolationMetric',
               dtype: float = tf.float32):
    """Computes the constraint violations given an input constraint.

    Given a certain constraint, this metric computes how often the selected
    actions in the trajectory violate the constraint.

    Args:
      constraint: an instance of `tf_agents.bandits.policies.BaseConstraint`.
      name: (str) name of the metric
      dtype: dtype of the metric value.
    """
    self._constraint = constraint
    self.dtype = dtype
    self.constraint_violations = common.create_variable(
        initial_value=0.0,
        dtype=self.dtype,
        shape=(),
        name='constraint_violations')
    super(ConstraintViolationsMetric, self).__init__(name=name)

  def call(self, trajectory):
    """Update the constraint violations metric.

    Args:
      trajectory: A tf_agents.trajectory.Trajectory

    Returns:
      The arguments, for easy chaining.
    """
    feasibility_prob_all_actions = self._constraint(trajectory.observation)
    feasibility_prob_selected_actions = common.index_with_actions(
        feasibility_prob_all_actions,
        tf.cast(trajectory.action, dtype=tf.int32))
    self.constraint_violations.assign(tf.reduce_mean(
        1.0 - feasibility_prob_selected_actions))
    return trajectory

  def result(self):
    return tf.identity(self.constraint_violations, name=self.name)

@gin.configurable
class DistanceFromGreedyMetric(tf_metric.TFStepMetric):
  """Difference between the estimated reward of the chosen and the best action.

  This metric measures how 'safely' the agent explores: it calculates the
  difference between what the agent thinks it would have gotten had it chosen
  the best looking action, vs the action it actually took. This metric is not
  equivalent to the regret, because the regret is calculated as a distance from
  optimality, while here everything calculated is based on the policy's
  'belief'.
  """

  def __init__(self,
               estimated_reward_fn: Callable[[types.Tensor], types.Tensor],
               name: Optional[Text] = 'DistanceFromGreedyMetric',
               dtype: float = tf.float32):
    """Init function for the metric.

    Args:
      estimated_reward_fn: A function that takes the observation as input and
        computes the estimated rewards that the greedy policy uses.
      name: (str) name of the metric
      dtype: dtype of the metric value.
    """
    self._estimated_reward_fn = estimated_reward_fn
    self.dtype = dtype
    self.safe_explore = common.create_variable(
        initial_value=0, dtype=self.dtype, shape=(), name='safe_explore')
    super(DistanceFromGreedyMetric, self).__init__(name=name)

  def call(self, trajectory):
    """Update the metric value.

    Args:
      trajectory: A tf_agents.trajectory.Trajectory

    Returns:
      The arguments, for easy chaining.
    """
    all_estimated_rewards = self._estimated_reward_fn(trajectory.observation)
    max_estimated_rewards = tf.reduce_max(all_estimated_rewards, axis=-1)
    estimated_action_rewards = tf.gather(
        all_estimated_rewards, trajectory.action, batch_dims=1)
    self.safe_explore.assign(
        tf.reduce_mean(max_estimated_rewards - estimated_action_rewards))
    return trajectory

  def result(self):
    return tf.identity(self.safe_explore, name=self.name)


text:
Here is an example of how to write an O2 Platform IE Automation script that will login a user into a wifi connection that needs a username and password.

Open the IE Script tool which you can get from this [stand-alone version](https://o2platform.googlecode.com/files/IE%20Automation%20%28Simple%20mode%29%20v1.0.exe) (see [Packaging an O2 Platform Script as a stand alone tool (in this case the WatiN based 'IE Script' tool)](https://blog.diniscruz.com/2013/03/packaging-o2-platform-script-as-stand.html) )

Or from the main O2 Platform gui:

[![image](images/image_thumb_25255B70_25255D.png)](http://lh5.ggpht.com/-28XByN_H4K0/UUMoEH_FTzI/AAAAAAAAKtc/A5gdYqAJ6-k/s1600-h/image%25255B151%25255D.png)

When opened it, should look like this:

[![image](images/image_thumb_25255B71_25255D.png)](http://lh4.ggpht.com/-FAfrPooOvlg/UUMoJo-G9gI/AAAAAAAAKts/lIf7keoxKho/s1600-h/image%25255B154%25255D.png)

Leave the first line and open the default wifi connection page (see at the end of this post for the scripts created in a format you can copy and paste):

[![image](images/image_thumb_25255B3_25255D1.png)](http://lh3.ggpht.com/-0O26JHlZM4I/UUMoN7g4U0I/AAAAAAAAKt8/3yw8TWb74O0/s1600-h/image%25255B7%25255D.png)

Take a look at the HTML links of this page (I commented out the **_ie.open_** since the browser session is persisted on multiple executions):

[![image](images/image_thumb_25255B5_25255D1.png)](http://lh3.ggpht.com/-kI8PoDidit8/UUMoRsLNhbI/AAAAAAAAKuM/y6F9SK-KCqk/s1600-h/image%25255B13%25255D.png)

Here is how to get a specific link (note the multiple variations caused by the fact that the **_Get Online_** link has no ID and a new line in its text:

[![image](images/image_thumb_25255B6_25255D1.png)](http://lh4.ggpht.com/-wARin3Thnk4/UUMoXeu_ruI/AAAAAAAAKuc/ciKuWeBbHMQ/s1600-h/image%25255B16%25255D.png)

Next step is to click on the link:

[![image](images/image_thumb_25255B7_25255D.png)](http://lh5.ggpht.com/-AYJqbfGUd1E/UUMoai0_API/AAAAAAAAKus/zdacQquxITg/s1600-h/image%25255B19%25255D.png)

Next get the links for this page and look at the details of the link we want to click next:

[![image](images/image_thumb_25255B10_25255D.png)](http://lh6.ggpht.com/-z5iVf50C7ac/UUMoeLI2A0I/AAAAAAAAKu8/R704z3qA-Aw/s1600-h/image%25255B28%25255D.png)

Which has the same issue of a new line at the beginning and no ID

[![image](images/image_thumb_25255B20_25255D1.png)](http://lh3.ggpht.com/-UOFXE9p9w5I/UUMohY8iAaI/AAAAAAAAKvM/3o3ieDPtHgo/s1600-h/image%25255B34%25255D.png)

Let's click on that Link:

[![image](images/image_thumb_25255B21_25255D1.png)](http://lh4.ggpht.com/-_PrXBMdek9E/UUMoj8LBC4I/AAAAAAAAKvc/DRtQNvAdaOk/s1600-h/image%25255B37%25255D.png)

And look at the fields in this page:

[![image](images/image_thumb_25255B22_25255D.png)](http://lh6.ggpht.com/-u4m7oZy7aN0/UUMonDcqq8I/AAAAAAAAKvs/DbWEEpCo-Wk/s1600-h/image%25255B40%25255D.png)

In there find the **_password_** one

[![image](images/image_thumb_25255B23_25255D.png)](http://lh6.ggpht.com/-wQzFyamt5kU/UUMoqZDtN3I/AAAAAAAAKv8/yBO8ugFbhtk/s1600-h/image%25255B43%25255D.png)

Note that we can edit this field and see its changes in real-time:

[![image](images/image_thumb_25255B26_25255D1.png)](http://lh3.ggpht.com/-9n56OoB5gl4/UUMouNAbvUI/AAAAAAAAKwM/zckoa_lKvZE/s1600-h/image%25255B50%25255D.png)  [![image](images/image_thumb_25255B27_25255D1.png)](http://lh3.ggpht.com/-bEI7oLBbhGA/UUMoy-O8qNI/AAAAAAAAKwc/6JXHymZYAS0/s1600-h/image%25255B51%25255D.png)

We can now get the reference to the password field:

[![image](images/image_thumb_25255B28_25255D.png)](http://lh5.ggpht.com/-Uhy3TmjBS9g/UUMo1vrHEoI/AAAAAAAAKws/uJYYiQlQ7sc/s1600-h/image%25255B54%25255D.png)

and change its value programmatically:

[![image](images/image_thumb_25255B29_25255D.png)](http://lh4.ggpht.com/-E7LO34t6Vyg/UUMo4Ua_CXI/AAAAAAAAKw8/VwSsY1R5VOo/s1600-h/image%25255B57%25255D.png)

Now the email field is going to be a little more complicated since it wasn't picked up by the **_fields WatiN _**Extension Method.

So take a look at the _**.elements() **_:

[![image](images/image_thumb_25255B30_25255D.png)](http://lh3.ggpht.com/-DXD9A4ca4KA/UUMo8GgrNGI/AAAAAAAAKxM/mo7kO9fca4Q/s1600-h/image%25255B60%25255D.png)

And get a programmatic reference to it:

[![image](images/image_thumb_25255B32_25255D.png)](http://lh5.ggpht.com/-i2pfK0GR_GE/UUMpC8jqDAI/AAAAAAAAKxc/cW9uRQjcGtI/s1600-h/image%25255B66%25255D.png)

Get its outerHtml (at this stage I'm trying to figure out the most efficient way to populate it)

[![image](images/image_thumb_25255B33_25255D1.png)](http://lh6.ggpht.com/-Xnzo5U4J7Ao/UUMpFbQRl3I/AAAAAAAAKxs/IutMX0FBBI0/s1600-h/image%25255B69%25255D.png)

Here are the element attributes:

[![image](images/image_thumb_25255B34_25255D1.png)](http://lh4.ggpht.com/-GRcd0H_506Y/UUMpIVIHTiI/AAAAAAAAKx8/1FGD7ZTC5eQ/s1600-h/image%25255B72%25255D.png)

Btw: taking a look at the parent's element outerHtml we can see that this input element is not properly terminated:

[![image](images/image_thumb_25255B35_25255D1.png)](http://lh6.ggpht.com/-YkRpM1PezWg/UUMpKics8EI/AAAAAAAAKyM/Qpp-nUY45Hk/s1600-h/image%25255B75%25255D.png)

Ok, here is one way to populate the Email field (by directly changing/replacing the outerHtml)

[![image](images/image_thumb_25255B36_25255D1.png)](http://lh3.ggpht.com/-8ivpMmAqCnk/UUMpNQ0ueCI/AAAAAAAAKyc/10ALzlUP3hw/s1600-h/image%25255B78%25255D.png)

And since they are using jQuery on this site, we can use also use jQuery to populate that field:

[![image](images/image_thumb_25255B37_25255D1.png)](http://lh4.ggpht.com/-tcdwd26ILHs/UUMpQoDKTTI/AAAAAAAAKys/EitonrilTE4/s1600-h/image%25255B81%25255D.png)

**Top tip**: you can also get javascript objects into your C# script. For example here is how to get the value of the email we just populated:

[![image](images/image_thumb_25255B38_25255D1.png)](http://lh3.ggpht.com/-9PtMRjcK-oo/UUMpTonJNVI/AAAAAAAAKy8/WdBgAQCX8a8/s1600-h/image%25255B84%25255D.png)

The **document.location** object

[![image](images/image_thumb_25255B39_25255D1.png)](http://lh5.ggpht.com/-UcYeFT1MD2k/UUMpXvBjNMI/AAAAAAAAKzM/4VjN4XI0cBU/s1600-h/image%25255B87%25255D.png)

The **window.screen** object

[![image](images/image_thumb_25255B40_25255D.png)](http://lh5.ggpht.com/-SidlJ220-Ck/UUMpa2EqOzI/AAAAAAAAKzc/s9hzTRpFASg/s1600-h/image%25255B90%25255D.png)

A **jQuery** selector:

[![image](images/image_thumb_25255B42_25255D1.png)](http://lh4.ggpht.com/--lZrtTQCrwY/UUMpfQALqqI/AAAAAAAAKzs/01FB15JmIKk/s1600-h/image%25255B96%25255D.png)

The **body html** (as seen by jQuery)

[![image](images/image_thumb_25255B43_25255D1.png)](http://lh5.ggpht.com/-iJKPpYPdZY8/UUMpi1yueCI/AAAAAAAAKz8/Z7XruXZuqHM/s1600-h/image%25255B99%25255D.png)

**ok, moving back to our login page....**

Now that we can populate data into both input fields, we need to find the button:

[![image](images/image_thumb_25255B44_25255D1.png)](http://lh3.ggpht.com/-0tcOUcsw7ug/UUMpng3FUwI/AAAAAAAAK0M/cMFSJS2rDH0/s1600-h/image%25255B102%25255D.png)

and click on it:

[![image](images/image_thumb_25255B46_25255D1.png)](http://lh5.ggpht.com/-aF4i7_mPTVw/UUMptwX67CI/AAAAAAAAK0c/eQnytw0toDk/s1600-h/image%25255B108%25255D.png)

Now that its working let's package the whole script into a lamdba method:

[![image](images/image_thumb_25255B48_25255D.png)](http://lh5.ggpht.com/-XwtTkt-Hw2A/UUMpwsi7GvI/AAAAAAAAK0s/-ZSQRr2YMZ0/s1600-h/image%25255B114%25255D.png)

**Note: **since we have jQuery, we could use it to add an attribute to the link, and then get that link from the C# REPL (instead of doing that lamda search):

[![image](images/image_thumb_25255B47_25255D1.png)](http://lh3.ggpht.com/-ISEQvDjRVhQ/UUMp0gwhAaI/AAAAAAAAK08/BrYi3YF2_ko/s1600-h/image%25255B111%25255D.png)

Next step is to ask the user for the account details and use it to login:

[![image](images/image_thumb_25255B49_25255D.png)](http://lh4.ggpht.com/-dEerevQ-wAU/UUMp4EMwwdI/AAAAAAAAK1M/Tj2k5KiVbmU/s1600-h/image%25255B117%25255D.png)

Now, when you click execute you will get a popup you can use to enter the email and password:

[![image](images/image_thumb_25255B51_25255D.png)](http://lh4.ggpht.com/-FQrMozZZzPc/UUMp6gaGCRI/AAAAAAAAK1c/yhMywPd2UFg/s1600-h/image%25255B123%25255D.png)

And if all goes good you will be logged in, and google should open up:

[![image](images/image_thumb_25255B52_25255D.png)](http://lh3.ggpht.com/-FVkTb4Ekr1k/UUMp852Y1UI/AAAAAAAAK1s/NFWw1xzILvM/s1600-h/image%25255B126%25255D.png)

Finally, we can make this into a stand alone script:

[![image](images/image_thumb_25255B53_25255D.png)](http://lh3.ggpht.com/-E1MT0AvjT9I/UUMqAaAePqI/AAAAAAAAK18/MQMA82mVUeY/s1600-h/image%25255B129%25255D.png)

which will open the IE/WatiN control in a popup window:

[![image](images/image_thumb_25255B55_25255D.png)](http://lh3.ggpht.com/-zFP2yv7qt3w/UUMqCUAabYI/AAAAAAAAK2M/izNJ75G9430/s1600-h/image%25255B133%25255D.png) and  [![image](images/image_thumb_25255B57_25255D.png)](http://lh6.ggpht.com/-oEDojg653bo/UUMqEgtgaQI/AAAAAAAAK2c/iT4uIjzEeBI/s1600-h/image%25255B137%25255D.png)

and even package it as a stand-alone exe:

[![image](images/image_thumb_25255B63_25255D.png)](http://lh3.ggpht.com/-Z-S9rojQAgA/UUMqHl-BWzI/AAAAAAAAK2s/pWiifwkT4B8/s1600-h/image%25255B141%25255D.png)

which can then be executed directly:

[![image](images/image_thumb_25255B64_25255D.png)](http://lh3.ggpht.com/-wWS7mM-bvYM/UUMqLI03LCI/AAAAAAAAK28/LXU0XDJSf3Y/s1600-h/image%25255B144%25255D.png)

(note that in this case there are no extra folders since the embedded dlls are extracted directly into memory and there are no scripts to dynamically compile)

[![image](images/image_thumb_25255B65_25255D.png)](http://lh6.ggpht.com/-ZO0J0jg_WvA/UUMqPtjoQaI/AAAAAAAAK3M/P-vw0G4DW4k/s1600-h/image%25255B147%25255D.png)
**
****
****Scripts used in this blog:**

**Open web page**

    var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);  // ie random value for o2cache makes this object to unique amongst multiple instances of this control
    ie.open("https://service.thecloud.net/service-platform/");

    return "done";

    //O2File:WatiN_IE_ExtensionMethods.cs
    //O2Ref:WatiN.Core.1x.dll
    //O2Tag_DontAddExtraO2Files;

**Multiple ways to get the GetOnline link:**

    var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);
    //ie.open("https://service.thecloud.net/service-platform/");
    var getOnlineLink = ie.link(@"
    Get Online");
    return getOnlineLink.text();

    //these also work;
    return ie.links()[2].text();
    return ie.links().third().text();
    return ie.links().where((link)=> link.text().contains("Get Online")).first();

    //O2File:WatiN_IE_ExtensionMethods.cs
    //O2Ref:WatiN.Core.1x.dll
    //O2Tag_DontAddExtraO2Files;

**Populating the email field using jQuery:**

    var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);
    //ie.open("https://service.thecloud.net/service-platform/");
    //var getOnlineLink = ie.links().where((link)=> link.text().contains("Get Online")).first();
    //getOnlineLink.click();
    //ie.link(@"
    //Free Cloud WiFi").click();
    ie.eval("$('#username').val('AAAAAanother@email.com')");
    return ie.getJsVariable("$('#username').val()");
    return "done";

    //O2File:WatiN_IE_ExtensionMethods.cs
    //O2Ref:WatiN.Core.1x.dll
    //O2Tag_DontAddExtraO2Files;

**Login script as Lambda method**

    var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);

    Action<string,string> loginIntoTheCloud =
    (email, password)=>
    {
    ie.open("https://service.thecloud.net/service-platform/");
    ie.links()
    .where((link)=> link.text().contains("Get Online")).first().click();
    ie.links()
    .where((link)=> link.text().contains("Free Cloud WiFi")).first().click();
    ie.link(@"").click();

    ie.eval("$('#username').val('{0}')".format(email));
    ie.field("password").value(password);
    ie.buttons().first().click();
    };

    loginIntoTheCloud("another@email.com", "password");
    return "done";
    //O2File:WatiN_IE_ExtensionMethods.cs
    //O2Ref:WatiN.Core.1x.dll
    //O2Tag_DontAddExtraO2Files;

**Adding an ID to an element using jQuery:**

    var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);

    ie.open("https://service.thecloud.net/service-platform/");
    ie.eval("$(\"a :contains('Online')\").first().parent().attr('id','myLink')");
    return ie.link("myLink");
    **Full script with login and redirect to google:**

        var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);

    Action<string,string> loginIntoTheCloud =
    (email, password)=>
    {
    ie.open("https://service.thecloud.net/service-platform/");
    ie.links()
    .where((link)=> link.text().contains("Get Online")).first().click();
    ie.links()
    .where((link)=> link.text().contains("Free Cloud WiFi")).first().click();
    ie.link(@"").click();

    ie.eval("$('#username').val('{0}')".format(email));
    ie.field("password").value(password);
    ie.buttons().first().click();
    };

    var credentials = ie.askUserForUsernameAndPassword();

    loginIntoTheCloud(credentials.UserName, credentials.Password);
    ie.waitForComplete();
    ie.open("http://www.google.com");

    //O2File:WatiN_IE_ExtensionMethods.cs
    //O2Ref:WatiN.Core.1x.dll
    //O2Tag_DontAddExtraO2Files;

**Final version of the script:**

    //var ie = "ie_aenoN".o2Cache<WatiN_IE>(()=> panel.clear().add_IE()).silent(false);
    var ie = "Util - Login into the cloud Wifi".popupWindow()
                                               .add_IE();

    Action<string,string> loginIntoTheCloud =
    (email, password)=>
    {
    ie.open("https://service.thecloud.net/service-platform/");
    ie.links()
    .where((link)=> link.text().contains("Get Online")).first().click();
    ie.links()
    .where((link)=> link.text().contains("Free Cloud WiFi")).first().click();
    ie.link(@"").click();

    ie.eval("$('#username').val('{0}')".format(email));
    ie.field("password").value(password);
    ie.buttons().first().click();
    };

    var credentials = ie.askUserForUsernameAndPassword();

    loginIntoTheCloud(credentials.UserName, credentials.Password);
    ie.waitForComplete();
    ie.open("http://www.google.com");

    //O2File:WatiN_IE_ExtensionMethods.cs
    //O2Ref:WatiN.Core.1x.dll
    //O2Tag_DontAddExtraO2Files;


text:
Chess moves travelling through WebRTC.

## Build Instructions

**Server**

Install [Go](https://golang.org/) and then:

```sh
# cd to the project directory
$ cd webrtc-chess

# Build server binary
$ go build
```

**Client**

Install [Node.js](https://nodejs.org/en/) and then:

```sh
# Install dependencies.
$ npm install

# Build
$ npm run build
```

Start the app:

```sh
$ ./webrtc-chess
```

and then navigate to [http://localhost:8080](http://localhost:8080).

## License

[MIT](/LICENSE.md) © Abhineet Tamrakar


text:
// hiding/ChocolateChip.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Can't use package-access member from another package
import hiding.dessert.*;

public class ChocolateChip extends Cookie {
  public ChocolateChip() {
    System.out.println("ChocolateChip constructor");
  }
  public void chomp() {
    //- bite(); // Can't access bite
  }
  public static void main(String[] args) {
    ChocolateChip x = new ChocolateChip();
    x.chomp();
  }
}
/* Output:
Cookie constructor
ChocolateChip constructor
*/


text:
#pragma once

#include <stdint.h>
#include <string.h>
#include <sys/mman.h>

#include <memory>
#include <vector>

#include <unwindstack/Global.h>
#include <unwindstack/Maps.h>

#include "Check.h"
#include "GlobalDebugInterface.h"
#include "MemoryCache.h"
#include "MemoryRange.h"

// This implements the JIT Compilation Interface.
// See https://sourceware.org/gdb/onlinedocs/gdb/JIT-Interface.html
//
// We use it to get in-memory ELF files created by the ART compiler,
// but we also use it to get list of DEX files used by the runtime.

namespace unwindstack {

// Implementation templated for ELF/DEX and for different architectures.
template <typename Symfile, typename Uintptr_T, typename Uint64_T>
class GlobalDebugImpl : public GlobalDebugInterface<Symfile>, public Global {
 public:
  static constexpr int kMaxRaceRetries = 16;
  static constexpr int kMaxHeadRetries = 16;
  static constexpr uint8_t kMagic[8] = {'A', 'n', 'd', 'r', 'o', 'i', 'd', '2'};

  struct JITCodeEntry {
    Uintptr_T next;
    Uintptr_T prev;
    Uintptr_T symfile_addr;
    Uint64_T symfile_size;
    // Android-specific fields:
    Uint64_T timestamp;
    uint32_t seqlock;
  };

  static constexpr size_t kSizeOfCodeEntryV1 = offsetof(JITCodeEntry, timestamp);
  static constexpr size_t kSizeOfCodeEntryV2 = sizeof(JITCodeEntry);

  struct JITDescriptor {
    uint32_t version;
    uint32_t action_flag;
    Uintptr_T relevant_entry;
    Uintptr_T first_entry;
    // Android-specific fields:
    uint8_t magic[8];
    uint32_t flags;
    uint32_t sizeof_descriptor;
    uint32_t sizeof_entry;
    uint32_t seqlock;
    Uint64_T timestamp;
  };

  static constexpr size_t kSizeOfDescriptorV1 = offsetof(JITDescriptor, magic);
  static constexpr size_t kSizeOfDescriptorV2 = sizeof(JITDescriptor);

  // This uniquely identifies entry in presence of concurrent modifications.
  // Each (address,seqlock) pair is unique for each newly created JIT entry.
  struct UID {
    uint64_t address;  // Address of JITCodeEntry in memory.
    uint32_t seqlock;  // This servers as "version" for the given address.

    bool operator<(const UID& other) const {
      return std::tie(address, seqlock) < std::tie(other.address, other.seqlock);
    }
  };

  GlobalDebugImpl(ArchEnum arch, std::shared_ptr<Memory>& memory,
                  std::vector<std::string>& search_libs, const char* global_variable_name)
      : Global(memory, search_libs), global_variable_name_(global_variable_name) {
    SetArch(arch);
  }

  bool ReadDescriptor(uint64_t addr) {
    JITDescriptor desc{};
    // Try to read the full descriptor including Android-specific fields.
    if (!this->memory_->ReadFully(addr, &desc, kSizeOfDescriptorV2)) {
      // Fallback to just the minimal descriptor.
      // This will make the magic check below fail.
      if (!this->memory_->ReadFully(addr, &desc, kSizeOfDescriptorV1)) {
        return false;
      }
    }

    if (desc.version != 1 || desc.first_entry == 0) {
      // Either unknown version, or no jit entries.
      return false;
    }

    // Check if there are extra Android-specific fields.
    if (memcmp(desc.magic, kMagic, sizeof(kMagic)) == 0) {
      jit_entry_size_ = kSizeOfCodeEntryV2;
      seqlock_offset_ = offsetof(JITCodeEntry, seqlock);
    } else {
      jit_entry_size_ = kSizeOfCodeEntryV1;
      seqlock_offset_ = 0;
    }
    descriptor_addr_ = addr;
    return true;
  }

  void ProcessArch() {}

  bool ReadVariableData(uint64_t ptr) { return ReadDescriptor(ptr); }

  // Invoke callback for all symfiles that contain the given PC.
  // Returns true if any callback returns true (which also aborts the iteration).
  template <typename Callback /* (Symfile*) -> bool */>
  bool ForEachSymfile(Maps* maps, uint64_t pc, Callback callback) {
    // Use a single lock, this object should be used so infrequently that
    // a fine grain lock is unnecessary.
    std::lock_guard<std::mutex> guard(lock_);
    if (descriptor_addr_ == 0) {
      FindAndReadVariable(maps, global_variable_name_);
      if (descriptor_addr_ == 0) {
        return false;
      }
    }

    // Try to find the entry in already loaded symbol files.
    for (auto& it : entries_) {
      Symfile* symfile = it.second.get();
      // Check seqlock to make sure that entry is still valid (it may be very old).
      if (symfile->IsValidPc(pc) && CheckSeqlock(it.first) && callback(symfile)) {
        return true;
      }
    }

    // Update all entries and retry.
    ReadAllEntries(maps);
    for (auto& it : entries_) {
      Symfile* symfile = it.second.get();
      // Note that the entry could become invalid since the ReadAllEntries above,
      // but that is ok.  We don't want to fail or refresh the entries yet again.
      // This is as if we found the entry in time and it became invalid after return.
      // This is relevant when ART moves/packs JIT entries. That is, the entry is
      // technically deleted, but only because it was copied into merged uber-entry.
      // So the JIT method is still alive and the deleted data is still correct.
      if (symfile->IsValidPc(pc) && callback(symfile)) {
        return true;
      }
    }

    return false;
  }

  bool GetFunctionName(Maps* maps, uint64_t pc, SharedString* name, uint64_t* offset) {
    // NB: If symfiles overlap in PC ranges, this will check all of them.
    return ForEachSymfile(maps, pc, [pc, name, offset](Symfile* file) {
      return file->GetFunctionName(pc, name, offset);
    });
  }

  Symfile* Find(Maps* maps, uint64_t pc) {
    // NB: If symfiles overlap in PC ranges (which can happen for both ELF and DEX),
    // this will check all of them and return one that also has a matching function.
    Symfile* result = nullptr;
    bool found = ForEachSymfile(maps, pc, [pc, &result](Symfile* file) {
      result = file;
      SharedString name;
      uint64_t offset;
      return file->GetFunctionName(pc, &name, &offset);
    });
    if (found) {
      return result;  // Found symfile with symbol that also matches the PC.
    }
    // There is no matching symbol, so return any symfile for which the PC is valid.
    // This is a useful fallback for tests, which often have symfiles with no functions.
    return result;
  }

  // Read all entries from the process and cache them locally.
  // The linked list might be concurrently modified. We detect races and retry.
  bool ReadAllEntries(Maps* maps) {
    for (int i = 0; i < kMaxRaceRetries; i++) {
      bool race = false;
      if (!ReadAllEntries(maps, &race)) {
        if (race) {
          continue;  // Retry due to concurrent modification of the linked list.
        }
        return false;  // Failed to read entries.
      }
      return true;  // Success.
    }
    return false;  // Too many retries.
  }

  // Read all JIT entries while assuming there might be concurrent modifications.
  // If there is a race, the method will fail and the caller should retry the call.
  bool ReadAllEntries(Maps* maps, bool* race) {
    // New entries might be added while we iterate over the linked list.
    // In particular, an entry could be effectively moved from end to start due to
    // the ART repacking algorithm, which groups smaller entries into a big one.
    // Therefore keep reading the most recent entries until we reach a fixed point.
    std::map<UID, std::shared_ptr<Symfile>> entries;
    for (size_t i = 0; i < kMaxHeadRetries; i++) {
      size_t old_size = entries.size();
      if (!ReadNewEntries(maps, &entries, race)) {
        return false;
      }
      if (entries.size() == old_size) {
        entries_.swap(entries);
        return true;
      }
    }
    return false;  // Too many retries.
  }

  // Read new JIT entries (head of linked list) until we find one that we have seen before.
  // This method uses seqlocks extensively to ensure safety in case of concurrent modifications.
  bool ReadNewEntries(Maps* maps, std::map<UID, std::shared_ptr<Symfile>>* entries, bool* race) {
    // Read the address of the head entry in the linked list.
    UID uid;
    if (!ReadNextField(descriptor_addr_ + offsetof(JITDescriptor, first_entry), &uid, race)) {
      return false;
    }

    // Follow the linked list.
    while (uid.address != 0) {
      // Check if we have reached an already cached entry (we restart from head repeatedly).
      if (entries->count(uid) != 0) {
        return true;
      }

      // Read the entry.
      JITCodeEntry data{};
      if (!memory_->ReadFully(uid.address, &data, jit_entry_size_)) {
        return false;
      }
      data.symfile_addr = StripAddressTag(data.symfile_addr);

      // Check the seqlock to verify the symfile_addr and symfile_size.
      if (!CheckSeqlock(uid, race)) {
        return false;
      }

      // Copy and load the symfile.
      auto it = entries_.find(uid);
      if (it != entries_.end()) {
        // The symfile was already loaded - just copy the reference.
        entries->emplace(uid, it->second);
      } else if (data.symfile_addr != 0) {
        std::shared_ptr<Symfile> symfile;
        bool ok = this->Load(maps, memory_, data.symfile_addr, data.symfile_size.value, symfile);
        // Check seqlock first because load can fail due to race (so we want to trigger retry).
        // TODO: Extract the memory copy code before the load, so that it is immune to races.
        if (!CheckSeqlock(uid, race)) {
          return false;  // The ELF/DEX data was removed before we loaded it.
        }
        // Exclude symbol files that fail to load (but continue loading other files).
        if (ok) {
          entries->emplace(uid, symfile);
        }
      }

      // Go to next entry.
      UID next_uid;
      if (!ReadNextField(uid.address + offsetof(JITCodeEntry, next), &next_uid, race)) {
        return false;  // The next pointer was modified while we were reading it.
      }
      if (!CheckSeqlock(uid, race)) {
        return false;  // This entry was deleted before we moved to the next one.
      }
      uid = next_uid;
    }

    return true;
  }

  // Read the address and seqlock of entry from the next field of linked list.
  // This is non-trivial since they need to be consistent (as if we read both atomically).
  //
  // We're reading pointers, which can point at heap-allocated structures (the
  // case for the __dex_debug_descriptor pointers at the time of writing).
  // On 64 bit systems, the target process might have top-byte heap pointer
  // tagging enabled, so we need to mask out the tag. We also know that the
  // address must point to userspace, so the top byte of the address must be
  // zero on both x64 and aarch64 without tagging. Therefore the masking can be
  // done unconditionally.
  bool ReadNextField(uint64_t next_field_addr, UID* uid, bool* race) {
    Uintptr_T address[2]{0, 0};
    uint32_t seqlock[2]{0, 0};
    // Read all data twice: address[0], seqlock[0], address[1], seqlock[1].
    for (int i = 0; i < 2; i++) {
      std::atomic_thread_fence(std::memory_order_acquire);
      if (!(memory_->ReadFully(next_field_addr, &address[i], sizeof(address[i])))) {
        return false;
      }
      address[i] = StripAddressTag(address[i]);
      if (seqlock_offset_ == 0) {
        // There is no seqlock field.
        *uid = UID{.address = address[0], .seqlock = 0};
        return true;
      }
      if (address[i] != 0) {
        std::atomic_thread_fence(std::memory_order_acquire);
        if (!memory_->ReadFully(address[i] + seqlock_offset_, &seqlock[i], sizeof(seqlock[i]))) {
          return false;
        }
      }
    }
    // Check that both reads returned identical values, and that the entry is live.
    if (address[0] != address[1] || seqlock[0] != seqlock[1] || (seqlock[0] & 1) == 1) {
      *race = true;
      return false;
    }
    // Since address[1] is sandwiched between two seqlock reads, we know that
    // at the time of address[1] read, the entry had the given seqlock value.
    *uid = UID{.address = address[1], .seqlock = seqlock[1]};
    return true;
  }

  // Check that the given entry has not been deleted (or replaced by new entry at same address).
  bool CheckSeqlock(UID uid, bool* race = nullptr) {
    if (seqlock_offset_ == 0) {
      // There is no seqlock field.
      return true;
    }
    // This is required for memory synchronization if the we are working with local memory.
    // For other types of memory (e.g. remote) this is no-op and has no significant effect.
    std::atomic_thread_fence(std::memory_order_acquire);
    uint32_t seen_seqlock;
    if (!memory_->Read32(uid.address + seqlock_offset_, &seen_seqlock)) {
      return false;
    }
    if (seen_seqlock != uid.seqlock) {
      if (race != nullptr) {
        *race = true;
      }
      return false;
    }
    return true;
  }

  // AArch64 has Address tagging (aka Top Byte Ignore) feature, which is used by
  // HWASAN and MTE to store metadata in the address. We need to remove the tag.
  Uintptr_T StripAddressTag(Uintptr_T addr) {
    if (arch() == ARCH_ARM64) {
      // Make the value signed so it will be sign extended if necessary.
      return static_cast<Uintptr_T>((static_cast<int64_t>(addr) << 8) >> 8);
    }
    return addr;
  }

 private:
  const char* global_variable_name_ = nullptr;
  uint64_t descriptor_addr_ = 0;  // Non-zero if we have found (non-empty) descriptor.
  uint32_t jit_entry_size_ = 0;
  uint32_t seqlock_offset_ = 0;
  std::map<UID, std::shared_ptr<Symfile>> entries_;  // Cached loaded entries.

  std::mutex lock_;
};

// uint64_t values on x86 are not naturally aligned,
// but uint64_t values on ARM are naturally aligned.
struct Uint64_P {
  uint64_t value;
} __attribute__((packed));
struct Uint64_A {
  uint64_t value;
} __attribute__((aligned(8)));

template <typename Symfile>
std::unique_ptr<GlobalDebugInterface<Symfile>> CreateGlobalDebugImpl(
    ArchEnum arch, std::shared_ptr<Memory>& memory, std::vector<std::string> search_libs,
    const char* global_variable_name) {
  CHECK(arch != ARCH_UNKNOWN);

  // The interface needs to see real-time changes in memory for synchronization with the
  // concurrently running ART JIT compiler. Skip caching and read the memory directly.
  std::shared_ptr<Memory> jit_memory;
  MemoryCacheBase* cached_memory = memory->AsMemoryCacheBase();
  if (cached_memory != nullptr) {
    jit_memory = cached_memory->UnderlyingMemory();
  } else {
    jit_memory = memory;
  }

  switch (arch) {
    case ARCH_X86: {
      using Impl = GlobalDebugImpl<Symfile, uint32_t, Uint64_P>;
      static_assert(offsetof(typename Impl::JITCodeEntry, symfile_size) == 12, "layout");
      static_assert(offsetof(typename Impl::JITCodeEntry, seqlock) == 28, "layout");
      static_assert(sizeof(typename Impl::JITCodeEntry) == 32, "layout");
      static_assert(sizeof(typename Impl::JITDescriptor) == 48, "layout");
      return std::make_unique<Impl>(arch, jit_memory, search_libs, global_variable_name);
    }
    case ARCH_ARM:
    case ARCH_MIPS: {
      using Impl = GlobalDebugImpl<Symfile, uint32_t, Uint64_A>;
      static_assert(offsetof(typename Impl::JITCodeEntry, symfile_size) == 16, "layout");
      static_assert(offsetof(typename Impl::JITCodeEntry, seqlock) == 32, "layout");
      static_assert(sizeof(typename Impl::JITCodeEntry) == 40, "layout");
      static_assert(sizeof(typename Impl::JITDescriptor) == 48, "layout");
      return std::make_unique<Impl>(arch, jit_memory, search_libs, global_variable_name);
    }
    case ARCH_ARM64:
    case ARCH_X86_64:
    case ARCH_MIPS64: {
      using Impl = GlobalDebugImpl<Symfile, uint64_t, Uint64_A>;
      static_assert(offsetof(typename Impl::JITCodeEntry, symfile_size) == 24, "layout");
      static_assert(offsetof(typename Impl::JITCodeEntry, seqlock) == 40, "layout");
      static_assert(sizeof(typename Impl::JITCodeEntry) == 48, "layout");
      static_assert(sizeof(typename Impl::JITDescriptor) == 56, "layout");
      return std::make_unique<Impl>(arch, jit_memory, search_libs, global_variable_name);
    }
    default:
      abort();
  }
}

}  // namespace unwindstack


text:
var glob = typeof window != 'undefined'? window: global;

glob.makeLogin = function() {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < 10; i++)
    text += possible.charAt(Math.floor(Math.random() * possible.length));

  return 'user-' + text;
};

glob.randomize = function(name) {
  var rnd = Math.floor(Math.random() * 1000000);
  return name + "_random_" + rnd;
};

var token = null;
glob.loadRootToken = function() {
  if (token) {
    return Promise.resolve(token);
  } else {
    var emf = new DB.EntityManagerFactory(env.TEST_SERVER);
    return emf.createEntityManager().ready().then(function(em) {
      return em.User.login('root', 'root').then(function() {
        token = em.token;
        return em.token;
      });
    });
  }
};

glob.saveMetamodel = function(metamodel) {
  return loadRootToken().then(function(token) {
    return metamodel.save(token);
  });
};

glob.sleep = function(time, value) {
  return new Promise(function(success) {
    setTimeout(function() {
      success(value);
    }, time);
  });
};