text:
@implementation AudioManager

static AudioManager* shareInstace = nil;
+ (instancetype)getInstance
{
    static dispatch_once_t instance;
    dispatch_once(&instance, ^{
        shareInstace = [[self alloc] init];
    });
    return shareInstace;
}

static void OnInputBufferCallback(void *inUserData,
                             AudioQueueRef inAQ,
                             AudioQueueBufferRef inBuffer,
                             const AudioTimeStamp *inStartTime,
                             UInt32 inNumPackets,
                             const AudioStreamPacketDescription *inPacketDesc)
{
    AudioManager * manager = (__bridge AudioManager*)inUserData;
    if (manager == NULL || manager->recording == NO)
    {
        return;
    }
    //编码
    int nRet = faacEncEncode(manager->audioEncoder, inBuffer->mAudioData, manager->inputSamples, manager->outputBuffer, manager->maxOutputBytes);

    if (nRet > 0)
    {
        [[rtmpManager getInstance] send_rtmp_audio:manager->outputBuffer andLength:nRet];
//        fwrite(manager->outputBuffer, 1, nRet, manager->fp);

    }
    AudioQueueEnqueueBuffer(manager->queueRef, inBuffer, 0, NULL);
}

static void OnIsRunningCallback(void *inUserData, AudioQueueRef inAQ, AudioQueuePropertyID inID)
{
    AudioManager * manager = (__bridge AudioManager*)inUserData;
    if (manager == NULL)
    {
        return;
    }

    UInt32 size = sizeof(manager->running);
    AudioQueueGetProperty(manager->queueRef, kAudioQueueProperty_IsRunning, &manager->running, &size);

    if (!manager->running)
    {
        [manager stopRecording];
    }
}

- (void)initRecording
{
    [self openEncoder];

    [self initForFilePath];

    AVAudioSession * audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error: nil];
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
                             sizeof (audioRouteOverride),
                             &audioRouteOverride);
    [audioSession setActive:YES error: nil];

    basicDescription.mFormatID = kAudioFormatLinearPCM;
    basicDescription.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
    basicDescription.mSampleRate = SAMPLERATE;
    basicDescription.mChannelsPerFrame = NUMBERCHANNEL;
    basicDescription.mBitsPerChannel = 16;
    basicDescription.mBytesPerPacket = self->basicDescription.mBytesPerFrame = (basicDescription.mBitsPerChannel / 8) * basicDescription.mChannelsPerFrame;
    basicDescription.mFramesPerPacket = 1;

    OSStatus status = AudioQueueNewInput(&basicDescription, OnInputBufferCallback, (__bridge void*)self, CFRunLoopGetMain(), kCFRunLoopDefaultMode, 0, &queueRef);
    if (status)
    {
        NSLog(@"Could not establish new queue");
        return;
    }

    AudioQueueSetParameter(queueRef, kAudioQueueParam_Volume, 1.0f);
    for(int i = 0; i != kNumberOfRecordBuffers; ++i)
    {
        AudioQueueAllocateBuffer(queueRef, (UInt32)maxInputBytes, &(buffer[i]));
        AudioQueueEnqueueBuffer(queueRef, buffer[i], 0, NULL);
    }

     //AudioQueueAddPropertyListener(self->queueRef, kAudioQueueProperty_IsRunning, OnIsRunningCallback, (__bridge void*)self);

    UInt32 trueValue = true;
    AudioQueueSetProperty(queueRef, kAudioQueueProperty_EnableLevelMetering, &trueValue, sizeof(trueValue));

}

- (void)startRecording
{
    OSStatus rst = AudioQueueStart(queueRef, NULL);

    if (rst != 0)
    {
        AudioQueueStart(queueRef, NULL);
    }
    recording = YES;
}

- (void)pauseRecording
{
    AudioQueuePause(queueRef);
    recording = NO;
}

- (void)stopRecording
{
    AudioQueueStop(queueRef, true);
    AudioQueueDispose(queueRef, false);
    queueRef = NULL;

    [self stopEncoder];
}

- (void)openEncoder
{
    audioEncoder = faacEncOpen(SAMPLERATE, NUMBERCHANNEL, &inputSamples, &maxOutputBytes);
    maxInputBytes = inputSamples*16/8;

    faacEncConfigurationPtr ptr = faacEncGetCurrentConfiguration(audioEncoder);

    // 设置配置参数
    ptr->inputFormat = FAAC_INPUT_16BIT;
    ptr->outputFormat = 1; ////输出是否包含ADTS头,默认1,如果要写文件本地播放则需要加ADTS头
    ptr->useTns = true; //时域噪音控制,大概就是消爆音
    ptr->useLfe = false;
    ptr->aacObjectType = LOW;//LC编码
    ptr->shortctl = SHORTCTL_NORMAL;
    ptr->quantqual = 50;
    ptr->bandWidth = 0;//频宽
    ptr->bitRate = 0;

    faacEncSetConfiguration(audioEncoder, ptr);

    printf("\ninputSamples:%ld maxInputBytes:%ld maxOutputBytes:%ld\n", inputSamples, maxInputBytes,maxOutputBytes);
    unsigned char *tmp;
    unsigned long spec_len;
    faacEncGetDecoderSpecificInfo(audioEncoder, &tmp, &spec_len);
    [[rtmpManager getInstance] send_rtmp_audio_spec:tmp andLength:(UInt32)spec_len];
    //如果现在释放,可能还没发送就释放了,导致发送的数据不对,因为发送是异步队列发送的。
    //如果free的时候同时设置为NULL,那么再引用数据的时候就会报错也能定位到问题了。
    //所以以后free的时候也要设置为NULL。
    //    free(tmp);
    //    tmp = nil;

    outputBuffer = malloc(maxOutputBytes);
}

- (void)stopEncoder
{
    faacEncClose(audioEncoder);
}

- (void)initForFilePath
{
    char *path = [self GetFilePathByfileName:"IOSCamDemo.aac"];
    NSLog(@"%s",path);
    fp = fopen(path,"wb");
}

- (char*)GetFilePathByfileName:(char*)filename
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *strName = [NSString stringWithFormat:@"%s",filename];

    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:strName];

    NSUInteger len = [writablePath length];

    char *filepath = (char*)malloc(sizeof(char) * (len + 1));

    [writablePath getCString:filepath maxLength:len + 1 encoding:[NSString defaultCStringEncoding]];

    return filepath;
}

@end


text:
.class final synthetic Lcom/android/systemui/doze/-$Lambda$5D-qktfRQdiZuJWCYYe1CwTdSjk$1;
.super Ljava/lang/Object;

# interfaces
.implements Landroid/app/AlarmManager$OnAlarmListener;

# instance fields
.field private final synthetic -$f0:Ljava/lang/Object;

# direct methods
.method private final synthetic $m$0()V
    .locals 1

    iget-object v0, p0, Lcom/android/systemui/doze/-$Lambda$5D-qktfRQdiZuJWCYYe1CwTdSjk$1;->-$f0:Ljava/lang/Object;

    check-cast v0, Lcom/android/systemui/doze/DozeUi;

    invoke-virtual {v0}, Lcom/android/systemui/doze/DozeUi;->-com_android_systemui_doze_DozeUi-mthref-0()V

    return-void
.end method

.method public synthetic constructor <init>(Ljava/lang/Object;)V
    .locals 0

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    iput-object p1, p0, Lcom/android/systemui/doze/-$Lambda$5D-qktfRQdiZuJWCYYe1CwTdSjk$1;->-$f0:Ljava/lang/Object;

    return-void
.end method

# virtual methods
.method public final onAlarm()V
    .locals 0

    invoke-direct {p0}, Lcom/android/systemui/doze/-$Lambda$5D-qktfRQdiZuJWCYYe1CwTdSjk$1;->$m$0()V

    return-void
.end method

redpajama_set_name: RedPajamaGithub


text:
module StreamsHelper
end


text:
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.singlejar;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.devtools.build.singlejar.ZipCombiner.OutputMode;
import com.google.devtools.build.singlejar.ZipEntryFilter.CustomMergeStrategy;
import com.google.devtools.build.zip.ExtraData;
import com.google.devtools.build.zip.ZipFileEntry;
import com.google.devtools.build.zip.ZipReader;
import com.google.devtools.build.zip.ZipUtil;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link ZipCombiner}.
 */
@RunWith(JUnit4.class)
public class ZipCombinerTest {
  @Rule public TemporaryFolder tmp = new TemporaryFolder();
  @Rule public ExpectedException thrown = ExpectedException.none();

  private File sampleZip() throws IOException {
    ZipFactory factory = new ZipFactory();
    factory.addFile("hello.txt", "Hello World!");
    return writeInputStreamToFile(factory.toInputStream());
  }

  private File sampleZip2() throws IOException {
    ZipFactory factory = new ZipFactory();
    factory.addFile("hello2.txt", "Hello World 2!");
    return writeInputStreamToFile(factory.toInputStream());
  }

  private File sampleZipWithTwoEntries() throws IOException {
    ZipFactory factory = new ZipFactory();
    factory.addFile("hello.txt", "Hello World!");
    factory.addFile("hello2.txt", "Hello World 2!");
    return writeInputStreamToFile(factory.toInputStream());
  }

  private File sampleZipWithOneUncompressedEntry() throws IOException {
    ZipFactory factory = new ZipFactory();
    factory.addFile("hello.txt", "Hello World!", false);
    return writeInputStreamToFile(factory.toInputStream());
  }

  private File sampleZipWithTwoUncompressedEntries() throws IOException {
    ZipFactory factory = new ZipFactory();
    factory.addFile("hello.txt", "Hello World!", false);
    factory.addFile("hello2.txt", "Hello World 2!", false);
    return writeInputStreamToFile(factory.toInputStream());
  }

  private File writeInputStreamToFile(InputStream in) throws IOException {
    File out = tmp.newFile();
    Files.copy(in, out.toPath(), StandardCopyOption.REPLACE_EXISTING);
    return out;
  }

  private void assertEntry(ZipInputStream zipInput, String filename, long time, byte[] content)
      throws IOException {
    ZipEntry zipEntry = zipInput.getNextEntry();
    assertThat(zipEntry).isNotNull();
    assertThat(zipEntry.getName()).isEqualTo(filename);
    assertThat(zipEntry.getTime()).isEqualTo(time);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int bytesCopied;
    while ((bytesCopied = zipInput.read(buffer)) != -1) {
      out.write(buffer, 0, bytesCopied);
    }
    assertThat(out.toByteArray()).isEqualTo(content);
  }

  private void assertEntry(ZipInputStream zipInput, String filename, byte[] content)
      throws IOException {
    assertEntry(zipInput, filename, ZipUtil.DOS_EPOCH, content);
  }

  private void assertEntry(ZipInputStream zipInput, String filename, String content)
      throws IOException {
    assertEntry(zipInput, filename, content.getBytes(ISO_8859_1));
  }

  private void assertEntry(ZipInputStream zipInput, String filename, Date date, String content)
      throws IOException {
    assertEntry(zipInput, filename, date.getTime(), content.getBytes(ISO_8859_1));
  }

  @Test
  public void testCompressedDontCare() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addZip(sampleZip());
    }
    FakeZipFile expectedResult = new FakeZipFile().addEntry("hello.txt", "Hello World!", true);
    expectedResult.assertSame(out.toByteArray());
  }

  @Test
  public void testCompressedForceDeflate() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(OutputMode.FORCE_DEFLATE, out)) {
      zipCombiner.addZip(sampleZip());
    }
    FakeZipFile expectedResult = new FakeZipFile().addEntry("hello.txt", "Hello World!", true);
    expectedResult.assertSame(out.toByteArray());
  }

  @Test
  public void testCompressedForceStored() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(OutputMode.FORCE_STORED, out)) {
      zipCombiner.addZip(sampleZip());
    }
    FakeZipFile expectedResult = new FakeZipFile().addEntry("hello.txt", "Hello World!", false);
    expectedResult.assertSame(out.toByteArray());
  }

  @Test
  public void testUncompressedDontCare() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addZip(sampleZipWithOneUncompressedEntry());
    }
    FakeZipFile expectedResult = new FakeZipFile().addEntry("hello.txt", "Hello World!", false);
    expectedResult.assertSame(out.toByteArray());
  }

  @Test
  public void testUncompressedForceDeflate() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(OutputMode.FORCE_DEFLATE, out)) {
      zipCombiner.addZip(sampleZipWithOneUncompressedEntry());
    }
    FakeZipFile expectedResult = new FakeZipFile().addEntry("hello.txt", "Hello World!", true);
    expectedResult.assertSame(out.toByteArray());
  }

  @Test
  public void testUncompressedForceStored() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(OutputMode.FORCE_STORED, out)) {
      zipCombiner.addZip(sampleZipWithOneUncompressedEntry());
    }
    FakeZipFile expectedResult = new FakeZipFile().addEntry("hello.txt", "Hello World!", false);
    expectedResult.assertSame(out.toByteArray());
  }

  @Test
  public void testCopyTwoEntries() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testCopyTwoUncompressedEntries() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testCombine() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addZip(sampleZip());
      zipCombiner.addZip(sampleZip2());
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testDuplicateEntry() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addZip(sampleZip());
      zipCombiner.addZip(sampleZip());
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testBadZipFileNoEntry() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      thrown.expect(ZipException.class);
      thrown.expectMessage("It does not contain an end of central directory record.");
      zipCombiner.addZip(writeInputStreamToFile(new ByteArrayInputStream(new byte[] {1, 2, 3, 4})));
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertThat(zipInput.getNextEntry()).isNull();
  }

  private InputStream asStream(String content) {
    return new ByteArrayInputStream(content.getBytes(UTF_8));
  }

  @Test
  public void testAddFile() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addFile("hello.txt", ZipCombiner.DOS_EPOCH, asStream("Hello World!"));
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testAddFileAndDuplicateZipEntry() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      zipCombiner.addFile("hello.txt", ZipCombiner.DOS_EPOCH, asStream("Hello World!"));
      zipCombiner.addZip(sampleZip());
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  static final class MergeStrategyPlaceHolder implements CustomMergeStrategy {

    @Override
    public void finish(OutputStream out) {
      throw new UnsupportedOperationException();
    }

    @Override
    public void merge(InputStream in, OutputStream out) {
      throw new UnsupportedOperationException();
    }
  }

  private static final CustomMergeStrategy COPY_PLACEHOLDER = new MergeStrategyPlaceHolder();
  private static final CustomMergeStrategy SKIP_PLACEHOLDER = new MergeStrategyPlaceHolder();

  /**
   * A mock implementation that either uses the specified behavior or calls
   * through to copy.
   */
  class MockZipEntryFilter implements ZipEntryFilter {

    private Date date = ZipCombiner.DOS_EPOCH;
    private final List<String> calls = new ArrayList<>();
    // File name to merge strategy map.
    private final Map<String, CustomMergeStrategy> behavior =
        new HashMap<>();
    private final ListMultimap<String, String> renameMap = ArrayListMultimap.create();

    @Override
    public void accept(String filename, StrategyCallback callback) throws IOException {
      calls.add(filename);
      CustomMergeStrategy strategy = behavior.get(filename);
      if (strategy == null) {
        callback.copy(null);
      } else if (strategy == COPY_PLACEHOLDER) {
        List<String> names = renameMap.get(filename);
        if (names != null && !names.isEmpty()) {
          // rename to the next name in list of replacement names.
          String newName = names.get(0);
          callback.rename(newName, null);
          // Unless this is the last replacment names, we pop the used name.
          // The lastreplacement name applies any additional entries.
          if (names.size() > 1) {
            names.remove(0);
          }
        } else {
          callback.copy(null);
        }
      } else if (strategy == SKIP_PLACEHOLDER) {
        callback.skip();
      } else {
        callback.customMerge(date, strategy);
      }
    }
  }

  @Test
  public void testCopyCallsFilter() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZip());
    }
    assertThat(mockFilter.calls).containsExactly("hello.txt");
  }

  @Test
  public void testDuplicateEntryCallsFilterOnce() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZip());
      zipCombiner.addZip(sampleZip());
    }
    assertThat(mockFilter.calls).containsExactly("hello.txt");
  }

  @Test
  public void testMergeStrategy() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", new ConcatenateStrategy());
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZip());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls).containsExactly("hello.txt", "hello2.txt").inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertEntry(zipInput, "hello.txt", "Hello World!\nHello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testMergeStrategyWithUncompressedFiles() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", new ConcatenateStrategy());
    mockFilter.behavior.put("hello2.txt", SKIP_PLACEHOLDER);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
    }
    assertThat(mockFilter.calls).isEqualTo(Arrays.asList("hello.txt", "hello2.txt"));
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!\nHello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testMergeStrategyWithSlowCopy() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", new SlowConcatenateStrategy());
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZip());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls).isEqualTo(Arrays.asList("hello.txt", "hello2.txt"));
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertEntry(zipInput, "hello.txt", "Hello World!Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testMergeStrategyWithUncompressedFilesAndSlowCopy() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", new SlowConcatenateStrategy());
    mockFilter.behavior.put("hello2.txt", SKIP_PLACEHOLDER);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
    }
    assertThat(mockFilter.calls).containsExactly("hello.txt", "hello2.txt").inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  private File specialZipWithMinusOne() throws IOException {
    ZipFactory factory = new ZipFactory();
    factory.addFile("hello.txt", new byte[] {-1});
    return writeInputStreamToFile(factory.toInputStream());
  }

  @Test
  public void testMergeStrategyWithSlowCopyAndNegativeBytes() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", new SlowConcatenateStrategy());
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(specialZipWithMinusOne());
    }
    assertThat(mockFilter.calls).containsExactly("hello.txt");
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", new byte[] { -1 });
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testCopyDateHandling() throws IOException {
    final Date date = new GregorianCalendar(2009, 8, 2, 0, 0, 0).getTime();
    ZipEntryFilter mockFilter =
        new ZipEntryFilter() {
          @Override
          public void accept(String filename, StrategyCallback callback) throws IOException {
            assertThat(filename).isEqualTo("hello.txt");
            callback.copy(date);
          }
        };
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZip());
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", date, "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testMergeDateHandling() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", new ConcatenateStrategy());
    mockFilter.date = new GregorianCalendar(2009, 8, 2, 0, 0, 0).getTime();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZip());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls).containsExactly("hello.txt", "hello2.txt").inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello2.txt", ZipCombiner.DOS_EPOCH, "Hello World 2!");
    assertEntry(zipInput, "hello.txt", mockFilter.date, "Hello World!\nHello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  @Test
  public void testDuplicateCallThrowsException() throws IOException {
    ZipEntryFilter badFilter = new ZipEntryFilter() {
      @Override
      public void accept(String filename, StrategyCallback callback) throws IOException {
        // Duplicate callback call.
        callback.skip();
        callback.copy(null);
      }
    };
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(badFilter, out)) {
      assertThrows(IllegalStateException.class, () -> zipCombiner.addZip(sampleZip()));
    }
  }

  @Test
  public void testNoCallThrowsException() throws IOException {
    ZipEntryFilter badFilter = new ZipEntryFilter() {
      @Override
      public void accept(String filename, StrategyCallback callback) {
        // No callback call.
      }
    };
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(badFilter, out)) {
      assertThrows(IllegalStateException.class, () -> zipCombiner.addZip(sampleZip()));
    }
  }

  // This test verifies that if an entry A is renamed as A (identy mapping),
  // then subsequent entries named A are still subject to filtering.
  // Note: this is different from a copy, where subsequent entries are skipped.
  @Test
  public void testRenameIdentityMapping() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", COPY_PLACEHOLDER);
    mockFilter.behavior.put("hello2.txt", COPY_PLACEHOLDER);
    mockFilter.renameMap.put("hello.txt", "hello.txt");   // identity rename, not copy
    mockFilter.renameMap.put("hello2.txt", "hello2.txt"); // identity rename, not copy
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls)
        .containsExactly("hello.txt", "hello2.txt", "hello.txt", "hello2.txt")
        .inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  // This test verifies that multiple entries with the same name can be
  // renamed to unique names.
  @Test
  public void testRenameNoConflictMapping() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", COPY_PLACEHOLDER);
    mockFilter.behavior.put("hello2.txt", COPY_PLACEHOLDER);
    mockFilter.renameMap.putAll("hello.txt", Arrays.asList("hello1.txt", "hello2.txt"));
    mockFilter.renameMap.putAll("hello2.txt", Arrays.asList("world1.txt", "world2.txt"));
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls)
        .containsExactly("hello.txt", "hello2.txt", "hello.txt", "hello2.txt")
        .inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello1.txt", "Hello World!");
    assertEntry(zipInput, "world1.txt", "Hello World 2!");
    assertEntry(zipInput, "hello2.txt", "Hello World!");
    assertEntry(zipInput, "world2.txt", "Hello World 2!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  // This tests verifies that an attempt to rename an entry to a
  // name already written, results in the entry being skipped, after
  // calling the filter.
  @Test
  public void testRenameSkipUsedName() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", COPY_PLACEHOLDER);
    mockFilter.behavior.put("hello2.txt", COPY_PLACEHOLDER);
    mockFilter.renameMap.putAll("hello.txt",
        Arrays.asList("hello1.txt", "hello2.txt", "hello3.txt"));
    mockFilter.renameMap.put("hello2.txt", "hello2.txt");
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls)
        .containsExactly(
            "hello.txt", "hello2.txt", "hello.txt", "hello2.txt", "hello.txt", "hello2.txt")
        .inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello1.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertEntry(zipInput, "hello3.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  // This tests verifies that if an entry has been copied, then
  // further entries of the same name are skipped (filter not invoked),
  // and entries renamed to the same name are skipped (after calling filter).
  @Test
  public void testRenameAndCopy() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", COPY_PLACEHOLDER);
    mockFilter.behavior.put("hello2.txt", COPY_PLACEHOLDER);
    mockFilter.renameMap.putAll("hello.txt",
        Arrays.asList("hello1.txt", "hello2.txt", "hello3.txt"));
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls)
        .containsExactly("hello.txt", "hello2.txt", "hello.txt", "hello.txt")
        .inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello1.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertEntry(zipInput, "hello3.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  // This tests verifies that if an entry has been skipped, then
  // further entries of the same name are skipped (filter not invoked),
  // and entries renamed to the same name are skipped (after calling filter).
  @Test
  public void testRenameAndSkip() throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", COPY_PLACEHOLDER);
    mockFilter.behavior.put("hello2.txt", SKIP_PLACEHOLDER);
    mockFilter.renameMap.putAll("hello.txt",
        Arrays.asList("hello1.txt", "hello2.txt", "hello3.txt"));
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
      zipCombiner.addZip(sampleZipWithTwoEntries());
    }
    assertThat(mockFilter.calls)
        .containsExactly("hello.txt", "hello2.txt", "hello.txt", "hello.txt")
        .inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello1.txt", "Hello World!");
    assertEntry(zipInput, "hello3.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  // This test verifies that renaming works when input and output
  // disagree on compression method. This is the simple case, where
  // content is read and rewritten, and no header repair is needed.
  @Test
  public void testRenameWithUncompressedFiles () throws IOException {
    MockZipEntryFilter mockFilter = new MockZipEntryFilter();
    mockFilter.behavior.put("hello.txt", COPY_PLACEHOLDER);
    mockFilter.behavior.put("hello2.txt", COPY_PLACEHOLDER);
    mockFilter.renameMap.putAll("hello.txt",
        Arrays.asList("hello1.txt", "hello2.txt", "hello3.txt"));
    mockFilter.renameMap.put("hello2.txt", "hello2.txt");
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(mockFilter, out)) {
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
      zipCombiner.addZip(sampleZipWithTwoUncompressedEntries());
    }
    assertThat(mockFilter.calls)
        .containsExactly(
            "hello.txt", "hello2.txt", "hello.txt", "hello2.txt", "hello.txt", "hello2.txt")
        .inOrder();
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    assertEntry(zipInput, "hello1.txt", "Hello World!");
    assertEntry(zipInput, "hello2.txt", "Hello World 2!");
    assertEntry(zipInput, "hello3.txt", "Hello World!");
    assertThat(zipInput.getNextEntry()).isNull();
  }

  // The next two tests check that ZipCombiner can handle a ZIP with an data
  // descriptor marker in the compressed data, i.e. that it does not scan for
  // the data descriptor marker. It's unfortunately a bit tricky to create such
  // a ZIP.
  private static final int LOCAL_FILE_HEADER_MARKER = 0x04034b50;

  // Create a ZIP with a partial entry.
  private InputStream zipWithPartialEntry() {
    ByteBuffer out = ByteBuffer.wrap(new byte[32]).order(ByteOrder.LITTLE_ENDIAN);
    out.clear();
    // file header
    out.putInt(LOCAL_FILE_HEADER_MARKER);  // file header signature
    out.putShort((short) 6); // version to extract
    out.putShort((short) 0); // general purpose bit flag
    out.putShort((short) ZipOutputStream.STORED); // compression method
    out.putShort((short) 0); // mtime (00:00:00)
    out.putShort((short) 0x21); // mdate (1.1.1980)
    out.putInt(0); // crc32
    out.putInt(10); // compressed size
    out.putInt(10); // uncompressed size
    out.putShort((short) 1); // file name length
    out.putShort((short) 0); // extra field length
    out.put((byte) 'a'); // file name

    // file contents
    out.put((byte) 0x01);
    // Unexpected end of file.

    return new ByteArrayInputStream(out.array());
  }

  @Test
  public void testBadZipFilePartialEntry() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner = new ZipCombiner(out)) {
      thrown.expect(ZipException.class);
      thrown.expectMessage("It does not contain an end of central directory record.");
      zipCombiner.addZip(writeInputStreamToFile(zipWithPartialEntry()));
    }
  }

  @Test
  public void testZipCombinerAgainstJavaUtil() throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (JarOutputStream jarOut = new JarOutputStream(out)) {
      ZipEntry entry;
      entry = new ZipEntry("META-INF/");
      entry.setTime(ZipCombiner.DOS_EPOCH.getTime());
      entry.setMethod(JarOutputStream.STORED);
      entry.setSize(0);
      entry.setCompressedSize(0);
      entry.setCrc(0);
      jarOut.putNextEntry(entry);
      entry = new ZipEntry("META-INF/MANIFEST.MF");
      entry.setTime(ZipCombiner.DOS_EPOCH.getTime());
      entry.setMethod(JarOutputStream.DEFLATED);
      jarOut.putNextEntry(entry);
      jarOut.write(new byte[] {1, 2, 3, 4});
    }
    File javaFile = writeInputStreamToFile(new ByteArrayInputStream(out.toByteArray()));
    out.reset();

    try (ZipCombiner zipcombiner = new ZipCombiner(out)) {
      zipcombiner.addDirectory("META-INF/", ZipCombiner.DOS_EPOCH,
          new ExtraData[] {new ExtraData((short) 0xCAFE, new byte[0])});
      zipcombiner.addFile("META-INF/MANIFEST.MF", ZipCombiner.DOS_EPOCH,
          new ByteArrayInputStream(new byte[] {1, 2, 3, 4}));
    }
    File zipCombinerFile = writeInputStreamToFile(new ByteArrayInputStream(out.toByteArray()));
    byte[] zipCombinerRaw = out.toByteArray();

    new ZipTester(zipCombinerRaw).validate();
    assertZipFilesEquivalent(zipCombinerFile, javaFile);
  }

  void assertZipFilesEquivalent(File a, File b) throws IOException {
    try (ZipReader x = new ZipReader(a);
        ZipReader y = new ZipReader(b)) {
      Collection<ZipFileEntry> xEntries = x.entries();
      Collection<ZipFileEntry> yEntries = y.entries();
      assertThat(xEntries).hasSize(yEntries.size());
      Iterator<ZipFileEntry> xIter = xEntries.iterator();
      Iterator<ZipFileEntry> yIter = yEntries.iterator();
      for (int i = 0; i < xEntries.size(); i++) {
        assertZipEntryEquivalent(xIter.next(), yIter.next());
      }
    }
  }

  void assertZipEntryEquivalent(ZipFileEntry x, ZipFileEntry y) {
    assertThat(x.getComment()).isEqualTo(y.getComment());
    assertThat(x.getCompressedSize()).isEqualTo(y.getCompressedSize());
    assertThat(x.getCrc()).isEqualTo(y.getCrc());
    assertThat(x.getExternalAttributes()).isEqualTo(y.getExternalAttributes());
    // The JDK adds different extra data to zip files on different platforms, so we don't compare
    // the extra data.
    assertThat(x.getInternalAttributes()).isEqualTo(y.getInternalAttributes());
    assertThat(x.getMethod()).isEqualTo(y.getMethod());
    assertThat(x.getName()).isEqualTo(y.getName());
    assertThat(x.getSize()).isEqualTo(y.getSize());
    assertThat(x.getTime()).isEqualTo(y.getTime());
    assertThat(x.getVersion()).isEqualTo(y.getVersion());
    assertThat(x.getVersionNeeded()).isEqualTo(y.getVersionNeeded());
    // Allow general purpose bit 3 (data descriptor) used in jdk7 to differ.
    // Allow general purpose bit 11 (UTF-8 encoding) used in jdk7 to differ.
    assertThat(x.getFlags() | (1 << 3) | (1 << 11))
        .isEqualTo(y.getFlags() | (1 << 3) | (1 << 11));
  }

  /**
   * Ensures that the code that grows the central directory and the code that patches it is not
   * obviously broken.
   */
  @Test
  public void testLotsOfFiles() throws IOException {
    int fileCount = 100;
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ZipCombiner zipCombiner =
        new ZipCombiner(OutputMode.DONT_CARE, new CopyEntryFilter(), out)) {
      for (int i = 0; i < fileCount; i++) {
        zipCombiner.addFile("hello" + i, ZipCombiner.DOS_EPOCH, asStream("Hello " + i + "!"));
      }
    }
    ZipInputStream zipInput = new ZipInputStream(new ByteArrayInputStream(out.toByteArray()));
    for (int i = 0; i < fileCount; i++) {
      assertEntry(zipInput, "hello" + i, "Hello " + i + "!");
    }
    assertThat(zipInput.getNextEntry()).isNull();
    new ZipTester(out.toByteArray()).validate();
  }
}


text:
import Ember from 'ember';
import ValidationEngine from 'ghost/mixins/validation-engine';

var SetupThreeController = Ember.Controller.extend(ValidationEngine, {
    users: '',
    usersArray: Ember.computed('users', function () {
        return this.get('users').split('\n').filter(function (user) {
            return validator.isEmail(user);
        });
    }),
    numUsers: Ember.computed('usersArray', function () {
        return this.get('usersArray').length;
    }),
    buttonText: Ember.computed('numUsers', function () {
        var user = this.get('numUsers') === 1 ? 'user' : 'users';
        return this.get('numUsers') > 0 ?
            'Invite ' + this.get('numUsers') + ' ' + user : 'I\'ll do this later, take me to my blog!';
    }),
    buttonClass: Ember.computed('numUsers', function () {
        return this.get('numUsers') > 0 ? 'btn-green' : 'btn-minor';
    }),
    actions: {
        invite: function () {
            console.log('inviting', this.get('usersArray'));

            if (this.get('numUsers') === 0) {
                this.sendAction('signin');
            }

            // TODO: do invites
        },
        signin: function () {
            var self = this;

            this.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', {
                identification: self.get('email'),
                password: self.get('password')
            });
        }
    }
});

export default SetupThreeController;


text:
<?php

namespace common\components\assets;

use yii\web\AssetBundle;

/**
 * Main frontend application asset bundle.
 */
class Html5ForIEAsset extends AssetBundle
{
    public $depends = [
        'common\components\assets\RespondAsset',
        'common\components\assets\Html5ShivAsset',
    ];

}


text:
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <selinux/android.h>
#include <selinux/label.h>
#include <selinux/avc.h>
#include <private/android_filesystem_config.h>
#include "policy.h"
#include "callbacks.h"
#include "selinux_internal.h"

/*
 * XXX Where should this configuration file be located?
 * Needs to be accessible by zygote and installd when
 * setting credentials for app processes and setting permissions
 * on app data directories.
 */
static char const * const seapp_contexts_file[] = {
	"/data/security/current/seapp_contexts",
	"/seapp_contexts",
	0 };

static const struct selinux_opt seopts[] = {
	{ SELABEL_OPT_PATH, "/data/security/current/file_contexts" },
	{ SELABEL_OPT_PATH, "/file_contexts" },
	{ 0, NULL } };

static const struct selinux_opt seopt_backup[] = {
	{ SELABEL_OPT_PATH, "/data/security/current/file_contexts_backup" },
	{ SELABEL_OPT_PATH, "/file_contexts" },
	{ 0, NULL } };

static const char *const sepolicy_file[] = {
        "/data/security/current/sepolicy",
        "/sepolicy",
        0 };

enum levelFrom {
	LEVELFROM_NONE,
	LEVELFROM_APP,
	LEVELFROM_USER,
	LEVELFROM_ALL
};

#if DEBUG
static char const * const levelFromName[] = {
	"none",
	"app",
	"user",
	"all"
};
#endif

struct seapp_context {
	/* input selectors */
	char isSystemServer;
	char *user;
	size_t len;
	char prefix;
	char *seinfo;
	char *name;
	/* outputs */
	char *domain;
	char *type;
	char *level;
	char *sebool;
	enum levelFrom levelFrom;
};

static int seapp_context_cmp(const void *A, const void *B)
{
	const struct seapp_context *const *sp1 = A, *const *sp2 = B;
	const struct seapp_context *s1 = *sp1, *s2 = *sp2;

	/* Give precedence to isSystemServer=true. */
	if (s1->isSystemServer != s2->isSystemServer)
		return (s1->isSystemServer ? -1 : 1);

	/* Give precedence to a specified user= over an unspecified user=. */
	if (s1->user && !s2->user)
		return -1;
	if (!s1->user && s2->user)
		return 1;

	if (s1->user) {
		/* Give precedence to a fixed user= string over a prefix. */
		if (s1->prefix != s2->prefix)
			return (s2->prefix ? -1 : 1);

		/* Give precedence to a longer prefix over a shorter prefix. */
		if (s1->prefix && s1->len != s2->len)
			return (s1->len > s2->len) ? -1 : 1;
	}

	/* Give precedence to a specified seinfo= over an unspecified seinfo=. */
	if (s1->seinfo && !s2->seinfo)
		return -1;
	if (!s1->seinfo && s2->seinfo)
		return 1;

	/* Give precedence to a specified name= over an unspecified name=. */
	if (s1->name && !s2->name)
		return -1;
	if (!s1->name && s2->name)
		return 1;

        /* Give precedence to a specified sebool= over an unspecified sebool=. */
        if (s1->sebool && !s2->sebool)
                return -1;
        if (!s1->sebool && s2->sebool)
                return 1;

	/* Anything else has equal precedence. */
	return 0;
}

static struct seapp_context **seapp_contexts = NULL;
static int nspec = 0;

int selinux_android_seapp_context_reload(void)
{
	FILE *fp = NULL;
	char line_buf[BUFSIZ];
	char *token;
	unsigned lineno;
	struct seapp_context *cur;
	char *p, *name = NULL, *value = NULL, *saveptr;
	size_t len;
	int i = 0, n, ret;

	while ((fp==NULL) && seapp_contexts_file[i])
		fp = fopen(seapp_contexts_file[i++], "r");

	if (!fp) {
		selinux_log(SELINUX_ERROR, "%s:  could not open any seapp_contexts file", __FUNCTION__);
		return -1;
	}

	if (seapp_contexts) {
		for (n = 0; n < nspec; n++) {
			cur = seapp_contexts[n];
			free(cur->user);
			free(cur->seinfo);
			free(cur->name);
			free(cur->domain);
			free(cur->type);
			free(cur->level);
			free(cur->sebool);
		}
		free(seapp_contexts);
	}

	nspec = 0;
	while (fgets(line_buf, sizeof line_buf - 1, fp)) {
		p = line_buf;
		while (isspace(*p))
			p++;
		if (*p == '#' || *p == 0)
			continue;
		nspec++;
	}

	seapp_contexts = calloc(nspec, sizeof(struct seapp_context *));
	if (!seapp_contexts)
		goto oom;

	rewind(fp);
	nspec = 0;
	lineno = 1;
	while (fgets(line_buf, sizeof line_buf - 1, fp)) {
		len = strlen(line_buf);
		if (line_buf[len - 1] == '\n')
			line_buf[len - 1] = 0;
		p = line_buf;
		while (isspace(*p))
			p++;
		if (*p == '#' || *p == 0)
			continue;

		cur = calloc(1, sizeof(struct seapp_context));
		if (!cur)
			goto oom;

		token = strtok_r(p, " \t", &saveptr);
		if (!token)
			goto err;

		while (1) {
			name = token;
			value = strchr(name, '=');
			if (!value)
				goto err;
			*value++ = 0;

			if (!strcasecmp(name, "isSystemServer")) {
				if (!strcasecmp(value, "true"))
					cur->isSystemServer = 1;
				else if (!strcasecmp(value, "false"))
					cur->isSystemServer = 0;
				else {
					goto err;
				}
			} else if (!strcasecmp(name, "user")) {
				cur->user = strdup(value);
				if (!cur->user)
					goto oom;
				cur->len = strlen(cur->user);
				if (cur->user[cur->len-1] == '*')
					cur->prefix = 1;
			} else if (!strcasecmp(name, "seinfo")) {
				cur->seinfo = strdup(value);
				if (!cur->seinfo)
					goto oom;
			} else if (!strcasecmp(name, "name")) {
				cur->name = strdup(value);
				if (!cur->name)
					goto oom;
			} else if (!strcasecmp(name, "domain")) {
				cur->domain = strdup(value);
				if (!cur->domain)
					goto oom;
			} else if (!strcasecmp(name, "type")) {
				cur->type = strdup(value);
				if (!cur->type)
					goto oom;
			} else if (!strcasecmp(name, "levelFromUid")) {
				if (!strcasecmp(value, "true"))
					cur->levelFrom = LEVELFROM_APP;
				else if (!strcasecmp(value, "false"))
					cur->levelFrom = LEVELFROM_NONE;
				else {
					goto err;
				}
			} else if (!strcasecmp(name, "levelFrom")) {
				if (!strcasecmp(value, "none"))
					cur->levelFrom = LEVELFROM_NONE;
				else if (!strcasecmp(value, "app"))
					cur->levelFrom = LEVELFROM_APP;
				else if (!strcasecmp(value, "user"))
					cur->levelFrom = LEVELFROM_USER;
				else if (!strcasecmp(value, "all"))
					cur->levelFrom = LEVELFROM_ALL;
				else {
					goto err;
				}
			} else if (!strcasecmp(name, "level")) {
				cur->level = strdup(value);
				if (!cur->level)
					goto oom;
			} else if (!strcasecmp(name, "sebool")) {
				cur->sebool = strdup(value);
				if (!cur->sebool)
					goto oom;
			} else
				goto err;

			token = strtok_r(NULL, " \t", &saveptr);
			if (!token)
				break;
		}

		seapp_contexts[nspec] = cur;
		nspec++;
		lineno++;
	}

	qsort(seapp_contexts, nspec, sizeof(struct seapp_context *),
	      seapp_context_cmp);

#if DEBUG
	{
		int i;
		for (i = 0; i < nspec; i++) {
			cur = seapp_contexts[i];
			selinux_log(SELINUX_INFO, "%s:  isSystemServer=%s user=%s seinfo=%s name=%s sebool=%s -> domain=%s type=%s level=%s levelFrom=%s",
			__FUNCTION__,
			cur->isSystemServer ? "true" : "false", cur->user,
			cur->seinfo, cur->name, cur->sebool, cur->domain,
			cur->type, cur->level,
			levelFromName[cur->levelFrom]);
		}
	}
#endif

	ret = 0;

out:
	fclose(fp);
	return ret;

err:
	selinux_log(SELINUX_ERROR, "%s:  Error reading %s, line %u, name %s, value %s\n",
		    __FUNCTION__, seapp_contexts_file[i - 1], lineno, name, value);
	ret = -1;
	goto out;
oom:
	selinux_log(SELINUX_ERROR,
		    "%s:  Out of memory\n", __FUNCTION__);
	ret = -1;
	goto out;
}

static void seapp_context_init(void)
{
        selinux_android_seapp_context_reload();
}

static pthread_once_t once = PTHREAD_ONCE_INIT;

/*
 * Max id that can be mapped to category set uniquely
 * using the current scheme.
 */
#define CAT_MAPPING_MAX_ID (0x1<<16)

enum seapp_kind {
	SEAPP_TYPE,
	SEAPP_DOMAIN
};

static int seapp_context_lookup(enum seapp_kind kind,
				uid_t uid,
				int isSystemServer,
				const char *seinfo,
				const char *pkgname,
				context_t ctx)
{
	const char *username = NULL;
	struct seapp_context *cur = NULL;
	int i;
	size_t n;
	uid_t userid;
	uid_t appid;

	userid = uid / AID_USER;
	appid = uid % AID_USER;
	if (appid < AID_APP) {
		for (n = 0; n < android_id_count; n++) {
			if (android_ids[n].aid == appid) {
				username = android_ids[n].name;
				break;
			}
		}
		if (!username)
			goto err;
	} else if (appid < AID_ISOLATED_START) {
		username = "_app";
		appid -= AID_APP;
	} else {
		username = "_isolated";
		appid -= AID_ISOLATED_START;
	}

	if (appid >= CAT_MAPPING_MAX_ID || userid >= CAT_MAPPING_MAX_ID)
		goto err;

	for (i = 0; i < nspec; i++) {
		cur = seapp_contexts[i];

		if (cur->isSystemServer != isSystemServer)
			continue;

		if (cur->user) {
			if (cur->prefix) {
				if (strncasecmp(username, cur->user, cur->len-1))
					continue;
			} else {
				if (strcasecmp(username, cur->user))
					continue;
			}
		}

		if (cur->seinfo) {
			if (!seinfo || strcasecmp(seinfo, cur->seinfo))
				continue;
		}

		if (cur->name) {
			if (!pkgname || strcasecmp(pkgname, cur->name))
				continue;
		}

		if (kind == SEAPP_TYPE && !cur->type)
			continue;
		else if (kind == SEAPP_DOMAIN && !cur->domain)
			continue;

		if (cur->sebool) {
			int value = security_get_boolean_active(cur->sebool);
			if (value == 0)
				continue;
			else if (value == -1) {
				selinux_log(SELINUX_ERROR, \
				"Could not find boolean: %s ", cur->sebool);
				goto err;
			}
		}

		if (kind == SEAPP_TYPE) {
			if (context_type_set(ctx, cur->type))
				goto oom;
		} else if (kind == SEAPP_DOMAIN) {
			if (context_type_set(ctx, cur->domain))
				goto oom;
		}

		if (cur->levelFrom != LEVELFROM_NONE) {
			char level[255];
			switch (cur->levelFrom) {
			case LEVELFROM_APP:
				snprintf(level, sizeof level, "%s:c%u,c%u",
					 context_range_get(ctx), appid & 0xff,
					 256 + (appid>>8 & 0xff));
				break;
			case LEVELFROM_USER:
				snprintf(level, sizeof level, "%s:c%u,c%u",
					 context_range_get(ctx),
					 512 + (userid & 0xff),
					 768 + (userid>>8 & 0xff));
				break;
			case LEVELFROM_ALL:
				snprintf(level, sizeof level, "%s:c%u,c%u,c%u,c%u",
					 context_range_get(ctx), appid & 0xff,
					 256 + (appid>>8 & 0xff),
					 512 + (userid & 0xff),
					 768 + (userid>>8 & 0xff));
				break;
			default:
				goto err;
			}
			if (context_range_set(ctx, level))
				goto oom;
		} else if (cur->level) {
			if (context_range_set(ctx, cur->level))
				goto oom;
		}

		break;
	}

	if (kind == SEAPP_DOMAIN && i == nspec) {
		/*
		 * No match.
		 * Fail to prevent staying in the zygote's context.
		 */
		selinux_log(SELINUX_ERROR,
			    "%s:  No match for app with uid %d, seinfo %s, name %s\n",
			    __FUNCTION__, uid, seinfo, pkgname);

		if (security_getenforce() == 1)
			goto err;
	}

	return 0;
err:
	return -1;
oom:
	return -2;
}

int selinux_android_setfilecon2(const char *pkgdir,
				const char *pkgname,
				const char *seinfo,
				uid_t uid)
{
	char *orig_ctx_str = NULL;
	char *ctx_str = NULL;
	context_t ctx = NULL;
	int rc = -1;

	if (is_selinux_enabled() <= 0)
		return 0;

	__selinux_once(once, seapp_context_init);

	rc = getfilecon(pkgdir, &ctx_str);
	if (rc < 0)
		goto err;

	ctx = context_new(ctx_str);
	orig_ctx_str = ctx_str;
	if (!ctx)
		goto oom;

	rc = seapp_context_lookup(SEAPP_TYPE, uid, 0, seinfo, pkgname, ctx);
	if (rc == -1)
		goto err;
	else if (rc == -2)
		goto oom;

	ctx_str = context_str(ctx);
	if (!ctx_str)
		goto oom;

	rc = security_check_context(ctx_str);
	if (rc < 0)
		goto err;

	if (strcmp(ctx_str, orig_ctx_str)) {
		rc = setfilecon(pkgdir, ctx_str);
		if (rc < 0)
			goto err;
	}

	rc = 0;
out:
	freecon(orig_ctx_str);
	context_free(ctx);
	return rc;
err:
	selinux_log(SELINUX_ERROR, "%s:  Error setting context for pkgdir %s, uid %d: %s\n",
		    __FUNCTION__, pkgdir, uid, strerror(errno));
	rc = -1;
	goto out;
oom:
	selinux_log(SELINUX_ERROR, "%s:  Out of memory\n", __FUNCTION__);
	rc = -1;
	goto out;
}

int selinux_android_setfilecon(const char *pkgdir,
			       const char *pkgname,
			       uid_t uid)
{
	return selinux_android_setfilecon2(pkgdir, pkgname, NULL, uid);
}

int selinux_android_setcontext(uid_t uid,
			       int isSystemServer,
			       const char *seinfo,
			       const char *pkgname)
{
	char *orig_ctx_str = NULL, *ctx_str;
	context_t ctx = NULL;
	int rc = -1;

	if (is_selinux_enabled() <= 0)
		return 0;

	__selinux_once(once, seapp_context_init);

	rc = getcon(&ctx_str);
	if (rc)
		goto err;

	ctx = context_new(ctx_str);
	orig_ctx_str = ctx_str;
	if (!ctx)
		goto oom;

	rc = seapp_context_lookup(SEAPP_DOMAIN, uid, isSystemServer, seinfo, pkgname, ctx);
	if (rc == -1)
		goto err;
	else if (rc == -2)
		goto oom;

	ctx_str = context_str(ctx);
	if (!ctx_str)
		goto oom;

	rc = security_check_context(ctx_str);
	if (rc < 0)
		goto err;

	if (strcmp(ctx_str, orig_ctx_str)) {
		rc = setcon(ctx_str);
		if (rc < 0)
			goto err;
	}

	rc = 0;
out:
	freecon(orig_ctx_str);
	context_free(ctx);
	avc_netlink_close();
	return rc;
err:
	if (isSystemServer)
		selinux_log(SELINUX_ERROR,
				"%s:  Error setting context for system server: %s\n",
				__FUNCTION__, strerror(errno));
	else
		selinux_log(SELINUX_ERROR,
				"%s:  Error setting context for app with uid %d, seinfo %s: %s\n",
				__FUNCTION__, uid, seinfo, strerror(errno));

	rc = -1;
	goto out;
oom:
	selinux_log(SELINUX_ERROR, "%s:  Out of memory\n", __FUNCTION__);
	rc = -1;
	goto out;
}

static struct selabel_handle *sehandle = NULL;

static struct selabel_handle *get_selabel_handle(const struct selinux_opt opts[]) {
	struct selabel_handle *h;
	int i = 0;

	h = NULL;
	while ((h == NULL) && opts[i].value) {
		h = selabel_open(SELABEL_CTX_FILE, &opts[i], 1);
		i++;
	}

	return h;
}

static struct selabel_handle *file_context_open(void)
{
	struct selabel_handle *h;

	h = get_selabel_handle(seopts);

	if (!h)
		selinux_log(SELINUX_ERROR, "%s: Error getting file context handle (%s)\n",
				__FUNCTION__, strerror(errno));
	return h;
}

static struct selabel_handle *file_context_backup_open(void)
{
	struct selabel_handle *h;

	h = get_selabel_handle(seopt_backup);

	if (!h)
		selinux_log(SELINUX_ERROR, "%s: Error getting backup file context handle (%s)\n",
				__FUNCTION__, strerror(errno));
	return h;
}

static void file_context_init(void)
{
	sehandle = file_context_open();
}

static pthread_once_t fc_once = PTHREAD_ONCE_INIT;

int selinux_android_restorecon(const char *pathname)
{

	char* oldcontext = NULL;
	char* newcontext = NULL;
	struct stat sb;
	int ret = -1;

	if (is_selinux_enabled() <= 0)
		return 0;

	__selinux_once(fc_once, file_context_init);

	if (!sehandle)
		goto bail;

	if (lstat(pathname, &sb) < 0)
		goto err;

	if (lgetfilecon(pathname, &oldcontext) < 0)
		goto err;

	if (selabel_lookup(sehandle, &newcontext, pathname, sb.st_mode) < 0)
		goto err;

	if (strcmp(newcontext, "<<none>>") && strcmp(oldcontext, newcontext))
		if (lsetfilecon(pathname, newcontext) < 0)
			goto err;

	ret = 0;
out:
	if (oldcontext)
		freecon(oldcontext);
	if (newcontext)
		freecon(newcontext);

	return ret;

err:
	selinux_log(SELINUX_ERROR,
		    "%s:  Error restoring context for %s (%s)\n",
		    __FUNCTION__, pathname, strerror(errno));

bail:
	ret = -1;
	goto out;
}

static int file_requires_fixup(const char *pathname,
		struct selabel_handle *sehandle_old,
		struct selabel_handle *sehandle_new)
{
	int ret;
	struct stat sb;
	char *current_context, *old_context, *new_context;

	ret = 0;
	old_context = NULL;
	new_context = NULL;
	current_context = NULL;

	if (lstat(pathname, &sb) < 0) {
		ret = -1;
		goto err;
	}

	if (lgetfilecon(pathname, &current_context) < 0) {
		ret = -1;
		goto err;
	}

	if (selabel_lookup(sehandle_old, &old_context, pathname, sb.st_mode) < 0) {
		ret = -1;
		goto err;
	}

	if (selabel_lookup(sehandle_new, &new_context, pathname, sb.st_mode) < 0) {
		ret = -1;
		goto err;
	}

	if (strstr(current_context, "unlabeled") != NULL) {
		ret = 1;
		goto out;
	}

	ret = (strcmp(old_context, new_context) && !strcmp(current_context, old_context));
	goto out;

err:
	selinux_log(SELINUX_ERROR,
		"%s:  Error comparing context for %s (%s)\n",
		__FUNCTION__,
		pathname,
		strerror(errno));

out:
	if (current_context)
		freecon(current_context);
	if (new_context)
		freecon(new_context);
	if (old_context)
		freecon(old_context);
	return ret;
}

static int fixcon_file(const char *pathname,
		struct selabel_handle *sehandle_old,
		struct selabel_handle *sehandle_new)
{
	int requires_fixup;

	requires_fixup = file_requires_fixup(pathname, sehandle_old, sehandle_new);
	if (requires_fixup < 0)
		return -1;

	if (requires_fixup)
		selinux_android_restorecon(pathname);

	return 0;
}

static int fixcon_recursive(const char *pathname,
		struct selabel_handle *sehandle_old,
		struct selabel_handle *sehandle_new)
{
	struct stat statresult;
	if (lstat(pathname, &statresult) < 0)
		return -1;

	if (!S_ISDIR(statresult.st_mode))
		return fixcon_file(pathname, sehandle_old, sehandle_new);

	DIR *dir = opendir(pathname);
	if (dir == NULL)
		return -1;

	struct dirent *entry;
	while ((entry = readdir(dir)) != NULL) {
		char *entryname;
		if (!strcmp(entry->d_name, ".."))
			continue;
		if (!strcmp(entry->d_name, "."))
			continue;
		if (asprintf(&entryname, "%s/%s", pathname, entry->d_name) == -1)
			continue;
		fixcon_recursive(entryname, sehandle_old, sehandle_new);
		free(entryname);
	}

	if (closedir(dir) < 0)
		return -1;

	return fixcon_file(pathname, sehandle_old, sehandle_new);
}

int selinux_android_fixcon(const char *pathname)
{
	struct selabel_handle *sehandle_old, *sehandle_new;

	sehandle_old = file_context_backup_open();
	if (sehandle_old == NULL)
		return -1;

	sehandle_new = file_context_open();
	if (sehandle_new == NULL)
		return -1;

	return fixcon_recursive(pathname, sehandle_old, sehandle_new);
}

struct selabel_handle* selinux_android_file_context_handle(void)
{
		return file_context_open();
}

int selinux_android_reload_policy(void)
{
	int fd = -1, rc;
	struct stat sb;
	void *map = NULL;
	int i = 0;

	while (fd < 0 && sepolicy_file[i]) {
		fd = open(sepolicy_file[i], O_RDONLY | O_NOFOLLOW);
		i++;
	}
	if (fd < 0) {
		selinux_log(SELINUX_ERROR, "SELinux:  Could not open sepolicy:  %s\n",
				strerror(errno));
		return -1;
	}
	if (fstat(fd, &sb) < 0) {
		selinux_log(SELINUX_ERROR, "SELinux:  Could not stat %s:  %s\n",
				sepolicy_file[i-1], strerror(errno));
		close(fd);
		return -1;
	}
	map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (map == MAP_FAILED) {
		selinux_log(SELINUX_ERROR, "SELinux:  Could not map %s:  %s\n",
			sepolicy_file[i-1], strerror(errno));
		close(fd);
		return -1;
	}

	rc = security_load_policy(map, sb.st_size);
	if (rc < 0) {
		selinux_log(SELINUX_ERROR, "SELinux:  Could not load policy:  %s\n",
			strerror(errno));
		munmap(map, sb.st_size);
		close(fd);
		return -1;
	}

	munmap(map, sb.st_size);
	close(fd);
	selinux_log(SELINUX_INFO, "SELinux: Loaded policy from %s\n", sepolicy_file[i-1]);

	return 0;
}

int selinux_android_load_policy(void)
{
	char *mnt = SELINUXMNT;
	int rc;
	rc = mount(SELINUXFS, mnt, SELINUXFS, 0, NULL);
	if (rc < 0) {
		if (errno == ENODEV) {
			/* SELinux not enabled in kernel */
			return -1;
		}
		if (errno == ENOENT) {
			/* Fall back to legacy mountpoint. */
			mnt = OLDSELINUXMNT;
			rc = mkdir(mnt, 0755);
			if (rc == -1 && errno != EEXIST) {
				selinux_log(SELINUX_ERROR,"SELinux:  Could not mkdir:  %s\n",
					strerror(errno));
				return -1;
			}
			rc = mount(SELINUXFS, mnt, SELINUXFS, 0, NULL);
		}
	}
	if (rc < 0) {
		selinux_log(SELINUX_ERROR,"SELinux:  Could not mount selinuxfs:  %s\n",
				strerror(errno));
		return -1;
	}
	set_selinuxmnt(mnt);

	return selinux_android_reload_policy();
}


text:
/*
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file:
 *
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */

package java.util.concurrent;

import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * A thread managed by a {@link ForkJoinPool}, which executes
 * {@link ForkJoinTask}s.
 * This class is subclassable solely for the sake of adding
 * functionality -- there are no overridable methods dealing with
 * scheduling or execution.  However, you can override initialization
 * and termination methods surrounding the main task processing loop.
 * If you do create such a subclass, you will also need to supply a
 * custom {@link ForkJoinPool.ForkJoinWorkerThreadFactory} to
 * {@linkplain ForkJoinPool#ForkJoinPool(int, ForkJoinWorkerThreadFactory,
 * UncaughtExceptionHandler, boolean, int, int, int, Predicate, long, TimeUnit)
 * use it} in a {@code ForkJoinPool}.
 *
 * @since 1.7
 * @author Doug Lea
 */
public class ForkJoinWorkerThread extends Thread {
    /*
     * ForkJoinWorkerThreads are managed by ForkJoinPools and perform
     * ForkJoinTasks. For explanation, see the internal documentation
     * of class ForkJoinPool.
     *
     * This class just maintains links to its pool and WorkQueue.
     */

    final ForkJoinPool pool;                // the pool this thread works in
    final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics

    /**
     * Full nonpublic constructor.
     */
    ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool,
                         boolean useSystemClassLoader, boolean isInnocuous) {
        super(group, null, pool.nextWorkerThreadName(), 0L);
        UncaughtExceptionHandler handler = (this.pool = pool).ueh;
        this.workQueue = new ForkJoinPool.WorkQueue(this, isInnocuous);
        super.setDaemon(true);
        if (handler != null)
            super.setUncaughtExceptionHandler(handler);
        if (useSystemClassLoader)
            super.setContextClassLoader(ClassLoader.getSystemClassLoader());
    }

    /**
     * Creates a ForkJoinWorkerThread operating in the given thread group and
     * pool.
     *
     * @param group if non-null, the thread group for this thread
     * @param pool the pool this thread works in
     * @throws NullPointerException if pool is null
     */
    /* TODO: protected */ ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool) {
        this(group, pool, false, false);
    }

    /**
     * Creates a ForkJoinWorkerThread operating in the given pool.
     *
     * @param pool the pool this thread works in
     * @throws NullPointerException if pool is null
     */
    protected ForkJoinWorkerThread(ForkJoinPool pool) {
        this(null, pool, false, false);
    }

    /**
     * Returns the pool hosting this thread.
     *
     * @return the pool
     */
    public ForkJoinPool getPool() {
        return pool;
    }

    /**
     * Returns the unique index number of this thread in its pool.
     * The returned value ranges from zero to the maximum number of
     * threads (minus one) that may exist in the pool, and does not
     * change during the lifetime of the thread.  This method may be
     * useful for applications that track status or collect results
     * per-worker-thread rather than per-task.
     *
     * @return the index number
     */
    public int getPoolIndex() {
        return workQueue.getPoolIndex();
    }

    /**
     * Initializes internal state after construction but before
     * processing any tasks. If you override this method, you must
     * invoke {@code super.onStart()} at the beginning of the method.
     * Initialization requires care: Most fields must have legal
     * default values, to ensure that attempted accesses from other
     * threads work correctly even before this thread starts
     * processing tasks.
     */
    protected void onStart() {
    }

    /**
     * Performs cleanup associated with termination of this worker
     * thread.  If you override this method, you must invoke
     * {@code super.onTermination} at the end of the overridden method.
     *
     * @param exception the exception causing this thread to abort due
     * to an unrecoverable error, or {@code null} if completed normally
     */
    protected void onTermination(Throwable exception) {
    }

    /**
     * This method is required to be public, but should never be
     * called explicitly. It performs the main run loop to execute
     * {@link ForkJoinTask}s.
     */
    public void run() {
        Throwable exception = null;
        ForkJoinPool p = pool;
        ForkJoinPool.WorkQueue w = workQueue;
        if (p != null && w != null) {   // skip on failed initialization
            try {
                p.registerWorker(w);
                onStart();
                p.runWorker(w);
            } catch (Throwable ex) {
                exception = ex;
            } finally {
                try {
                    onTermination(exception);
                } catch (Throwable ex) {
                    if (exception == null)
                        exception = ex;
                } finally {
                    p.deregisterWorker(this, exception);
                }
            }
        }
    }

    /**
     * A worker thread that has no permissions, is not a member of any
     * user-defined ThreadGroup, uses the system class loader as
     * thread context class loader, and erases all ThreadLocals after
     * running each top-level task.
     */
    static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
        /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
        @SuppressWarnings("removal")
        private static final ThreadGroup innocuousThreadGroup =
            AccessController.doPrivileged(new PrivilegedAction<>() {
                public ThreadGroup run() {
                    ThreadGroup group = Thread.currentThread().getThreadGroup();
                    for (ThreadGroup p; (p = group.getParent()) != null; )
                        group = p;
                    return new ThreadGroup(
                        group, "InnocuousForkJoinWorkerThreadGroup");
                }});

        InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
            super(innocuousThreadGroup, pool, true, true);
        }

        @Override // to silently fail
        public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }

        @Override // paranoically
        public void setContextClassLoader(ClassLoader cl) {
            if (cl != null && ClassLoader.getSystemClassLoader() != cl)
                throw new SecurityException("setContextClassLoader");
        }
    }
}


text:
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta name=Generator content="Microsoft Word 15 (filtered)">

Chapter 21 – DAVID GLEN
BROWNING

On September of 1970,
the Lord blessed us with another beautiful baby son whom we named David.   When
this son was born, I told Ken I didn't care if his mom didn't like the name of
David, we did and he was our child and we could name him what we wanted - so we
named him David Glen.  Glen after my father.  Ken's mom never said anything
about his name.

            My concerns about having two children so close,
especially since Shellie & Mike were only two years apart, quickly ended
when David was born.  David didn't have colic and was a contented baby, and
Mike was so cute with David and always wanted to help.  He was a big help.  I
let him get me the diapers, binkee, help feed him when I bottle fed him or gave
him water in the bottle, etc.  He always wanted to hold him, etc., and as soon
as David was old enough to play, they were having fun together.  David,
although a contended baby, was a sickly baby.  He was always getting colds
which would turn into tonsillitis, croup, ear infections, etc.


text:
var livejson = require('../lib/datasources/livejson');
var webjson = require('../lib/datasources/webjson');
var series = require('../lib/datasources/series');
var ReportParameter = require('../lib/parameter');

exports.testGetParameterizedUrlWithPathVariables = function(test) {
	test.expect(1);

	var params = [
		new ReportParameter("about", "string", "people"),
		new ReportParameter("me", "string", "phil")
	];

	var ds = new webjson("http://www.gooogle.com/:about/:me", params);

	test.equal(ds.getParameterizedUrl(), "http://www.gooogle.com/people/phil");
	test.done();
}

exports.testGetParameterizedUrlWithSearchVariables = function(test) {
	test.expect(1);

	var params = [
		new ReportParameter("about", "string", "people"),
		new ReportParameter("me", "string", "phil")
	];

	var ds = new webjson("http://www.gooogle.com?about=:about&who=:me", params);

	test.equal(ds.getParameterizedUrl(), "http://www.gooogle.com?about=people&who=phil");
	test.done();
}

exports.testGetParameterizedUrlWithPathAndSearchVariables = function(test) {
	test.expect(1);

	var params = [
		new ReportParameter("about", "string", "people"),
		new ReportParameter("me", "string", "phil"),
		new ReportParameter("limit", "number", 500)
	];

	var ds = new webjson("http://www.gooogle.com/:about/:me?limit=:limit", params);

	test.equal(ds.getParameterizedUrl(), "http://www.gooogle.com/people/phil?limit=500");
	test.done();
}

//

exports.testExecuteWebJson = function(test) {
	test.expect(3);

	var params = [
		new ReportParameter("address", "string", "Portland, OR")
	];

	var ds = new webjson("http://maps.googleapis.com/maps/api/geocode/json?address=:address&sensor=false", params);

	ds.execute(function(err, data){

		test.ifError(err);
		test.ok(data != null);
		test.equal(data.status, "OK");

		test.done();
	});

}

exports.testExecuteLiveJson = function(test) {
	test.expect(3);

	var params = [
		new ReportParameter("postalcode", "string", "6600"),
		new ReportParameter("country", "string", "AT"),
		new ReportParameter("username", "string", "demo")
	];

	var json = {
		"postalcodes":[
			{"adminCode3":"70805","adminName2":"Politischer Bezirk Reutte","adminName3":"Breitenwang","adminCode2":"708","postalcode":"6600","adminCode1":"07","countryCode":"AT","lng":10.7333333,"placeName":"Breitenwang","lat":47.4833333,"adminName1":"Tirol"},
			{"adminCode3":"70806","adminName2":"Politischer Bezirk Reutte","adminName3":"Ehenbichl","adminCode2":"708","postalcode":"6600","adminCode1":"07","countryCode":"AT","lng":10.7,"placeName":"Ehenbichl","lat":47.4666667,"adminName1":"Tirol"},
			{"adminCode3":"70820","adminName2":"Politischer Bezirk Reutte","adminName3":"Lechaschau","adminCode2":"708","postalcode":"6600","adminCode1":"07","countryCode":"AT","lng":10.7,"placeName":"Lechaschau","lat":47.4833333,"adminName1":"Tirol"}
			]
	};

	var ds = new livejson(params, json);

	ds.execute(function(err, data){

		test.ifError(err);
		test.ok(data != null);
		test.ok(data.postalcodes != null);

		test.done();
	});

}

exports.testGetDatasourceUrlWithHostnameInConfig = function(test) {
	test.expect(1);

	var ds = new webjson("{googleHost}/:about/:me", null);

	test.equal(ds.getDatasourceUrl(), "http://www.gooogle.com/:about/:me");
	test.done();
}

exports.testGetDatasourceUrlWithHostnameInEnvironment = function(test) {
	test.expect(1);

	process.env.googleHostEnv = 'http://www.gooogle.com';

	var ds = new webjson("{googleHostEnv}/:about/:me", null);

	test.equal(ds.getDatasourceUrl(), "http://www.gooogle.com/:about/:me");
	test.done();
}

exports.testExecuteSeriesNoSelectors = function(test) {
    test.expect(6);

    var params = [];

    var json1 = new livejson(params, [
        {"id": 1, "name": "James Smith"},
        {"id": 2, "name": "Will Farrel"}
    ]);

    var json2 = new livejson(params, [
        {"person_id": 2, "phone": "503-555-1212"},
        {"person_id": 1, "phone": "971-555-1313"}
    ]);

    var ds = new series(params, [json1, json2]);

    ds.execute(function(err, data){

        test.ifError(err);
        test.ok(data != null);
        test.ok(data instanceof Array);
        test.equal(data.length, 4);

        console.log(data[0]);
        test.equal(data[0].name, 'James Smith');

        console.log(data[3]);
        test.equal(data[3].phone, '971-555-1313');

        test.done();
    });

}

exports.testExecuteSeriesWithSelectors = function(test) {
    test.expect(7);

    var params = [];

    var json1 = new livejson(params, [
        {"id": 1, "name": "James Smith"},
        {"id": 2, "name": "Will Farrel"}
    ]);

    var json2 = new livejson(params, [
        {"person_id": 2, "phone": "503-555-1212"},
        {"person_id": 1, "phone": "971-555-1313"}
    ]);

    var ds = new series(params, [json1, json2]);
    ds.setSelectors([
        { key: "id" },
        { key: "person_id" }
    ]);

    ds.execute(function(err, data){

        test.ifError(err);
        test.ok(data != null);
        test.ok(data instanceof Array);
        test.equal(data.length, 2);

        test.equal(data[1].id, 2);
        test.equal(data[1].name, 'Will Farrel');
        test.equal(data[1].phone, '503-555-1212');

        console.log(data[1]);

        test.done();
    });

}

exports.testExecuteSeriesWithSelectorsAndTable = function(test) {
    test.expect(7);

    var params = [];

    var json1 = new livejson(params, {
        "status" : 200,
        "results" : [
        {"id": 1, "name": "James Smith"},
        {"id": 2, "name": "Will Farrel"}
        ]
    });

    var json2 = new livejson(params, [
        {"person_id": 2, "phone": "503-555-1212"},
        {"person_id": 1, "phone": "971-555-1313"}
    ]);

    var ds = new series(params, [json1, json2]);
    var ds = new series(params, [json1, json2]);
    ds.setSelectors([
        { key: "id", table: "results" },
        { key: "person_id" }
    ]);

    ds.execute(function(err, data){

        test.ifError(err);
        test.ok(data != null);
        test.ok(data instanceof Array);
        test.equal(data.length, 2);

        test.equal(data[1].id, 2);
        test.equal(data[1].name, 'Will Farrel');
        test.equal(data[1].phone, '503-555-1212');

        console.log(data[1]);

        test.done();
    });

}

exports.testExecuteSeriesWithSelectorsAndTableAndTransformer = function(test) {
    test.expect(8);

    var params = [];

    var json1 = new livejson(params, {
        "status" : 200,
        "results" : [
            {"id": 1, "name": "James Smith"},
            {"id": 2, "name": "Will Farrel"}
        ]
    });

    var json2 = new livejson(params, [
        {"person_id": 2, "phone": "503-555-1212"},
        {"person_id": 1, "phone": "971-555-1313"}
    ]);

    var ds = new series(params, [json1, json2]);
    var ds = new series(params, [json1, json2]);
    ds.setSelectors([
        { key: "id", table: "results" },
        { key: "person_id", transformer: function(item){ return { phone: item.phone }; } }
    ]);

    ds.execute(function(err, data){

        test.ifError(err);
        test.ok(data != null);
        test.ok(data instanceof Array);
        test.equal(data.length, 2);

        test.equal(data[1].id, 2);
        test.equal(data[1].name, 'Will Farrel');
        test.equal(data[1].phone, '503-555-1212');
        test.ok(data[1].person_id == null);

        console.log(data[1]);

        test.done();
    });

}


text:
@interface WGBSystemImagePickerManager : NSObject

	/// 创建这样一个管理类对象
- (instancetype)initWithViewController:(UIViewController *)VC;

	///选择图片的回调block
@property (nonatomic,copy) void(^didSelectImageBlock) (UIImage *image);

	/// 相册选择器对象
@property (nonatomic,strong) UIImagePickerController *imagePicker;

	///最大视频时长
@property (nonatomic,assign) NSTimeInterval videoMaximumDuration;

@property (nonatomic,assign) BOOL isVideo;

#pragma mark- 快速创建一个图片选择弹出窗
- (void)quickAlertSheetPickerImage ;

#pragma mark- 打开相机
- (void)openCamera;

#pragma mark- 打开相册
- (void)openPhoto ;

@end


text:
<?php

namespace Cms;

/**
 * Klasa kontrolera szablonu - folder
 */
class FolderTemplateController extends AbstractTemplateController
{
}


text:
import sys

from defer import inline_callbacks, return_value, defer as maybe_deferred
from tornado.ioloop import IOLoop

from tornado.web import RequestHandler, HTTPError, MissingArgumentError as TornadoMissingArgumentError

from pycloudia.rest.interfaces import IRequest
from pycloudia.rest.exceptions import MissingArgumentError

__all__ = ['GetRequestHandler', 'PostRequestHandler']

class HttpRequest(IRequest):
    def __init__(self, handler, *args, **kwargs):
        """
        :type handler: L{pycloudia.rest.tornado_impl.handlers.BaseRequestHandler}
        """
        self.handler = handler
        self.path_args = args
        self.path_kwargs = kwargs

    def get_argument(self, type_func, name, default=IRequest.MISSED):
        try:
            return type_func(self.path_args[int(name)])
        except (ValueError, IndexError):
            pass

        try:
            return type_func(self.path_kwargs[name])
        except KeyError:
            pass

        if issubclass(type_func, (tuple, list)):
            method = self.handler.get_arguments
        else:
            method = self.handler.get_argument
        if default is IRequest.MISSED:
            try:
                value = method(name)
            except TornadoMissingArgumentError:
                raise MissingArgumentError(name)
        else:
            value = method(name, default)

        return type_func(value)

class BaseRequestHandler(RequestHandler):
    func = None
    spec = None

    def initialize(self, func, spec):
        """
        :type func: C{Callable}
        :type spec: L{pycloudia.rest.spec.Spec}
        """
        self.func = func
        self.spec = spec

    @inline_callbacks
    def _invoke(self, *args, **kwargs):
        """
        :rtype: L{defer.Deferred} of C{unicode}
        """
        request = self._create_request(*args, **kwargs)
        self._auto_finish = False
        try:
            content = yield maybe_deferred(self.func, request)
        except Exception as e:
            exception_cls, exception, traceback = sys.exc_info()
            try:
                resolver = self.spec.resolve_exception(e)
            except LookupError:
                IOLoop.instance().add_callback(self.send_error, 500)
                raise exception_cls, exception, traceback
            else:
                if not isinstance(resolver, callable):
                    status_code, message = resolver
                    IOLoop.instance().add_callback(self.finish)
                    raise HTTPError(status_code, e, reason=message)
                content = resolver(e, exception_cls, exception, traceback)
        content, headers = yield maybe_deferred(self.spec.render, request, content)
        return_value((content, headers))

    def _create_request(self, *args, **kwargs):
        return HttpRequest(self, *args, **kwargs)

    def _finish(self, args):
        """
        :type args: C{tuple} of (C{basestring}, C{dict})
        """
        content, headers = args
        self.write(content)
        for name, value in headers.iteritems():
            self.set_header(name, value)
        self.finish()

class GetRequestHandler(BaseRequestHandler):
    def get(self, *args, **kwargs):
        self._invoke(*args, **kwargs).add_callback(self._finish)

class PostRequestHandler(BaseRequestHandler):
    def post(self, *args, **kwargs):
        self._invoke(*args, **kwargs).add_callback(self._finish)


text:
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/platform/device/npu/npu_op_runner.h"

namespace paddle {
namespace operators {

template <typename T>
class MaskedSelectedNPUKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext& ctx) const override {
    auto input = ctx.Input<phi::DenseTensor>("X");
    auto mask = ctx.Input<phi::DenseTensor>("Mask");
    auto out = ctx.Output<phi::DenseTensor>("Y");

    auto input_dim = input->dims();
    auto mask_dim = mask->dims();
    PADDLE_ENFORCE_EQ(
        input_dim,
        mask_dim,
        platform::errors::InvalidArgument(
            "The dim size of input and mask in OP(masked_selected) "
            "must be equal, but got input dim:(%ld), mask dim: "
            "(%ld). Please check input "
            "value.",
            input_dim,
            mask_dim));

    auto& dev_ctx =
        ctx.template device_context<paddle::platform::NPUDeviceContext>();
    auto stream = dev_ctx.stream();

    Tensor mask_int32, out_size;
    std::vector<int32_t> out_size_vec;
    mask_int32.mutable_data<int32_t>(mask->dims(), ctx.GetPlace());
    out_size.mutable_data<int32_t>({1}, ctx.GetPlace());
    {
      const auto& cast_runner = NpuOpRunner(
          "Cast",
          {*mask},
          {mask_int32},
          {{"dst_type",
            static_cast<int32_t>(
                ConvertToNpuDtype(framework::proto::VarType::INT32))}});
      cast_runner.Run(stream);

      mask_int32.Resize({mask_int32.numel()});
      NpuOpRunner sum_runner;
      sum_runner.SetType("ReduceSum");
      sum_runner.AddInput(mask_int32);
      sum_runner.AddInput(std::vector<int32_t>({0}));
      sum_runner.AddOutput(out_size);
      sum_runner.AddAttr("keep_dims", false);
      sum_runner.Run(stream);
      paddle::framework::TensorToVector(out_size, dev_ctx, &out_size_vec);
    }

    out->Resize({out_size_vec[0]});
    out->mutable_data<T>(ctx.GetPlace());

    Tensor topkv2_out, indices;
    topkv2_out.mutable_data<int32_t>({out_size_vec[0]}, ctx.GetPlace());
    indices.mutable_data<int32_t>({out_size_vec[0]}, ctx.GetPlace());
    {
      NpuOpRunner topkv2_runner;
      topkv2_runner.SetType("TopKV2")
          .AddInput(mask_int32)
          .AddInput(out_size)
          .AddOutput(topkv2_out)
          .AddOutput(indices)
          .AddAttr("sorted", false)
          .AddAttr("dim", 0)
          .AddAttr("largest", true)
          .Run(stream);
      // TopKV2 may be unstable
      NpuOpRunner topkv2_runner2;
      topkv2_runner2.SetType("TopKV2")
          .AddInput(indices)
          .AddInput(out_size)
          .AddOutput(topkv2_out)
          .AddOutput(indices)
          .AddAttr("sorted", true)
          .AddAttr("dim", 0)
          .AddAttr("largest", false)
          .Run(stream);

      Tensor input_tmp;
      input_tmp.ShareDataWith(*input);
      input_tmp.Resize({input->numel()});
      const auto& gather_runner = NpuOpRunner(
          "GatherV2D", {input_tmp, topkv2_out}, {*out}, {{"axis", 0}});
      gather_runner.Run(stream);
    }
  }
};

template <typename T>
class MaskedSelectedGradNPUKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext& ctx) const override {
    auto mask = ctx.Input<phi::DenseTensor>("Mask");
    auto y_grad = ctx.Input<phi::DenseTensor>(framework::GradVarName("Y"));
    auto x_grad = ctx.Output<phi::DenseTensor>(framework::GradVarName("X"));

    x_grad->mutable_data<T>(ctx.GetPlace());

    auto& dev_ctx =
        ctx.template device_context<paddle::platform::NPUDeviceContext>();
    auto stream = dev_ctx.stream();

    Tensor mask_int32, out_size;
    std::vector<int32_t> out_size_vec;
    mask_int32.mutable_data<int32_t>(mask->dims(), ctx.GetPlace());
    out_size.mutable_data<int32_t>({1}, ctx.GetPlace());
    {
      const auto& cast_runner = NpuOpRunner(
          "Cast",
          {*mask},
          {mask_int32},
          {{"dst_type",
            static_cast<int32_t>(
                ConvertToNpuDtype(framework::proto::VarType::INT32))}});
      cast_runner.Run(stream);

      mask_int32.Resize({mask_int32.numel()});
      NpuOpRunner sum_runner;
      sum_runner.SetType("ReduceSum");
      sum_runner.AddInput(mask_int32);
      sum_runner.AddInput(std::vector<int32_t>({0}));
      sum_runner.AddOutput(out_size);
      sum_runner.AddAttr("keep_dims", false);
      sum_runner.Run(stream);
      paddle::framework::TensorToVector(out_size, dev_ctx, &out_size_vec);
    }

    Tensor topkv2_out, indices;
    topkv2_out.mutable_data<int32_t>({out_size_vec[0]}, ctx.GetPlace());
    indices.mutable_data<int32_t>({out_size_vec[0]}, ctx.GetPlace());
    {
      NpuOpRunner topkv2_runner;
      topkv2_runner.SetType("TopKV2")
          .AddInput(mask_int32)
          .AddInput(out_size)
          .AddOutput(topkv2_out)
          .AddOutput(indices)
          .AddAttr("sorted", false)
          .AddAttr("dim", 0)
          .AddAttr("largest", true)
          .Run(stream);

      NpuOpRunner topkv2_runner2;
      topkv2_runner2.SetType("TopKV2")
          .AddInput(indices)
          .AddInput(out_size)
          .AddOutput(topkv2_out)
          .AddOutput(indices)
          .AddAttr("sorted", true)
          .AddAttr("dim", 0)
          .AddAttr("largest", false)
          .Run(stream);

      topkv2_out.Resize({out_size_vec[0], 1});
      x_grad->Resize({x_grad->numel()});
      NpuOpRunner scatter_runner;
      scatter_runner.SetType("ScatterNd");
      scatter_runner.AddInput(topkv2_out);
      scatter_runner.AddInput(*y_grad);
      scatter_runner.AddInput(
          std::vector<int32_t>({static_cast<int32_t>(x_grad->numel())}));
      scatter_runner.AddOutput(*x_grad);
      scatter_runner.Run(stream);
      x_grad->Resize(mask->dims());
    }
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
namespace plat = paddle::platform;
REGISTER_OP_NPU_KERNEL(masked_select,
                       ops::MaskedSelectedNPUKernel<plat::float16>,
                       ops::MaskedSelectedNPUKernel<float>,
                       ops::MaskedSelectedNPUKernel<int>,
                       ops::MaskedSelectedNPUKernel<int64_t>);
REGISTER_OP_NPU_KERNEL(masked_select_grad,
                       ops::MaskedSelectedGradNPUKernel<plat::float16>,
                       ops::MaskedSelectedGradNPUKernel<float>,
                       ops::MaskedSelectedGradNPUKernel<int>,
                       ops::MaskedSelectedGradNPUKernel<int64_t>);


text:
<?xml version="1.0" encoding="UTF-8"?>
<billStatus>
  <bill>
    <laws />
    <amendments />
    <originChamber>House</originChamber>
    <congress>115</congress>
    <relatedBills>
      <item>
        <latestAction>
          <actionDate>2017-04-19</actionDate>
          <text>Became Public Law No: 115-27.</text>
        </latestAction>
        <number>30</number>
        <relationshipDetails>
          <item>
            <identifiedBy>CRS</identifiedBy>
            <type>Identical bill</type>
          </item>
        </relationshipDetails>
        <congress>115</congress>
        <type>SJRES</type>
        <latestTitle>A joint resolution providing for the reappointment of Steve Case as a citizen regent of the Board of Regents of the Smithsonian Institution.</latestTitle>
      </item>
    </relatedBills>
    <billNumber>78</billNumber>
    <cosponsors>
      <item>
        <lastName>Cole</lastName>
        <firstName>Tom</firstName>
        <sponsorshipDate>2017-02-16</sponsorshipDate>
        <isOriginalCosponsor>True</isOriginalCosponsor>
        <state>OK</state>
        <bioguideId>C001053</bioguideId>
        <identifiers>
          <lisID>1742</lisID>
          <gpoId>8112</gpoId>
          <bioguideId>C001053</bioguideId>
        </identifiers>
        <middleName />
        <fullName>Rep. Cole, Tom [R-OK-4]</fullName>
        <party>R</party>
        <district>4</district>
        <sponsorshipWithdrawnDate />
      </item>
      <item>
        <lastName>Matsui</lastName>
        <firstName>Doris</firstName>
        <sponsorshipDate>2017-02-16</sponsorshipDate>
        <isOriginalCosponsor>True</isOriginalCosponsor>
        <state>CA</state>
        <bioguideId>M001163</bioguideId>
        <identifiers>
          <lisID>1814</lisID>
          <gpoId>7810</gpoId>
          <bioguideId>M001163</bioguideId>
        </identifiers>
        <middleName>O.</middleName>
        <fullName>Rep. Matsui, Doris O. [D-CA-6]</fullName>
        <party>D</party>
        <district>6</district>
        <sponsorshipWithdrawnDate />
      </item>
    </cosponsors>
    <calendarNumbers />
    <committees>
      <billCommittees>
        <item>
          <subcommittees />
          <activities>
            <item>
              <date>2017-02-16T15:01:15Z</date>
              <name>Referred to</name>
            </item>
          </activities>
          <type>Standing</type>
          <systemCode>hsha00</systemCode>
          <name>House Administration Committee</name>
          <chamber>House</chamber>
        </item>
      </billCommittees>
    </committees>
    <createDate>2017-02-17T04:46:07Z</createDate>
    <cboCostEstimates />
    <introducedDate>2017-02-16</introducedDate>
    <title>Providing for the reappointment of Stephen M. Case as a citizen regent of the Board of Regents of the Smithsonian Institution.</title>
    <updateDate>2017-05-04T00:17:08Z</updateDate>
    <titles>
      <item>
        <chamberCode />
        <titleType>Official Title as Introduced</titleType>
        <parentTitleType />
        <chamberName />
        <title>Providing for the reappointment of Stephen M. Case as a citizen regent of the Board of Regents of the Smithsonian Institution.</title>
      </item>
      <item>
        <chamberCode />
        <titleType>Display Title</titleType>
        <parentTitleType />
        <chamberName />
        <title>Providing for the reappointment of Stephen M. Case as a citizen regent of the Board of Regents of the Smithsonian Institution.</title>
      </item>
    </titles>
    <committeeReports />
    <latestAction>
      <text>Referred to the House Committee on House Administration.</text>
      <actionDate>2017-02-16</actionDate>
      <links />
    </latestAction>
    <recordedVotes />
    <summaries>
      <billSummaries>
        <item>
          <actionDate>2017-02-16</actionDate>
          <lastSummaryUpdateDate>2017-04-12T18:14:32Z</lastSummaryUpdateDate>
          <actionDesc>Introduced in House</actionDesc>
          <updateDate>2017-02-16T05:00:00Z</updateDate>
          <text><![CDATA[
This joint resolution reappoints Stephen M. Case as a citizen regent of the Board of Regents of the Smithsonian Institution.
]]></text>
          <versionCode>00</versionCode>
          <name>Introduced in House</name>
        </item>
      </billSummaries>
    </summaries>
    <notes />
    <actions>
      <item>
        <committee>
          <name>House Administration Committee</name>
          <systemCode>hsha00</systemCode>
        </committee>
        <actionDate>2017-02-16</actionDate>
        <type>IntroReferral</type>
        <actionCode>H11100</actionCode>
        <text>Referred to the House Committee on House Administration.</text>
        <sourceSystem>
          2
          <name>House floor actions</name>
        </sourceSystem>
        <links />
      </item>
      <item>
        <committee />
        <actionDate>2017-02-16</actionDate>
        <type>IntroReferral</type>
        <actionCode>Intro-H</actionCode>
        <text>Introduced in House</text>
        <sourceSystem>
          9
          <name>Library of Congress</name>
        </sourceSystem>
        <links />
      </item>
      <item>
        <committee />
        <actionDate>2017-02-16</actionDate>
        <type>IntroReferral</type>
        <actionCode>1000</actionCode>
        <text>Introduced in House</text>
        <sourceSystem>
          9
          <name>Library of Congress</name>
        </sourceSystem>
        <links />
      </item>
      <actionByCounts>
        <houseOfRepresentatives>3</houseOfRepresentatives>
      </actionByCounts>
      <actionTypeCounts>
        <introducedInHouse>1</introducedInHouse>
        <billReferrals>1</billReferrals>
        <introducedInTheHouse>1</introducedInTheHouse>
      </actionTypeCounts>
    </actions>
    <sponsors>
      <item>
        <firstName>SAM</firstName>
        <middleName />
        <state>TX</state>
        <lastName>JOHNSON</lastName>
        <identifiers>
          <gpoId>8159</gpoId>
          <bioguideId>J000174</bioguideId>
          <lisID>603</lisID>
        </identifiers>
        <bioguideId>J000174</bioguideId>
        <fullName>Rep. Johnson, Sam [R-TX-3]</fullName>
        <district>3</district>
        <byRequestType />
        <party>R</party>
      </item>
    </sponsors>
    <billType>HJRES</billType>
    <version>1.0.0</version>
    <policyArea>
      <name>Government Operations and Politics</name>
    </policyArea>
    <constitutionalAuthorityStatementText><![CDATA[
From the Congressional Record Online through the Government Publishing Office [www.gpo.gov]By Mr. SAM JOHNSON of Texas:H.J. Res. 78.Congress has the power to enact this legislation pursuantto the following:Article 1, Section 8, Clause 17, giving Congress exclusivejurisdiction over the District of Columbia. That clause wascited as the authority for the government's ability to acceptthe original Smithson donation and the creation of theSmithsonian Institution via the Act of August 10, 1846.Article 1, Section 8, Clause 18, the Necessary and Properclause, which provides the power to enact legislationnecessary to effectuate one of the earlier enumerated powers,such as the authority granted in Clause 17 above.[Page H1306]
]]></constitutionalAuthorityStatementText>
    <subjects>
      <billSubjects>
        <policyArea>
          <name>Government Operations and Politics</name>
        </policyArea>
        <legislativeSubjects>
          <item>
            <name>Federal officials</name>
          </item>
          <item>
            <name>Museums, exhibitions, cultural centers</name>
          </item>
          <item>
            <name>Smithsonian Institution</name>
          </item>
        </legislativeSubjects>
      </billSubjects>
    </subjects>
  </bill>
  <dublinCore xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:format>text/xml</dc:format>
    <dc:language>EN</dc:language>
    <dc:rights>Pursuant to Title 17 Section 105 of the United States Code, this file is not subject to copyright protection and is in the public domain.</dc:rights>
    <dc:contributor>Congressional Research Service, Library of Congress</dc:contributor>
    <dc:description>This file contains bill summaries and statuses for federal legislation. A bill summary describes the most significant provisions of a piece of legislation and details the effects the legislative text may have on current law and federal programs. Bill summaries are authored by the Congressional Research Service (CRS) of the Library of Congress. As stated in Public Law 91-510 (2 USC 166 (d)(6)), one of the duties of CRS is "to prepare summaries and digests of bills and resolutions of a public general nature introduced in the Senate or House of Representatives". For more information, refer to the User Guide that accompanies this file.</dc:description>
  </dublinCore>
</billStatus>


text:
layout: default
---

{{ page.title }}

{{ page.description }}

✎ Edit Post

		{% include post-title.html post=page %}

			{{ content }}

				{% assign author_id = page.author_staff_member | prepend: "/staff_members/" | append: "/" %}
				{% assign author = site.staff_members | where: "url", author_id | first %}

{{ author.blurb }}

				{% if page.previous.url %}
					« {{ page.previous.title }}
				{% endif %}
				{% if page.next.url %}
					{{ page.next.title }} »
				{% endif %}

			{% if site.disqus_shortname and page.comments %}

				Please enable JavaScript to view the comments powered by Disqus.
			{% endif %}


text:
cask "deezer" do
  version "5.30.270"
  sha256 "e6584835073edcce00437b1d915085e8637ec50a0f4264a4db8031a1c20bbe62"

  url "https://www.deezer.com/desktop/download/artifact/darwin/x64/#{version}"
  name "Deezer"
  desc "Music player"
  homepage "https://www.deezer.com/download"

  livecheck do
    url "https://www.deezer.com/desktop/download?platform=darwin&architecture=x64"
    strategy :header_match
  end

  auto_updates true
  depends_on macos: ">= :high_sierra"

  app "Deezer.app"

  zap trash: [
    "~/Library/Application Support/Caches/deezer-desktop-updater",
    "~/Library/Application Support/deezer-desktop",
    "~/Library/Caches/com.deezer.deezer*",
    "~/Library/Logs/Deezer",
    "~/Library/Logs/deezer-desktop",
    "~/Library/Preferences/ByHost/com.deezer.*",
    "~/Library/Preferences/com.deezer.deezer-desktop.plist",
    "~/Library/Saved Application State/com.deezer.deezer-desktop.savedState",
  ]
end