'use strict';
const dart_sdk = require('dart_sdk');
const core = dart_sdk.core;
const dart = dart_sdk.dart;
const dartx = dart_sdk.dartx;
const node_modules = Object.create(null);
let B = () => (B = dart.constFn(node_modules.B$()))();
let _B = () => (_B = dart.constFn(node_modules._B$()))();
let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [])))();
let VoidToString = () => (VoidToString = dart.constFn(dart.definiteFunctionType(core.String, [])))();
node_modules.Callback = dart.typedef('Callback', () => dart.functionType(dart.void, [], {i: core.int}));
node_modules.A = class A extends core.Object {};
node_modules._A = class _A extends core.Object {};
node_modules.B$ = dart.generic(T => {
  class B extends core.Object {}
  dart.addTypeTests(B);
  return B;
});
node_modules.B = B();
node_modules._B$ = dart.generic(T => {
  class _B extends core.Object {}
  dart.addTypeTests(_B);
  return _B;
});
node_modules._B = _B();
node_modules.f = function() {
};
dart.fn(node_modules.f, VoidTodynamic());
node_modules._f = function() {
};
dart.fn(node_modules._f, VoidTodynamic());
node_modules.constant = "abc";
node_modules.finalConstant = "abc";
dart.defineLazy(node_modules, {
  get lazy() {
    return dart.fn(() => {
      core.print('lazy');
      return "abc";
    }, VoidToString())();
  }
});
node_modules.mutable = "abc";
dart.defineLazy(node_modules, {
  get lazyMutable() {
    return dart.fn(() => {
      core.print('lazyMutable');
      return "abc";
    }, VoidToString())();
  },
  set lazyMutable(_) {}
});
dart.trackLibraries("node_modules", {"node_modules.dart": node_modules}, null);
// Exports:
exports.node_modules = node_modules;
